home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDSC / BDSC-4 / BDSLIB.ARK / FORMAT.C < prev    next >
Text File  |  1983-07-15  |  6KB  |  287 lines

  1. /*
  2.  * This file contains all of the formatted I/O functions. They
  3.  * are essentially those from BDS C 1.5 with some alterations
  4.  * to accomodate the I/O primitives of the standard library.
  5.  * Last Edit 7/1/83
  6.  */
  7.  
  8. printf(format)
  9. char *format;
  10. {
  11.     void fputc();
  12.     _spr(&format, &fputc, stdout);    /* use "_spr" to form the output */
  13. }
  14.  
  15. sprintf(buffer,format)
  16. char *buffer, *format;
  17. {
  18.     int _sspr();
  19.     _spr(&format, &_sspr, &buffer);    /* call _spr to do all the work */
  20.     *buffer = '\0';
  21. }
  22.  
  23. _sspr(c,strptr)
  24. char **strptr;
  25. {
  26.     *(*strptr)++ = c;
  27. }
  28.  
  29. int fprintf(stream,format)
  30. char *format;
  31. FILE *stream;
  32. {
  33.     void fputc();
  34.     _spr(&format, &fputc, stream);
  35. }
  36.  
  37. int scanf(format)
  38. char *format;
  39. {
  40.     char line[MAXLINE];
  41.     gets(line);            /* get a line of input from user */
  42.     return _scn(line,&format);    /* and scan it with "_scn"     */
  43. }
  44.  
  45. int sscanf(line,format)
  46. char *line, *format;
  47. {
  48.     return _scn(line,&format);    /* let _scn do all the work */
  49. }
  50.  
  51.  
  52. int
  53. fscanf(stream,format)
  54. char *format;
  55. FILE *stream;
  56. {
  57.     char text[MAXLINE];
  58.     if (fgets(text,stream) == NULL)
  59.         return 0;
  60.     return _scn(text,&format);
  61. }
  62.  
  63.  
  64. _spr(fmt,putcf,arg1)
  65. int (*putcf)();
  66. char **fmt;
  67. {
  68.     char _uspr(), c, base, *sptr, *format;
  69.     char wbuf[MAXLINE], *wptr, pf, ljflag, zfflag;
  70.     int width, precision,  *args;
  71.  
  72.     format = *fmt++;    /* fmt first points to the format string    */
  73.     args = fmt;        /* now fmt points to the first arg value    */
  74.  
  75.     while (c = *format++)
  76.       if (c == '%') {
  77.         wptr = wbuf;
  78.         precision = 6;
  79.         ljflag = pf = zfflag = 0;
  80.  
  81.         if (*format == '-') {
  82.             format++;
  83.             ljflag++;
  84.          }
  85.  
  86.  
  87.         if (*format == '0') zfflag++;    /* test for zero-fill */
  88.  
  89.         width = (isdigit(*format)) ? _gv2(&format) : 0;
  90.  
  91.         if ((c = *format++) == '.') {
  92.             precision = _gv2(&format);
  93.             pf++;
  94.             c = *format++;
  95.          }
  96.  
  97.         switch(toupper(c)) {
  98.  
  99.         case 'D':  if (*args < 0) {
  100.                 *wptr++ = '-';
  101.                 *args = -*args;
  102.                 width--;
  103.                 }
  104.  
  105.         case 'U':  base = 10; goto val;
  106.         case 'X':  base = 16; goto val;
  107.         case 'O':  base = 8;  goto val;
  108.         case 'B':  base = 2;  /* note that arbitrary bases can be
  109.                          added easily before this line */
  110.  
  111.              val:  width -= _uspr(&wptr,*args++,base);
  112.                goto pad;
  113.  
  114.         case 'C':  *wptr++ = *args++;
  115.                width--;
  116.                goto pad;
  117.  
  118.         case 'S':  if (!pf) precision = 200;
  119.                sptr = *args++;
  120.                while (*sptr && precision) {
  121.                 *wptr++ = *sptr++;
  122.                 precision--;
  123.                 width--;
  124.                 }
  125.  
  126.              pad:  *wptr = '\0';
  127.              pad2: wptr = wbuf;
  128.                if (!ljflag)
  129.                 while (width-- > 0)
  130.                     (*putcf)(zfflag ? '0' : ' ',arg1);
  131.  
  132.                while (*wptr)
  133.                 (*putcf)(*wptr++,arg1) ;
  134.  
  135.                if (ljflag)
  136.                 while (width-- > 0)
  137.                     (*putcf)(' ',arg1) ;
  138.                break;
  139.  
  140.          default:  (*putcf)(c,arg1) ;
  141.          }
  142.       }
  143.       else (*putcf)(c,arg1) ;
  144. }
  145.  
  146. /*
  147.     Internal routine used by "_spr" to perform ascii-
  148.     to-decimal conversion and update an associated pointer:
  149. */
  150.  
  151. int _gv2(sptr)
  152. char **sptr;
  153. {
  154.     int n;
  155.     n = 0;
  156.     while (isdigit(**sptr)) n = 10 * n + *(*sptr)++ - '0';
  157.     return n;
  158. }
  159.  
  160. char _uspr(string, n, base)
  161. char **string;
  162. unsigned n;
  163. {
  164.     char length;
  165.     if (n<base) {
  166.         *(*string)++ = (n < 10) ? n + '0' : n + 55;
  167.         return 1;
  168.     }
  169.     length = _uspr(string, n/base, base);
  170.     _uspr(string, n%base, base);
  171.     return length + 1;
  172. }
  173.  
  174.  
  175. /*
  176.     General formatted input conversion routine. "line" points
  177.     to a string containing ascii text to be converted, and "fmt"
  178.     points to an argument list consisting of first a format
  179.     string and then a list of pointers to the destination objects.
  180. */
  181.  
  182. int _scn(line,fmt)
  183. char *line, **fmt;
  184. {
  185.     char sf, c, base, n, *sptr, *format;
  186.     int sign, val, **args;
  187.  
  188.     format = *fmt++;    /* fmt first points to the format string */
  189.     args = fmt;        /* now it points to the arg list */
  190.  
  191.     n = 0;
  192.     while (c = *format++)
  193.     {
  194.        if (isspace(c)) continue;    /* skip white space in format string */
  195.        if (c != '%')        /* if not %, must match text */
  196.         {
  197.         if (c != _igs(&line)) return n;
  198.         else line++;
  199.         }
  200.        else        /* process conversion */
  201.         {
  202.         sign = 1;
  203.         base = 10;
  204.         sf = 0;
  205.         if ((c = *format++) == '*')
  206.          {
  207.             sf++;        /* if "*" given, supress assignment */
  208.             c = *format++;
  209.          }
  210.         switch (toupper(c))
  211.          {
  212.            case 'X': base = 16;
  213.                  goto doval;
  214.  
  215.            case 'O': base = 8;
  216.                  goto doval;
  217.  
  218.            case 'B': base = 2;
  219.                  goto doval;
  220.  
  221.            case 'D': if (_igs(&line) == '-') {
  222.                 sign = -1;
  223.                 line++;
  224.                   }
  225.  
  226.        doval:  case 'U': val = 0;
  227.                  if (_bc(_igs(&line),base) == ERROR)
  228.                 return n;
  229.                  while ((c = _bc(*line++,base)) != 255)
  230.                 val = val * base + c;
  231.                  line--;
  232.                  break;
  233.  
  234.            case 'S': _igs(&line);
  235.                  sptr = *args;
  236.                  while (c = *line++)   {
  237.                 if (c == *format) {
  238.                     format++;
  239.                     break;
  240.                  }
  241.                 if (!sf) *sptr++ = c;
  242.                   }                
  243.                  if (!sf) {
  244.                 n++;
  245.                 *sptr = '\0';
  246.                 args++;
  247.                   }
  248.                  continue;
  249.  
  250.            case 'C': if (!sf) {
  251.                 poke(*args++, *line);
  252.                 n++;
  253.                  }
  254.                  line++;
  255.                  continue;
  256.  
  257.            default:  return n;
  258.          }
  259.         if (!sf)
  260.          {
  261.             **args++ = val * sign;
  262.             n++;
  263.          }
  264.         }
  265.        if (!*line) return n;    /* if end of input string, return */
  266.     }
  267.     return n;
  268. }
  269.  
  270. char _igs(sptr)
  271. char **sptr;
  272. {
  273.     char c;
  274.     while (isspace((c = **sptr))) ++*sptr;
  275.     return (c);
  276. }
  277.  
  278. int _bc(c,b)
  279. char c,b;
  280. {
  281.     if (isalpha((c = toupper(c)))) c -= 55;
  282.          else  if (isdigit(c))  c -= 0x30;
  283.      else return ERROR;
  284.     if (c > b-1) return ERROR;
  285.         else return c;
  286. }
  287.