OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uC-libc/] [stdio2/] [scanf.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
#include <stdio.h>
2
#include <ctype.h>
3
#include <string.h>
4
 
5
#ifdef __STDC__
6
#include <stdarg.h>
7
#define va_strt      va_start
8
#else
9
#include <varargs.h>
10
#define va_strt(p,i) va_start(p)
11
#endif
12
 
13
#ifdef L_scanf
14
#ifdef __STDC__
15
int scanf(const char * fmt, ...)
16
#else
17
int scanf(fmt, va_alist)
18
__const char *fmt;
19
va_dcl
20
#endif
21
{
22
  va_list ptr;
23
  int rv;
24
  va_strt(ptr, fmt);
25
  rv = vfscanf(stdin,fmt,ptr);
26
  va_end(ptr);
27
  return rv;
28
}
29
#endif
30
 
31
#ifdef L_sscanf
32
#ifdef __STDC__
33
int sscanf(char * sp, const char * fmt, ...)
34
#else
35
int sscanf(sp, fmt, va_alist)
36
char * sp;
37
__const char *fmt;
38
va_dcl
39
#endif
40
{
41
static FILE  string[1] =
42
{
43
   {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
44
    _IOFBF | __MODE_READ}
45
};
46
 
47
  va_list ptr;
48
  int rv;
49
  va_strt(ptr, fmt);
50
  string->bufpos = sp;
51
  rv = vfscanf(string,fmt,ptr);
52
  va_end(ptr);
53
  return rv;
54
}
55
#endif
56
 
57
#ifdef L_fscanf
58
#ifdef __STDC__
59
int fscanf(FILE * fp, const char * fmt, ...)
60
#else
61
int fscanf(fp, fmt, va_alist)
62
FILE * fp;
63
__const char *fmt;
64
va_dcl
65
#endif
66
{
67
  va_list ptr;
68
  int rv;
69
  va_strt(ptr, fmt);
70
  rv = vfscanf(fp,fmt,ptr);
71
  va_end(ptr);
72
  return rv;
73
}
74
#endif
75
 
76
#ifdef L_vscanf
77
int vscanf(fmt, ap)
78
__const char *fmt;
79
va_list ap;
80
{
81
  return vfscanf(stdin,fmt,ap);
82
}
83
#endif
84
 
85
#ifdef L_vsscanf
86
int vsscanf(sp, fmt, ap)
87
char * sp;
88
__const char *fmt;
89
{
90
static FILE  string[1] =
91
{
92
   {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
93
    _IOFBF | __MODE_READ}
94
};
95
 
96
  string->bufpos = sp;
97
  return vfscanf(string,fmt,ap);
98
}
99
#endif
100
 
101
#ifdef L_vfscanf
102
 
103
#if FLOATS
104
int _vfscanf_fp_ref = 1;
105
#else
106
int _vfscanf_fp_ref = 0;
107
#endif
108
 
109
/* #define      skip()  do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/
110
 
111
#define skip()  while(isspace(c)) { if ((c=getc(fp))<1) goto done; }
112
 
113
#if FLOATS
114
/* fp scan actions */
115
#define F_NADA  0        /* just change state */
116
#define F_SIGN  1       /* set sign */
117
#define F_ESIGN 2       /* set exponent's sign */
118
#define F_INT   3       /* adjust integer part */
119
#define F_FRAC  4       /* adjust fraction part */
120
#define F_EXP   5       /* adjust exponent part */
121
#define F_QUIT  6
122
 
123
#define NSTATE  8
124
#define FS_INIT         0        /* initial state */
125
#define FS_SIGNED       1       /* saw sign */
126
#define FS_DIGS         2       /* saw digits, no . */
127
#define FS_DOT          3       /* saw ., no digits */
128
#define FS_DD           4       /* saw digits and . */
129
#define FS_E            5       /* saw 'e' */
130
#define FS_ESIGN        6       /* saw exp's sign */
131
#define FS_EDIGS        7       /* saw exp's digits */
132
 
133
#define FC_DIG          0
134
#define FC_DOT          1
135
#define FC_E            2
136
#define FC_SIGN         3
137
 
138
/* given transition,state do what action? */
139
int fp_do[][NSTATE] = {
140
        {F_INT,F_INT,F_INT,
141
         F_FRAC,F_FRAC,
142
         F_EXP,F_EXP,F_EXP},    /* see digit */
143
        {F_NADA,F_NADA,F_NADA,
144
         F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT},   /* see '.' */
145
        {F_QUIT,F_QUIT,
146
         F_NADA,F_QUIT,F_NADA,
147
         F_QUIT,F_QUIT,F_QUIT}, /* see e/E */
148
        {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT,
149
         F_ESIGN,F_QUIT,F_QUIT},        /* see sign */
150
};
151
/* given transition,state what is new state? */
152
int fp_ns[][NSTATE] = {
153
        {FS_DIGS,FS_DIGS,FS_DIGS,
154
         FS_DD,FS_DD,
155
         FS_EDIGS,FS_EDIGS,FS_EDIGS},   /* see digit */
156
        {FS_DOT,FS_DOT,FS_DD,
157
         },     /* see '.' */
158
        {0,0,
159
         FS_E,0,FS_E,
160
        },      /* see e/E */
161
        {FS_SIGNED,0,0,0,0,
162
         FS_ESIGN,0,0},   /* see sign */
163
};
164
/* which states are valid terminators? */
165
int fp_sval[NSTATE] = {
166
        0,0,1,0,1,0,0,1
167
};
168
#endif
169
 
170
int
171
vfscanf(fp, fmt, ap)
172
register FILE *fp;
173
register char *fmt;
174
va_list ap;
175
 
176
{
177
   register long n;
178
   register int c, width, lval, cnt = 0;
179
   int   store, neg, base, wide1, endnull, rngflag, c2;
180
   register unsigned char *p;
181
   unsigned char delim[128], digits[17], *q;
182
#if FLOATS
183
   long  frac, expo;
184
   int   eneg, fraclen, fstate, trans;
185
   double fx, fp_scan();
186
#endif
187
 
188
   if (!*fmt)
189
      return (0);
190
 
191
   c = getc(fp);
192
   while (c > 0)
193
   {
194
      store = 0;
195
      if (*fmt == '%')
196
      {
197
         n = 0;
198
         width = -1;
199
         wide1 = 1;
200
         base = 10;
201
         lval = (sizeof(long) == sizeof(int));
202
         store = 1;
203
         endnull = 1;
204
         neg = -1;
205
 
206
         strcpy(delim, "\011\012\013\014\015 ");
207
         strcpy(digits, "0123456789ABCDEF");
208
 
209
         if (fmt[1] == '*')
210
         {
211
            endnull = store = 0;
212
            ++fmt;
213
         }
214
 
215
         while (isdigit(*++fmt))/* width digit(s) */
216
         {
217
            if (width == -1)
218
               width = 0;
219
            wide1 = width = (width * 10) + (*fmt - '0');
220
         }
221
         --fmt;
222
       fmtnxt:
223
         ++fmt;
224
         switch (tolower(*fmt)) /* tolower() is a MACRO! */
225
         {
226
         case '*':
227
            endnull = store = 0;
228
            goto fmtnxt;
229
 
230
         case 'l':              /* long data */
231
            lval = 1;
232
            goto fmtnxt;
233
         case 'h':              /* short data */
234
            lval = 0;
235
            goto fmtnxt;
236
 
237
         case 'i':              /* any-base numeric */
238
            base = 0;
239
            goto numfmt;
240
 
241
         case 'b':              /* unsigned binary */
242
            base = 2;
243
            goto numfmt;
244
 
245
         case 'o':              /* unsigned octal */
246
            base = 8;
247
            goto numfmt;
248
 
249
         case 'x':              /* unsigned hexadecimal */
250
            base = 16;
251
            goto numfmt;
252
 
253
         case 'd':              /* SIGNED decimal */
254
            neg = 0;
255
            /* FALL-THRU */
256
 
257
         case 'u':              /* unsigned decimal */
258
          numfmt:skip();
259
 
260
            if (isupper(*fmt))
261
               lval = 1;
262
 
263
            if (!base)
264
            {
265
               base = 10;
266
               neg = 0;
267
               if (c == '%')
268
               {
269
                  base = 2;
270
                  goto skip1;
271
               }
272
               else if (c == '0')
273
               {
274
                  c = getc(fp);
275
                  if (c < 1)
276
                     goto savnum;
277
                  if ((c != 'x')
278
                      && (c != 'X'))
279
                  {
280
                     base = 8;
281
                     digits[8] = '\0';
282
                     goto zeroin;
283
                  }
284
                  base = 16;
285
                  goto skip1;
286
               }
287
            }
288
 
289
            if ((neg == 0) && (base == 10)
290
                && ((neg = (c == '-')) || (c == '+')))
291
            {
292
             skip1:
293
               c = getc(fp);
294
               if (c < 1)
295
                  goto done;
296
            }
297
 
298
            digits[base] = '\0';
299
            p = ((unsigned char *)
300
                 strchr(digits, toupper(c)));
301
 
302
            if ((!c || !p) && width)
303
               goto done;
304
 
305
            while (p && width-- && c)
306
            {
307
               n = (n * base) + (p - digits);
308
               c = getc(fp);
309
             zeroin:
310
               p = ((unsigned char *)
311
                    strchr(digits, toupper(c)));
312
            }
313
          savnum:
314
            if (store)
315
            {
316
               if (neg == 1)
317
                  n = -n;
318
               if (lval)
319
                  *va_arg(ap, long*) = n;
320
               else
321
                  *va_arg(ap, short*) = n;
322
               ++cnt;
323
            }
324
            break;
325
 
326
#if FLOATS
327
         case 'e':              /* float */
328
         case 'f':
329
         case 'g':
330
            skip();
331
            fprintf(stderr,"LIBM:SCANF");
332
 
333
            if (isupper(*fmt))
334
               lval = 1;
335
 
336
            fstate = FS_INIT;
337
            neg = 0;
338
            eneg = 0;
339
            n = 0;
340
            frac = 0;
341
            expo = 0;
342
            fraclen = 0;
343
 
344
            while (c && width--)
345
            {
346
               if (c >= '0' && c <= '9')
347
                  trans = FC_DIG;
348
               else if (c == '.')
349
                  trans = FC_DOT;
350
               else if (c == '+' || c == '-')
351
                  trans = FC_SIGN;
352
               else if (tolower(c) == 'e')
353
                  trans = FC_E;
354
               else
355
                  goto fdone;
356
 
357
               switch (fp_do[trans][fstate])
358
               {
359
               case F_SIGN:
360
                  neg = (c == '-');
361
                  break;
362
               case F_ESIGN:
363
                  eneg = (c == '-');
364
                  break;
365
               case F_INT:
366
                  n = 10 * n + (c - '0');
367
                  break;
368
               case F_FRAC:
369
                  frac = 10 * frac + (c - '0');
370
                  fraclen++;
371
                  break;
372
               case F_EXP:
373
                  expo = 10 * expo + (c - '0');
374
                  break;
375
               case F_QUIT:
376
                  goto fdone;
377
               }
378
               fstate = fp_ns[trans][fstate];
379
               c = getc(fp);
380
            }
381
 
382
          fdone:
383
            if (!fp_sval[fstate])
384
               goto done;
385
            if (store)
386
            {
387
               fx = fp_scan(neg, eneg, n, frac, expo, fraclen);
388
               if (lval)
389
                  *va_arg(ap, double *) = fx;
390
               else
391
                  *va_arg(ap, float *) = fx;
392
               ++cnt;
393
            }
394
            break;
395
#else
396
         case 'e':              /* float */
397
         case 'f':
398
         case 'g':
399
                fprintf(stderr, "LIBC:SCANF");
400
                exit(-1);
401
#endif
402
 
403
         case 'c':              /* character data */
404
            width = wide1;
405
            lval = endnull = 0;
406
            delim[0] = '\0';
407
            goto strproc;
408
 
409
         case '[':              /* string w/ delimiter set */
410
 
411
            /* get delimiters */
412
            p = delim;
413
 
414
            if (*++fmt == '^')
415
            {
416
               fmt++;
417
               lval = 0;
418
            }
419
            else
420
               lval = 1;
421
 
422
            rngflag = 2;
423
            if ((*fmt == ']') || (*fmt == '-'))
424
            {
425
               *p++ = *fmt++;
426
               rngflag = 0;
427
            }
428
 
429
            while (*fmt != ']')
430
            {
431
               if (*fmt == '\0')
432
                  goto done;
433
               switch (rngflag)
434
               {
435
               case 1:
436
                  c2 = *(p - 2);
437
                  if (c2 <= *fmt)
438
                  {
439
                     p -= 2;
440
                     while (c2 < *fmt)
441
                        *p++ = c2++;
442
                     rngflag = 2;
443
                     break;
444
                  }
445
                  /* fall thru intentional */
446
 
447
               case 0:
448
                  rngflag = (*fmt == '-');
449
                  break;
450
 
451
               case 2:
452
                  rngflag = 0;
453
               }
454
 
455
               *p++ = *fmt++;
456
            }
457
 
458
            *p = '\0';
459
            goto strproc;
460
 
461
         case 's':              /* string data */
462
            lval = 0;
463
            skip();
464
          strproc:
465
            /* process string */
466
            p = va_arg(ap, unsigned char *);
467
 
468
            /* if the 1st char fails, match fails */
469
            if (width)
470
            {
471
               q = ((unsigned char *)
472
                    strchr(delim, c));
473
               if ((c < 1) || lval == (q==0))
474
               {
475
                  if (endnull)
476
                     *p = '\0';
477
                  goto done;
478
               }
479
            }
480
 
481
            for (;;)            /* FOREVER */
482
            {
483
               if (store)
484
                  *p++ = c;
485
               if (((c = getc(fp)) < 1) ||
486
                   (--width == 0))
487
                  break;
488
 
489
               q = ((unsigned char *)
490
                    strchr(delim, c));
491
               if (lval == (q==0))
492
                  break;
493
            }
494
 
495
            if (store)
496
            {
497
               if (endnull)
498
                  *p = '\0';
499
               ++cnt;
500
            }
501
            break;
502
 
503
         case '\0':             /* early EOS */
504
            --fmt;
505
            /* FALL THRU */
506
 
507
         default:
508
            goto cmatch;
509
         }
510
      }
511
      else if (isspace(*fmt))   /* skip whitespace */
512
      {
513
         skip();
514
      }
515
      else
516
      {                         /* normal match char */
517
       cmatch:
518
         if (c != *fmt)
519
            break;
520
         c = getc(fp);
521
      }
522
 
523
      if (!*++fmt)
524
         break;
525
   }
526
 
527
 done:                          /* end of scan */
528
   if ((c == EOF) && (cnt == 0))
529
      return (EOF);
530
 
531
   if( c != EOF )
532
      ungetc(c, fp);
533
   return (cnt);
534
}
535
 
536
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.