home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 387b.lha / dice_v2.02 / lib / stdio / sfmt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-03  |  4.4 KB  |  267 lines

  1.  
  2. /*
  3.  *  SFMT.C    *scanf()
  4.  *
  5.  *  (c)Copyright 1990, Matthew Dillon, All Rights Reserved
  6.  *
  7.  *  func format same as fgetc: func(desc)
  8.  *  unfunc format same as ungetc: func(c,desc)
  9.  */
  10.  
  11. #include <stdarg.h>
  12. #include <stdio.h>
  13.  
  14. #define F_SPAC        1
  15. #define F_PLUS        2
  16. #define F_MINUS     4
  17. #define F_HASH        8
  18. #define F_ZERO        16
  19.  
  20. #define F_SHORT     32
  21. #define F_LONG        64
  22. #define F_DLONG     128
  23.  
  24. int
  25. _sfmt(ctl, va, func, unfunc, desc, pcnt)
  26. unsigned char *ctl;
  27. va_list va;
  28. int (*func)();
  29. void (*unfunc)();
  30. int *pcnt;
  31. void *desc;
  32. {
  33.     int error = 0;
  34.     short flags;
  35.     short v;
  36.     short i1;
  37.     void *stor;
  38.  
  39.     *pcnt = 0;
  40.     v = (*func)(desc);
  41.     for (;;) {
  42.     while (*ctl && *ctl != '%') {
  43.         if (*ctl == ' ') {
  44.         if (v != ' ' && v != '\t' && v != '\n')
  45.             goto done;
  46.         while (v == ' ' || v == '\t' || v == '\n')
  47.             v = (*func)(desc);
  48.         while (*ctl == ' ')
  49.             ++ctl;
  50.         } else {
  51.         if (v != *ctl)
  52.             goto done;
  53.         v = (*func)(desc);
  54.         ++ctl;
  55.         }
  56.         if (v == 0)
  57.         goto done;
  58.     }
  59.     if (*ctl++ == 0)
  60.         goto done;
  61.     if (*ctl == '%') {      /*  match a %   */
  62.         if (v != '%')
  63.         goto done;
  64.         v = (*func)(desc);
  65.         ++ctl;
  66.         continue;
  67.     }
  68.  
  69.     /*
  70.      *  %[flags][width]c
  71.      */
  72.  
  73.     if (*ctl == '*') {
  74.         stor = NULL;
  75.         ++ctl;
  76.     } else {
  77.         stor = va_arg(va, void *);
  78.     }
  79.     i1 = -1;
  80.     if (*ctl >= '0' && *ctl <= '9') {
  81.         char c = *ctl;
  82.         i1 = 0;
  83.         while (c >= '0' && c <= '9') {
  84.         i1 = i1 * 10 + (c - '0');
  85.         c = *++ctl;
  86.         }
  87.     }
  88.     flags = 0;
  89.     for (;;) {
  90.         char c = *ctl;
  91.         if (c == 'h') {
  92.         ++ctl;
  93.         flags |= F_SHORT;   /*    only if sizeof(int) != 4 */
  94.         continue;
  95.         }
  96.         if (c == 'l') {
  97.         ++ctl;
  98.         flags |= F_LONG;
  99.         continue;
  100.         }
  101.         if (c == 'L') {
  102.         ++ctl;
  103.         flags |= F_DLONG;
  104.         continue;
  105.         }
  106.         break;
  107.     }
  108.     error = _sfmtone(*ctl++, &v, stor, func, desc, flags, i1);
  109.     if (error)
  110.         break;
  111.     ++*pcnt;
  112.     }
  113. done:
  114.     if (v != EOF)
  115.     (*unfunc)(v, desc);
  116.  
  117.     if (error && *pcnt == 0)
  118.     return(EOF);
  119.     return(0);
  120. }
  121.  
  122. _sfmtone(c, pv, stor, func, desc, flags, i1)
  123. char c;     /*  conversion specifier    */
  124. short *pv;    /*  last read value        */
  125. void *stor;    /*  pointer into storage    */
  126. int (*func)();  /*  fgetc type function     */
  127. void *desc;    /*  stdio/custom descriptor */
  128. short flags;    /*  conversion flags        */
  129. short i1;    /*  maximum field width     */
  130. {
  131.     short v = *pv;
  132.     int len = 0;
  133.     char buf[32];
  134.     char *ptr = buf;
  135.  
  136.     while (v == ' ' || v == '\t' || v == '\n')
  137.     v = (*func)(desc);
  138.  
  139.     if (i1 == 0)
  140.     return(0);
  141.     if (v == 0 || v == EOF)
  142.     return(EOF);
  143.  
  144.     switch(c) {
  145.     case 'c':
  146.     if (i1 == -1)
  147.         i1 = 1;
  148.     while (v != EOF && v != '\n' && i1) {
  149.         if (stor)
  150.         *(char *)stor = v;
  151.         v = (*func)(desc);
  152.         if (stor)
  153.         stor = (void *)((char *)stor + 1);
  154.         --i1;
  155.     }
  156.     break;
  157.     case 'd':
  158.     case 'u':
  159.     {
  160.         long n = 0;
  161.         short neg = 0;
  162.  
  163.         if (v != '-' && (v < '0' || v > '9'))
  164.         return(EOF);
  165.  
  166.         if (v == '-') {
  167.         neg = 1;
  168.         v = (*func)(desc);
  169.         --i1;
  170.         }
  171.         while (i1 && v >= '0' && v <= '9') {
  172.         n = n * 10 + v - '0';
  173.         v = (*func)(desc);
  174.         --i1;
  175.         }
  176.         if (neg)
  177.         n = -n;
  178.         if (stor)
  179.         *(int *)stor = n;
  180.     }
  181.     break;
  182.     case 'e':
  183.     case 'E':
  184.     case 'f':
  185.     case 'g':
  186.     case 'G':
  187.     case 'i':
  188.     case 'n':
  189.     break;
  190.     case 'o':
  191.     {
  192.         long n = 0;
  193.         short neg = 0;
  194.  
  195.         if (v != '-' && (v < '0' || v > '7'))
  196.         return(EOF);
  197.         if (v == '-') {
  198.         neg = 1;
  199.         v = (*func)(desc);
  200.         --i1;
  201.         }
  202.         while (i1 && v >= '0' && v <= '7') {
  203.         n = (n << 3) + v - '0';
  204.         v = (*func)(desc);
  205.         --i1;
  206.         }
  207.         if (neg)
  208.         n = -n;
  209.         if (stor)
  210.         *(int *)stor = n;
  211.     }
  212.     break;
  213.     case 'p':
  214.     break;
  215.     case 's':
  216.     while (i1 && v != ' ' && v != '\t' && v != '\n' && v != EOF) {
  217.         if (stor)
  218.         *(char *)stor = v;
  219.         v = (*func)(desc);
  220.         if (stor)
  221.         stor = (void *)((char *)stor + 1);
  222.         --i1;
  223.     }
  224.     if (stor)
  225.         *(char *)stor = 0;
  226.     break;
  227.     case 'x':
  228.     case 'X':
  229.     {
  230.         long n = 0;
  231.         short neg = 0;
  232.         long oldi1 = i1;
  233.  
  234.         if (v == '-') {
  235.         neg = 1;
  236.         v = (*func)(desc);
  237.         --i1;
  238.         }
  239.         while (i1) {
  240.         if (v >= '0' && v <= '9') {
  241.             n = (n << 4) + v - '0';
  242.         } else if (v >= 'a' && v <= 'f') {
  243.             n = (n << 4) + v - 'a' + 10;
  244.         } else if (v >= 'A' && v <= 'F') {
  245.             n = (n << 4) + v - 'A' + 10;
  246.         } else {
  247.             break;
  248.         }
  249.         v = (*func)(desc);
  250.         --i1;
  251.         }
  252.         if (i1 == oldi1)    /*  nada    */
  253.         return(EOF);
  254.         if (neg)
  255.         n = -n;
  256.         if (stor)
  257.         *(int *)stor = n;
  258.     }
  259.     break;
  260.     default:
  261.     return(-2);
  262.     }
  263.     *pv = v;
  264.     return(0);
  265. }
  266.  
  267.