Subversion Repositories Kolibri OS

Rev

Rev 4872 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*-
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. /* Split from vfscanf.c  */
  19.  
  20. #include <_ansi.h>
  21. #include <reent.h>
  22. #include <newlib.h>
  23. #include <stdio.h>
  24. #include "local.h"
  25.  
  26. /*
  27.  * Fill in the given table from the scanset at the given format
  28.  * (just after `[').  Return a pointer to the character past the
  29.  * closing `]'.  The table has a 1 wherever characters should be
  30.  * considered part of the scanset.
  31.  */
  32.  
  33. u_char *
  34. _DEFUN(__sccl, (tab, fmt),
  35.        register char *tab _AND
  36.        register u_char *fmt)
  37. {
  38.   register int c, n, v;
  39.  
  40.   /* first `clear' the whole table */
  41.   c = *fmt++;                   /* first char hat => negated scanset */
  42.   if (c == '^')
  43.     {
  44.       v = 1;                    /* default => accept */
  45.       c = *fmt++;               /* get new first char */
  46.     }
  47.   else
  48.     v = 0;                      /* default => reject */
  49.   /* should probably use memset here */
  50.   for (n = 0; n < 256; n++)
  51.     tab[n] = v;
  52.   if (c == 0)
  53.     return fmt - 1;             /* format ended before closing ] */
  54.  
  55.   /*
  56.    * Now set the entries corresponding to the actual scanset to the
  57.    * opposite of the above.
  58.    *
  59.    * The first character may be ']' (or '-') without being special; the
  60.    * last character may be '-'.
  61.    */
  62.  
  63.   v = 1 - v;
  64.   for (;;)
  65.     {
  66.       tab[c] = v;               /* take character c */
  67.     doswitch:
  68.       n = *fmt++;               /* and examine the next */
  69.       switch (n)
  70.         {
  71.  
  72.         case 0:         /* format ended too soon */
  73.           return fmt - 1;
  74.  
  75.         case '-':
  76.           /*
  77.            * A scanset of the form [01+-] is defined as `the digit 0, the
  78.            * digit 1, the character +, the character -', but the effect of a
  79.            * scanset such as [a-zA-Z0-9] is implementation defined.  The V7
  80.            * Unix scanf treats `a-z' as `the letters a through z', but treats
  81.            * `a-a' as `the letter a, the character -, and the letter a'.
  82.            *
  83.            * For compatibility, the `-' is not considerd to define a range if
  84.            * the character following it is either a close bracket (required by
  85.            * ANSI) or is not numerically greater than the character we just
  86.            * stored in the table (c).
  87.            */
  88.           n = *fmt;
  89.           if (n == ']' || n < c)
  90.             {
  91.               c = '-';
  92.               break;            /* resume the for(;;) */
  93.             }
  94.           fmt++;
  95.           do
  96.             {                   /* fill in the range */
  97.               tab[++c] = v;
  98.             }
  99.           while (c < n);
  100. #if 1                   /* XXX another disgusting compatibility hack */
  101.           /*
  102.            * Alas, the V7 Unix scanf also treats formats such
  103.            * as [a-c-e] as `the letters a through e'. This too
  104.            * is permitted by the standard....
  105.            */
  106.           goto doswitch;
  107. #else
  108.           c = *fmt++;
  109.           if (c == 0)
  110.             return fmt - 1;
  111.           if (c == ']')
  112.             return fmt;
  113. #endif
  114.  
  115.           break;
  116.  
  117.  
  118.         case ']':               /* end of scanset */
  119.           return fmt;
  120.  
  121.         default:                /* just another character */
  122.           c = n;
  123.           break;
  124.         }
  125.     }
  126.   /* NOTREACHED */
  127. }
  128.