Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / stdio / sccl.c
blobdd705e4104884d47b8bbe2af65274474d296927b
1 /*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
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 * and/or 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.
18 /* Split from vfscanf.c */
20 #include <_ansi.h>
21 #include <reent.h>
22 #include <newlib.h>
23 #include <stdio.h>
24 #include "local.h"
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.
33 u_char *
34 __sccl (register char *tab,
35 register u_char *fmt)
37 register int c, n, v;
39 /* first `clear' the whole table */
40 c = *fmt++; /* first char hat => negated scanset */
41 if (c == '^')
43 v = 1; /* default => accept */
44 c = *fmt++; /* get new first char */
46 else
47 v = 0; /* default => reject */
48 /* should probably use memset here */
49 for (n = 0; n < 256; n++)
50 tab[n] = v;
51 if (c == 0)
52 return fmt - 1; /* format ended before closing ] */
55 * Now set the entries corresponding to the actual scanset to the
56 * opposite of the above.
58 * The first character may be ']' (or '-') without being special; the
59 * last character may be '-'.
62 v = 1 - v;
63 for (;;)
65 tab[c] = v; /* take character c */
66 doswitch:
67 n = *fmt++; /* and examine the next */
68 switch (n)
71 case 0: /* format ended too soon */
72 return fmt - 1;
74 case '-':
76 * A scanset of the form [01+-] is defined as `the digit 0, the
77 * digit 1, the character +, the character -', but the effect of a
78 * scanset such as [a-zA-Z0-9] is implementation defined. The V7
79 * Unix scanf treats `a-z' as `the letters a through z', but treats
80 * `a-a' as `the letter a, the character -, and the letter a'.
82 * For compatibility, the `-' is not considerd to define a range if
83 * the character following it is either a close bracket (required by
84 * ANSI) or is not numerically greater than the character we just
85 * stored in the table (c).
87 n = *fmt;
88 if (n == ']' || n < c)
90 c = '-';
91 break; /* resume the for(;;) */
93 fmt++;
95 { /* fill in the range */
96 tab[++c] = v;
98 while (c < n);
99 #if 1 /* XXX another disgusting compatibility hack */
101 * Alas, the V7 Unix scanf also treats formats such
102 * as [a-c-e] as `the letters a through e'. This too
103 * is permitted by the standard....
105 goto doswitch;
106 #else
107 c = *fmt++;
108 if (c == 0)
109 return fmt - 1;
110 if (c == ']')
111 return fmt;
112 #endif
114 break;
117 case ']': /* end of scanset */
118 return fmt;
120 default: /* just another character */
121 c = n;
122 break;
125 /* NOTREACHED */