root / prex-0.9.0 / usr / lib / libc / stdio / vfscanf.c @ 03e9c04a
History | View | Annotate | Download (14.9 KB)
1 |
/*-
|
---|---|
2 |
* Copyright (c) 1990, 1993
|
3 |
* The Regents of the University of California. All rights reserved.
|
4 |
*
|
5 |
* This code is derived from software contributed to Berkeley by
|
6 |
* Chris Torek.
|
7 |
*
|
8 |
* Redistribution and use in source and binary forms, with or without
|
9 |
* modification, are permitted provided that the following conditions
|
10 |
* are met:
|
11 |
* 1. Redistributions of source code must retain the above copyright
|
12 |
* notice, this list of conditions and the following disclaimer.
|
13 |
* 2. Redistributions in binary form must reproduce the above copyright
|
14 |
* notice, this list of conditions and the following disclaimer in the
|
15 |
* documentation and/or other materials provided with the distribution.
|
16 |
* 3. Neither the name of the University nor the names of its contributors
|
17 |
* may be used to endorse or promote products derived from this software
|
18 |
* without specific prior written permission.
|
19 |
*
|
20 |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
21 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
24 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
26 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
27 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
28 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
29 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
30 |
* SUCH DAMAGE.
|
31 |
*/
|
32 |
|
33 |
#include <stdio.h> |
34 |
#include <stdlib.h> |
35 |
#include <ctype.h> |
36 |
#include <stdarg.h> |
37 |
#include "local.h" |
38 |
|
39 |
#define BUF 513 /* Maximum length of numeric string. */ |
40 |
|
41 |
/*
|
42 |
* Flags used during conversion.
|
43 |
*/
|
44 |
#define LONG 0x01 /* l: long or double */ |
45 |
#define LONGDBL 0x02 /* L: long double; unimplemented */ |
46 |
#define SHORT 0x04 /* h: short */ |
47 |
#define SUPPRESS 0x08 /* suppress assignment */ |
48 |
#define POINTER 0x10 /* weird %p pointer (`fake hex') */ |
49 |
#define NOSKIP 0x20 /* do not skip blanks */ |
50 |
|
51 |
/*
|
52 |
* The following are used in numeric conversions only:
|
53 |
* SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
|
54 |
* SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
|
55 |
*/
|
56 |
#define SIGNOK 0x40 /* +/- is (still) legal */ |
57 |
#define NDIGITS 0x80 /* no digits detected */ |
58 |
|
59 |
#define DPTOK 0x100 /* (float) decimal point is still legal */ |
60 |
#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */ |
61 |
|
62 |
#define PFXOK 0x100 /* 0x prefix is (still) legal */ |
63 |
#define NZDIGITS 0x200 /* no zero digits detected */ |
64 |
|
65 |
/*
|
66 |
* Conversion types.
|
67 |
*/
|
68 |
#define CT_CHAR 0 /* %c conversion */ |
69 |
#define CT_CCL 1 /* %[...] conversion */ |
70 |
#define CT_STRING 2 /* %s conversion */ |
71 |
#define CT_INT 3 /* integer, i.e., strtol or strtoul */ |
72 |
#define CT_FLOAT 4 /* floating, i.e., strtod */ |
73 |
|
74 |
#define u_char unsigned char |
75 |
#define u_long unsigned long |
76 |
|
77 |
static u_char *__sccl(char *, u_char *); |
78 |
|
79 |
/*
|
80 |
* vfscanf
|
81 |
*/
|
82 |
int
|
83 |
__svfscanf(fp, fmt0, ap) |
84 |
FILE *fp; |
85 |
char const *fmt0; |
86 |
va_list ap; |
87 |
{ |
88 |
u_char *fmt = (u_char *)fmt0; |
89 |
int c; /* character from format, or conversion */ |
90 |
size_t width; /* field width, or 0 */
|
91 |
char *p; /* points into all kinds of strings */ |
92 |
int n; /* handy integer */ |
93 |
int flags; /* flags as defined above */ |
94 |
char *p0; /* saves original value of p when necessary */ |
95 |
int nassigned; /* number of fields assigned */ |
96 |
int nread; /* number of characters consumed from fp */ |
97 |
int base; /* base argument to strtol/strtoul */ |
98 |
u_long (*ccfn)(const char *, char **, int); |
99 |
/* conversion function (strtol/strtoul) */
|
100 |
char ccltab[256]; /* character class table for %[...] */ |
101 |
char buf[BUF]; /* buffer for numeric conversions */ |
102 |
|
103 |
/* `basefix' is used to avoid `if' tests in the integer scanner */
|
104 |
static short basefix[17] = |
105 |
{ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; |
106 |
|
107 |
nassigned = 0;
|
108 |
nread = 0;
|
109 |
base = 0; /* XXX just to keep gcc happy */ |
110 |
ccfn = 0; /* XXX just to keep gcc happy */ |
111 |
for (;;) {
|
112 |
c = *fmt++; |
113 |
if (c == 0) |
114 |
return (nassigned);
|
115 |
if (isspace(c)) {
|
116 |
for (;;) {
|
117 |
if (fp->_r <= 0 && __srefill(fp)) |
118 |
return (nassigned);
|
119 |
if (!isspace(*fp->_p))
|
120 |
break;
|
121 |
nread++, fp->_r--, fp->_p++; |
122 |
} |
123 |
continue;
|
124 |
} |
125 |
if (c != '%') |
126 |
goto literal;
|
127 |
width = 0;
|
128 |
flags = 0;
|
129 |
/*
|
130 |
* switch on the format. continue if done;
|
131 |
* break once format type is derived.
|
132 |
*/
|
133 |
again: c = *fmt++;
|
134 |
switch (c) {
|
135 |
case '%': |
136 |
literal:
|
137 |
if (fp->_r <= 0 && __srefill(fp)) |
138 |
goto input_failure;
|
139 |
if (*fp->_p != c)
|
140 |
goto match_failure;
|
141 |
fp->_r--, fp->_p++; |
142 |
nread++; |
143 |
continue;
|
144 |
|
145 |
case '*': |
146 |
flags |= SUPPRESS; |
147 |
goto again;
|
148 |
case 'l': |
149 |
flags |= LONG; |
150 |
goto again;
|
151 |
case 'L': |
152 |
flags |= LONGDBL; |
153 |
goto again;
|
154 |
case 'h': |
155 |
flags |= SHORT; |
156 |
goto again;
|
157 |
|
158 |
case '0': case '1': case '2': case '3': case '4': |
159 |
case '5': case '6': case '7': case '8': case '9': |
160 |
width = width * 10 + c - '0'; |
161 |
goto again;
|
162 |
|
163 |
/*
|
164 |
* Conversions.
|
165 |
* Those marked `compat' are for 4.[123]BSD compatibility.
|
166 |
*
|
167 |
* (According to ANSI, E and X formats are supposed
|
168 |
* to the same as e and x. Sorry about that.)
|
169 |
*/
|
170 |
case 'D': /* compat */ |
171 |
flags |= LONG; |
172 |
/* FALLTHROUGH */
|
173 |
case 'd': |
174 |
c = CT_INT; |
175 |
ccfn = (u_long (*)(const char *, char **, int))strtol; |
176 |
base = 10;
|
177 |
break;
|
178 |
|
179 |
case 'i': |
180 |
c = CT_INT; |
181 |
ccfn = (u_long (*)(const char *, char **, int))strtol; |
182 |
base = 0;
|
183 |
break;
|
184 |
|
185 |
case 'O': /* compat */ |
186 |
flags |= LONG; |
187 |
/* FALLTHROUGH */
|
188 |
case 'o': |
189 |
c = CT_INT; |
190 |
ccfn = strtoul; |
191 |
base = 8;
|
192 |
break;
|
193 |
|
194 |
case 'u': |
195 |
c = CT_INT; |
196 |
ccfn = strtoul; |
197 |
base = 10;
|
198 |
break;
|
199 |
|
200 |
case 'X': /* compat XXX */ |
201 |
flags |= LONG; |
202 |
/* FALLTHROUGH */
|
203 |
case 'x': |
204 |
flags |= PFXOK; /* enable 0x prefixing */
|
205 |
c = CT_INT; |
206 |
ccfn = strtoul; |
207 |
base = 16;
|
208 |
break;
|
209 |
|
210 |
case 's': |
211 |
c = CT_STRING; |
212 |
break;
|
213 |
|
214 |
case '[': |
215 |
fmt = __sccl(ccltab, fmt); |
216 |
flags |= NOSKIP; |
217 |
c = CT_CCL; |
218 |
break;
|
219 |
|
220 |
case 'c': |
221 |
flags |= NOSKIP; |
222 |
c = CT_CHAR; |
223 |
break;
|
224 |
|
225 |
case 'p': /* pointer format is like hex */ |
226 |
flags |= POINTER | PFXOK; |
227 |
c = CT_INT; |
228 |
ccfn = strtoul; |
229 |
base = 16;
|
230 |
break;
|
231 |
|
232 |
case 'n': |
233 |
if (flags & SUPPRESS) /* ??? */ |
234 |
continue;
|
235 |
if (flags & SHORT)
|
236 |
*va_arg(ap, short *) = nread;
|
237 |
else if (flags & LONG) |
238 |
*va_arg(ap, long *) = nread;
|
239 |
else
|
240 |
*va_arg(ap, int *) = nread;
|
241 |
continue;
|
242 |
|
243 |
/*
|
244 |
* Disgusting backwards compatibility hacks. XXX
|
245 |
*/
|
246 |
case '\0': /* compat */ |
247 |
return (EOF); |
248 |
|
249 |
default: /* compat */ |
250 |
if (isupper(c))
|
251 |
flags |= LONG; |
252 |
c = CT_INT; |
253 |
ccfn = (u_long (*)(const char *, char **, int))strtol; |
254 |
base = 10;
|
255 |
break;
|
256 |
} |
257 |
|
258 |
/*
|
259 |
* We have a conversion that requires input.
|
260 |
*/
|
261 |
if (fp->_r <= 0 && __srefill(fp)) |
262 |
goto input_failure;
|
263 |
|
264 |
/*
|
265 |
* Consume leading white space, except for formats
|
266 |
* that suppress this.
|
267 |
*/
|
268 |
if ((flags & NOSKIP) == 0) { |
269 |
while (isspace(*fp->_p)) {
|
270 |
nread++; |
271 |
if (--fp->_r > 0) |
272 |
fp->_p++; |
273 |
else if (__srefill(fp)) |
274 |
goto input_failure;
|
275 |
} |
276 |
/*
|
277 |
* Note that there is at least one character in
|
278 |
* the buffer, so conversions that do not set NOSKIP
|
279 |
* ca no longer result in an input failure.
|
280 |
*/
|
281 |
} |
282 |
|
283 |
/*
|
284 |
* Do the conversion.
|
285 |
*/
|
286 |
switch (c) {
|
287 |
|
288 |
case CT_CHAR:
|
289 |
/* scan arbitrary characters (sets NOSKIP) */
|
290 |
if (width == 0) |
291 |
width = 1;
|
292 |
if (flags & SUPPRESS) {
|
293 |
size_t sum = 0;
|
294 |
for (;;) {
|
295 |
if ((size_t)(n = fp->_r) < width) {
|
296 |
sum += n; |
297 |
width -= n; |
298 |
fp->_p += n; |
299 |
if (__srefill(fp)) {
|
300 |
if (sum == 0) |
301 |
goto input_failure;
|
302 |
break;
|
303 |
} |
304 |
} else {
|
305 |
sum += width; |
306 |
fp->_r -= width; |
307 |
fp->_p += width; |
308 |
break;
|
309 |
} |
310 |
} |
311 |
nread += sum; |
312 |
} else {
|
313 |
size_t r = fread((void *)va_arg(ap, char *), 1, |
314 |
width, fp); |
315 |
|
316 |
if (r == 0) |
317 |
goto input_failure;
|
318 |
nread += r; |
319 |
nassigned++; |
320 |
} |
321 |
break;
|
322 |
|
323 |
case CT_CCL:
|
324 |
/* scan a (nonempty) character class (sets NOSKIP) */
|
325 |
if (width == 0) |
326 |
width = ~0; /* `infinity' */ |
327 |
/* take only those things in the class */
|
328 |
if (flags & SUPPRESS) {
|
329 |
n = 0;
|
330 |
while (ccltab[*fp->_p]) {
|
331 |
n++, fp->_r--, fp->_p++; |
332 |
if (--width == 0) |
333 |
break;
|
334 |
if (fp->_r <= 0 && __srefill(fp)) { |
335 |
if (n == 0) |
336 |
goto input_failure;
|
337 |
break;
|
338 |
} |
339 |
} |
340 |
if (n == 0) |
341 |
goto match_failure;
|
342 |
} else {
|
343 |
p0 = p = va_arg(ap, char *);
|
344 |
while (ccltab[*fp->_p]) {
|
345 |
fp->_r--; |
346 |
*p++ = *fp->_p++; |
347 |
if (--width == 0) |
348 |
break;
|
349 |
if (fp->_r <= 0 && __srefill(fp)) { |
350 |
if (p == p0)
|
351 |
goto input_failure;
|
352 |
break;
|
353 |
} |
354 |
} |
355 |
n = p - p0; |
356 |
if (n == 0) |
357 |
goto match_failure;
|
358 |
*p = 0;
|
359 |
nassigned++; |
360 |
} |
361 |
nread += n; |
362 |
break;
|
363 |
|
364 |
case CT_STRING:
|
365 |
/* like CCL, but zero-length string OK, & no NOSKIP */
|
366 |
if (width == 0) |
367 |
width = ~0;
|
368 |
if (flags & SUPPRESS) {
|
369 |
n = 0;
|
370 |
while (!isspace(*fp->_p)) {
|
371 |
n++, fp->_r--, fp->_p++; |
372 |
if (--width == 0) |
373 |
break;
|
374 |
if (fp->_r <= 0 && __srefill(fp)) |
375 |
break;
|
376 |
} |
377 |
nread += n; |
378 |
} else {
|
379 |
p0 = p = va_arg(ap, char *);
|
380 |
while (!isspace(*fp->_p)) {
|
381 |
fp->_r--; |
382 |
*p++ = *fp->_p++; |
383 |
if (--width == 0) |
384 |
break;
|
385 |
if (fp->_r <= 0 && __srefill(fp)) |
386 |
break;
|
387 |
} |
388 |
*p = 0;
|
389 |
nread += p - p0; |
390 |
nassigned++; |
391 |
} |
392 |
continue;
|
393 |
|
394 |
case CT_INT:
|
395 |
/* scan an integer as if by strtol/strtoul */
|
396 |
#ifdef hardway
|
397 |
if (width == 0 || width > sizeof(buf) - 1) |
398 |
width = sizeof(buf) - 1; |
399 |
#else
|
400 |
/* size_t is unsigned, hence this optimisation */
|
401 |
if (--width > sizeof(buf) - 2) |
402 |
width = sizeof(buf) - 2; |
403 |
width++; |
404 |
#endif
|
405 |
flags |= SIGNOK | NDIGITS | NZDIGITS; |
406 |
for (p = buf; width; width--) {
|
407 |
c = *fp->_p; |
408 |
/*
|
409 |
* Switch on the character; `goto ok'
|
410 |
* if we accept it as a part of number.
|
411 |
*/
|
412 |
switch (c) {
|
413 |
|
414 |
/*
|
415 |
* The digit 0 is always legal, but is
|
416 |
* special. For %i conversions, if no
|
417 |
* digits (zero or nonzero) have been
|
418 |
* scanned (only signs), we will have
|
419 |
* base==0. In that case, we should set
|
420 |
* it to 8 and enable 0x prefixing.
|
421 |
* Also, if we have not scanned zero digits
|
422 |
* before this, do not turn off prefixing
|
423 |
* (someone else will turn it off if we
|
424 |
* have scanned any nonzero digits).
|
425 |
*/
|
426 |
case '0': |
427 |
if (base == 0) { |
428 |
base = 8;
|
429 |
flags |= PFXOK; |
430 |
} |
431 |
if (flags & NZDIGITS)
|
432 |
flags &= ~(SIGNOK|NZDIGITS|NDIGITS); |
433 |
else
|
434 |
flags &= ~(SIGNOK|PFXOK|NDIGITS); |
435 |
goto ok;
|
436 |
|
437 |
/* 1 through 7 always legal */
|
438 |
case '1': case '2': case '3': |
439 |
case '4': case '5': case '6': case '7': |
440 |
base = basefix[base]; |
441 |
flags &= ~(SIGNOK | PFXOK | NDIGITS); |
442 |
goto ok;
|
443 |
|
444 |
/* digits 8 and 9 ok iff decimal or hex */
|
445 |
case '8': case '9': |
446 |
base = basefix[base]; |
447 |
if (base <= 8) |
448 |
break; /* not legal here */ |
449 |
flags &= ~(SIGNOK | PFXOK | NDIGITS); |
450 |
goto ok;
|
451 |
|
452 |
/* letters ok iff hex */
|
453 |
case 'A': case 'B': case 'C': |
454 |
case 'D': case 'E': case 'F': |
455 |
case 'a': case 'b': case 'c': |
456 |
case 'd': case 'e': case 'f': |
457 |
/* no need to fix base here */
|
458 |
if (base <= 10) |
459 |
break; /* not legal here */ |
460 |
flags &= ~(SIGNOK | PFXOK | NDIGITS); |
461 |
goto ok;
|
462 |
|
463 |
/* sign ok only as first character */
|
464 |
case '+': case '-': |
465 |
if (flags & SIGNOK) {
|
466 |
flags &= ~SIGNOK; |
467 |
goto ok;
|
468 |
} |
469 |
break;
|
470 |
|
471 |
/* x ok iff flag still set & 2nd char */
|
472 |
case 'x': case 'X': |
473 |
if (flags & PFXOK && p == buf + 1) { |
474 |
base = 16; /* if %i */ |
475 |
flags &= ~PFXOK; |
476 |
goto ok;
|
477 |
} |
478 |
break;
|
479 |
} |
480 |
|
481 |
/*
|
482 |
* If we got here, c is not a legal character
|
483 |
* for a number. Stop accumulating digits.
|
484 |
*/
|
485 |
break;
|
486 |
ok:
|
487 |
/*
|
488 |
* c is legal: store it and look at the next.
|
489 |
*/
|
490 |
*p++ = c; |
491 |
if (--fp->_r > 0) |
492 |
fp->_p++; |
493 |
else if (__srefill(fp)) |
494 |
break; /* EOF */ |
495 |
} |
496 |
/*
|
497 |
* If we had only a sign, it is no good; push
|
498 |
* back the sign. If the number ends in `x',
|
499 |
* it was [sign] '0' 'x', so push back the x
|
500 |
* and treat it as [sign] '0'.
|
501 |
*/
|
502 |
if (flags & NDIGITS) {
|
503 |
if (p > buf)
|
504 |
(void) ungetc(*(u_char *)--p, fp);
|
505 |
goto match_failure;
|
506 |
} |
507 |
c = ((u_char *)p)[-1];
|
508 |
if (c == 'x' || c == 'X') { |
509 |
--p; |
510 |
(void) ungetc(c, fp);
|
511 |
} |
512 |
if ((flags & SUPPRESS) == 0) { |
513 |
u_long res; |
514 |
|
515 |
*p = 0;
|
516 |
res = (*ccfn)(buf, (char **)NULL, base); |
517 |
if (flags & POINTER)
|
518 |
*va_arg(ap, void **) = (void *)res; |
519 |
else if (flags & SHORT) |
520 |
*va_arg(ap, short *) = res;
|
521 |
else if (flags & LONG) |
522 |
*va_arg(ap, long *) = res;
|
523 |
else
|
524 |
*va_arg(ap, int *) = res;
|
525 |
nassigned++; |
526 |
} |
527 |
nread += p - buf; |
528 |
break;
|
529 |
|
530 |
} |
531 |
} |
532 |
input_failure:
|
533 |
return (nassigned ? nassigned : -1); |
534 |
match_failure:
|
535 |
return (nassigned);
|
536 |
} |
537 |
|
538 |
/*
|
539 |
* Fill in the given table from the scanset at the given format
|
540 |
* (just after `['). Return a pointer to the character past the
|
541 |
* closing `]'. The table has a 1 wherever characters should be
|
542 |
* considered part of the scanset.
|
543 |
*/
|
544 |
static u_char *
|
545 |
__sccl(tab, fmt) |
546 |
char *tab;
|
547 |
u_char *fmt; |
548 |
{ |
549 |
int c, n, v;
|
550 |
|
551 |
/* first `clear' the whole table */
|
552 |
c = *fmt++; /* first char hat => negated scanset */
|
553 |
if (c == '^') { |
554 |
v = 1; /* default => accept */ |
555 |
c = *fmt++; /* get new first char */
|
556 |
} else
|
557 |
v = 0; /* default => reject */ |
558 |
/* should probably use memset here */
|
559 |
for (n = 0; n < 256; n++) |
560 |
tab[n] = v; |
561 |
if (c == 0) |
562 |
return (fmt - 1);/* format ended before closing ] */ |
563 |
|
564 |
/*
|
565 |
* Now set the entries corresponding to the actual scanset
|
566 |
* to the opposite of the above.
|
567 |
*
|
568 |
* The first character may be ']' (or '-') without being special;
|
569 |
* the last character may be '-'.
|
570 |
*/
|
571 |
v = 1 - v;
|
572 |
for (;;) {
|
573 |
tab[c] = v; /* take character c */
|
574 |
doswitch:
|
575 |
n = *fmt++; /* and examine the next */
|
576 |
switch (n) {
|
577 |
|
578 |
case 0: /* format ended too soon */ |
579 |
return (fmt - 1); |
580 |
|
581 |
case '-': |
582 |
/*
|
583 |
* A scanset of the form
|
584 |
* [01+-]
|
585 |
* is defined as `the digit 0, the digit 1,
|
586 |
* the character +, the character -', but
|
587 |
* the effect of a scanset such as
|
588 |
* [a-zA-Z0-9]
|
589 |
* is implementation defined. The V7 Unix
|
590 |
* scanf treats `a-z' as `the letters a through
|
591 |
* z', but treats `a-a' as `the letter a, the
|
592 |
* character -, and the letter a'.
|
593 |
*
|
594 |
* For compatibility, the `-' is not considerd
|
595 |
* to define a range if the character following
|
596 |
* it is either a close bracket (required by ANSI)
|
597 |
* or is not numerically greater than the character
|
598 |
* we just stored in the table (c).
|
599 |
*/
|
600 |
n = *fmt; |
601 |
if (n == ']' || n < c) { |
602 |
c = '-';
|
603 |
break; /* resume the for(;;) */ |
604 |
} |
605 |
fmt++; |
606 |
do { /* fill in the range */ |
607 |
tab[++c] = v; |
608 |
} while (c < n);
|
609 |
#if 1 /* XXX another disgusting compatibility hack */ |
610 |
/*
|
611 |
* Alas, the V7 Unix scanf also treats formats
|
612 |
* such as [a-c-e] as `the letters a through e'.
|
613 |
* This too is permitted by the standard....
|
614 |
*/
|
615 |
goto doswitch;
|
616 |
#else
|
617 |
c = *fmt++; |
618 |
if (c == 0) |
619 |
return (fmt - 1); |
620 |
if (c == ']') |
621 |
return (fmt);
|
622 |
#endif
|
623 |
break;
|
624 |
|
625 |
case ']': /* end of scanset */ |
626 |
return (fmt);
|
627 |
|
628 |
default: /* just another character */ |
629 |
c = n; |
630 |
break;
|
631 |
} |
632 |
} |
633 |
/* NOTREACHED */
|
634 |
} |