home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / libc / stdio / doscan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  4.4 KB  |  276 lines

  1. #include <stdio.h>
  2. #include    <ctype.h>
  3.  
  4. #define    SPC    01
  5. #define    STP    02
  6.  
  7. #define    SHORT    0
  8. #define    REGULAR    1
  9. #define    LONG    2
  10. #define    INT    0
  11. #define    FLOAT    1
  12.  
  13. char    *_getccl();
  14.  
  15. char    _sctab[128] = {
  16.     0,0,0,0,0,0,0,0,
  17.     0,SPC,SPC,0,0,0,0,0,
  18.     0,0,0,0,0,0,0,0,
  19.     0,0,0,0,0,0,0,0,
  20.     SPC,0,0,0,0,0,0,0,
  21.     0,0,0,0,0,0,0,0,
  22.     0,0,0,0,0,0,0,0,
  23.     0,0,0,0,0,0,0,0,
  24. };
  25.  
  26. _doscan(iop, fmt, argp)
  27. FILE *iop;
  28. register char *fmt;
  29. register int **argp;
  30. {
  31.     register int ch;
  32.     int nmatch, len, ch1;
  33.     int **ptr, fileended, size;
  34.  
  35.     nmatch = 0;
  36.     fileended = 0;
  37.     for (;;) switch (ch = *fmt++) {
  38.     case '\0': 
  39.         return (nmatch);
  40.     case '%': 
  41.         if ((ch = *fmt++) == '%')
  42.             goto def;
  43.         ptr = 0;
  44.         if (ch != '*')
  45.             ptr = argp++;
  46.         else
  47.             ch = *fmt++;
  48.         len = 0;
  49.         size = REGULAR;
  50.         while (isdigit(ch)) {
  51.             len = len*10 + ch - '0';
  52.             ch = *fmt++;
  53.         }
  54.         if (len == 0)
  55.             len = 30000;
  56.         if (ch=='l') {
  57.             ch = *fmt++;
  58.             size = LONG;
  59.         } else if (ch=='h') {
  60.             size = SHORT;
  61.             ch = *fmt++;
  62.         } else if (ch=='[')
  63.             fmt = _getccl(fmt);
  64.         if (isupper(ch)) {
  65.             ch = tolower(ch);
  66.             size = LONG;
  67.         }
  68.         if (ch == '\0')
  69.             return(-1);
  70.         if (_innum(ptr, ch, len, size, iop, &fileended) && ptr)
  71.             nmatch++;
  72.         if (fileended)
  73.             return(nmatch? nmatch: -1);
  74.         break;
  75.  
  76.     case ' ':
  77.     case '\n':
  78.     case '\t': 
  79.         while ((ch1 = getc(iop))==' ' || ch1=='\t' || ch1=='\n')
  80.             ;
  81.         if (ch1 != EOF)
  82.             ungetc(ch1, iop);
  83.         break;
  84.  
  85.     default: 
  86.     def:
  87.         ch1 = getc(iop);
  88.         if (ch1 != ch) {
  89.             if (ch1==EOF)
  90.                 return(-1);
  91.             ungetc(ch1, iop);
  92.             return(nmatch);
  93.         }
  94.     }
  95. }
  96.  
  97. _innum(ptr, type, len, size, iop, eofptr)
  98. int **ptr, *eofptr;
  99. struct _iobuf *iop;
  100. {
  101.     extern double atof();
  102.     register char *np;
  103.     char numbuf[64];
  104.     register c, base;
  105.     int expseen, scale, negflg, c1, ndigit;
  106.     long lcval;
  107.  
  108.     if (type=='c' || type=='s' || type=='[')
  109.         return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len, iop, eofptr));
  110.     lcval = 0;
  111.     ndigit = 0;
  112.     scale = INT;
  113.     if (type=='e'||type=='f')
  114.         scale = FLOAT;
  115.     base = 10;
  116.     if (type=='o')
  117.         base = 8;
  118.     else if (type=='x')
  119.         base = 16;
  120.     np = numbuf;
  121.     expseen = 0;
  122.     negflg = 0;
  123.     while ((c = getc(iop))==' ' || c=='\t' || c=='\n');
  124.     if (c=='-') {
  125.         negflg++;
  126.         *np++ = c;
  127.         c = getc(iop);
  128.         len--;
  129.     } else if (c=='+') {
  130.         len--;
  131.         c = getc(iop);
  132.     }
  133.     for ( ; --len>=0; *np++ = c, c = getc(iop)) {
  134.         if (isdigit(c)
  135.          || base==16 && ('a'<=c && c<='f' || 'A'<=c && c<='F')) {
  136.             ndigit++;
  137.             if (base==8)
  138.                 lcval <<=3;
  139.             else if (base==10)
  140.                 lcval = ((lcval<<2) + lcval)<<1;
  141.             else
  142.                 lcval <<= 4;
  143.             c1 = c;
  144.             if ('0'<=c && c<='9')
  145.                 c -= '0';
  146.             else if ('a'<=c && c<='f')
  147.                 c -= 'a'-10;
  148.             else
  149.                 c -= 'A'-10;
  150.             lcval += c;
  151.             c = c1;
  152.             continue;
  153.         } else if (c=='.') {
  154.             if (base!=10 || scale==INT)
  155.                 break;
  156.             ndigit++;
  157.             continue;
  158.         } else if ((c=='e'||c=='E') && expseen==0) {
  159.             if (base!=10 || scale==INT || ndigit==0)
  160.                 break;
  161.             expseen++;
  162.             *np++ = c;
  163.             c = getc(iop);
  164.             if (c!='+'&&c!='-'&&('0'>c||c>'9'))
  165.                 break;
  166.         } else
  167.             break;
  168.     }
  169.     if (negflg)
  170.         lcval = -lcval;
  171.     if (c != EOF) {
  172.         ungetc(c, iop);
  173.         *eofptr = 0;
  174.     } else
  175.         *eofptr = 1;
  176.     if (ptr==NULL || np==numbuf)
  177.         return(0);
  178.     *np++ = 0;
  179.     switch((scale<<4) | size) {
  180.  
  181.     case (FLOAT<<4) | SHORT:
  182.     case (FLOAT<<4) | REGULAR:
  183.         **(float **)ptr = atof(numbuf);
  184.         break;
  185.  
  186.     case (FLOAT<<4) | LONG:
  187.         **(double **)ptr = atof(numbuf);
  188.         break;
  189.  
  190.     case (INT<<4) | SHORT:
  191.         **(short **)ptr = lcval;
  192.         break;
  193.  
  194.     case (INT<<4) | REGULAR:
  195.         **(int **)ptr = lcval;
  196.         break;
  197.  
  198.     case (INT<<4) | LONG:
  199.         **(long **)ptr = lcval;
  200.         break;
  201.     }
  202.     return(1);
  203. }
  204.  
  205. _instr(ptr, type, len, iop, eofptr)
  206. register char *ptr;
  207. register struct _iobuf *iop;
  208. int *eofptr;
  209. {
  210.     register ch;
  211.     register char *optr;
  212.     int ignstp;
  213.  
  214.     *eofptr = 0;
  215.     optr = ptr;
  216.     if (type=='c' && len==30000)
  217.         len = 1;
  218.     ignstp = 0;
  219.     if (type=='s')
  220.         ignstp = SPC;
  221.     while (_sctab[ch = getc(iop)] & ignstp)
  222.         if (ch==EOF)
  223.             break;
  224.     ignstp = SPC;
  225.     if (type=='c')
  226.         ignstp = 0;
  227.     else if (type=='[')
  228.         ignstp = STP;
  229.     while (ch!=EOF && (_sctab[ch]&ignstp)==0) {
  230.         if (ptr)
  231.             *ptr++ = ch;
  232.         if (--len <= 0)
  233.             break;
  234.         ch = getc(iop);
  235.     }
  236.     if (ch != EOF) {
  237.         if (len > 0)
  238.             ungetc(ch, iop);
  239.         *eofptr = 0;
  240.     } else
  241.         *eofptr = 1;
  242.     if (ptr && ptr!=optr) {
  243.         if (type!='c')
  244.             *ptr++ = '\0';
  245.         return(1);
  246.     }
  247.     return(0);
  248. }
  249.  
  250. char *
  251. _getccl(s)
  252. register char *s;
  253. {
  254.     register c, t;
  255.  
  256.     t = 0;
  257.     if (*s == '^') {
  258.         t++;
  259.         s++;
  260.     }
  261.     for (c = 0; c < 128; c++)
  262.         if (t)
  263.             _sctab[c] &= ~STP;
  264.         else
  265.             _sctab[c] |= STP;
  266.     while (((c = *s++)&0177) != ']') {
  267.         if (t)
  268.             _sctab[c++] |= STP;
  269.         else
  270.             _sctab[c++] &= ~STP;
  271.         if (c==0)
  272.             return(--s);
  273.     }
  274.     return(s);
  275. }
  276.