home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 146_01 / prtlib.c < prev    next >
Text File  |  1985-03-10  |  9KB  |  310 lines

  1. /*
  2. HEADER:       CUG146.02;
  3. TITLE:        Small C compiler for 6800;
  4. DESCRIPTION:  "Contains the source for library functions: printf,
  5.               fprintf, sprintf, fmspr, fputs";
  6. KEYWORDS:     printf, fpintf, sprintf, fmspr, fputs;
  7. FILENAME:     prtlib.c;
  8. WARNINGS:     "Functions differ from those defined in K&R in that they
  9.               need a parameter count as the last argument in a
  10.               calling routine.";
  11. */
  12.  /*
  13.         This file contains the source for the following
  14.         library functions:
  15.  
  16.         printf          fprintf         sprintf         fmspr
  17.         fputs
  18.  
  19.         These functions differ from the ones defined in K&R in
  20.         one important aspect only -- they require a parameter
  21.         count as the very last argument in the calling routine.
  22.  
  23.         For example:
  24.                printf("Hello World !");      in K&R
  25.         becomes:
  26.                printf("Hello World !", 1);   for Small-C
  27.  
  28.         This abberation is caused by the fact that Small-C
  29.         pushes its calling arguments in the order encountered,
  30.         i.e. left to right, instead of the normal C conven-
  31.         tion of right to left.  Therefore, the called routine
  32.         must be somehow told the number of arguments present.
  33.  
  34.         Note that all the upper-level formatted I/O functions
  35.         ("printf", "fprintf", and "sprintf") use
  36.         "fmspr" for doing conversions.
  37.  
  38.         Note that temporary work space is declared within
  39.         each of the high-level functions as a one-dimensional
  40.         character array. The length limit on this array is
  41.         presently set to 132 by the #define MAXLINE statement;
  42.         if you intend to create longer lines through printf
  43.         or fprintf calls, be SURE to raise this
  44.         limit by changing the #define statement.
  45.  
  46.   */
  47.  
  48.   #define MAXLINE 132
  49.   #define ERROR -1
  50.   #define OK 0
  51.  
  52.   /*
  53.         printf
  54.  
  55.         usage:
  56.                 printf(format, arg1, arg2, ...);
  57.         
  58.         Note that since the "fmspr" function is used to
  59.         form the output string, and then "puts" is used to
  60.         actually print it out, care must be taken to
  61.         avoid generating null (zero) bytes in the output,
  62.         since such a byte will terminate printing of the
  63.         string by puts. Thus, a statement such as:
  64.  
  65.                 printf("%c foo",'\0',2);
  66.  
  67.         would print nothing at all.
  68.  
  69.   */
  70.  
  71.   printf(count)
  72.   int count;
  73.   {
  74.         char line[MAXLINE], *format;
  75.         format = &count + count +count; /* point to 1st argument */
  76.         fmspr(line,format);             /* use "fmspr" to form the output */
  77.         puts(line);                     /* and print out the line        */
  78.   }
  79.  
  80.  
  81.   /*
  82.         fprintf:
  83.         Like printf, except that the first argument is
  84.         a pointer to a buffered I/O buffer, and the text
  85.         is written to the file described by the buffer:
  86.         ERROR (-1) returned on error.
  87.  
  88.         usage:
  89.                 fprintf(iobuf, format, arg1, arg2, ..., argn, count);
  90.                          where count = n + 2
  91.   */
  92.  
  93.   fprintf(count)
  94.   int count;
  95.   {
  96.         int iobuf, *format;
  97.         char text[MAXLINE];
  98.         format = &count + count + count; /* point to 1st argument */
  99.         iobuf = *format--;
  100.         fmspr(text,format);
  101.         return fputs(text,iobuf);
  102.   }
  103.  
  104.  
  105.   /*
  106.         sprintf:
  107.         Like fprintf, except a string pointer is specified
  108.         instead of a buffer pointer. The text is written
  109.         directly into memory where the string pointer points.
  110.  
  111.         Usage:
  112.                 sprintf(string,format,arg1, arg2, ..., argN, count);
  113.   */
  114.  
  115.   sprintf(count)
  116.   int count;
  117.   {
  118.         char *buffer;
  119.         int *format;
  120.         format = &count + count + count;
  121.         buffer = *format--;
  122.         fmspr(buffer,format);  /* call fmspr to do all the work */
  123.   }
  124.  
  125.  
  126.   /*
  127.         General formatted output conversion routine, used by
  128.         fprintf and sprintf..."line" is where the output is
  129.         written, and "fmt" is a pointer to an argument list
  130.         which must consist of a format string pointer and
  131.         subsequent list of (optional) values.
  132.   */
  133.  
  134.  
  135.   fmspr(line,fmt)
  136.   char *line;
  137.   int *fmt;
  138.   {
  139.         char c, base, *sptr, *format, uc, tf;
  140.         char wbuf[MAXLINE], *wptr, pf, ljflag, zfflag;
  141.         int width, precision,  *args;
  142.  
  143.         format = *fmt--;    /* fmt first points to the format string    */
  144.         args = fmt;         /* now fmt points to the first arg value    */
  145.  
  146.         while (c = *format++) {
  147.           if (c == '%') {
  148.             wptr = wbuf;
  149.             precision = 6;
  150.             base = tf = ljflag = pf = zfflag = 0;
  151.  
  152.             if (*format == '-') {
  153.                     format++;
  154.                     ljflag++;
  155.              }
  156.  
  157.  
  158.             if (*format == '0') zfflag++;       /* zero-fill feature test */
  159.  
  160.             if (isdigit(*format))
  161.                 width = gv2(&format);
  162.             else
  163.                 width = 0;
  164.  
  165.             if ((c = *format++) == '.') {
  166.                     precision = gv2(&format);
  167.                     pf++;
  168.                     c = *format++;
  169.              }
  170.  
  171.             uc = toupper(c);
  172.             while(1) {
  173.                 if (uc == 'D') {
  174.                     if (*args < 0) {
  175.                         *wptr++ = '-';
  176.                         *args = -*args;
  177.                         width--;
  178.                     }
  179.                     base = 10;
  180.                 }
  181.                 else if (uc == 'U')
  182.                     base = 10;
  183.                 else if (uc == 'X')
  184.                     base = 16;
  185.                 else if (uc == 'O')
  186.                     base = 8;
  187.  
  188.                 if (base) {
  189.                     width = width - uspr(&wptr, *args--, base);
  190.                     tf++;
  191.                 }
  192.  
  193.                 if (uc == 'C') {
  194.                     *wptr++ = *args--;
  195.                     width--;  tf++;
  196.                 }
  197.                 else if (uc == 'S') {
  198.                     if (pf == 0) precision =200;
  199.                     sptr = *args--;
  200.                     while (*sptr && precision) {
  201.                         *wptr++ = *sptr++;
  202.                         precision--;
  203.                         width--;
  204.                     }
  205.                     tf++;
  206.                 }
  207.  
  208.                 if (tf) {
  209.                     *wptr = 0;
  210.                     wptr = wbuf;
  211.                     if (ljflag == 0) {
  212.                         while (width-- > 0) {
  213.                             if (zfflag)
  214.                                 *line++ = '0';
  215.                             else
  216.                                 *line++ = ' ';
  217.                         }
  218.                     }
  219.                     while (*line = *wptr++)
  220.                         line++;
  221.                     if (ljflag)
  222.                         while (width-- > 0)
  223.                             *line++ = ' ';
  224.                 }
  225.                 else
  226.                     *line++ = c;
  227.  
  228.                 break;
  229.              }
  230.           }
  231.           else *line++ = c;
  232.         }
  233.         *line = 0;
  234.   }
  235.  
  236.   /*
  237.         Internal routine used by "fmspr" to perform ascii-
  238.         to-decimal conversion and update an associated pointer:
  239.   */
  240.  
  241.   gv2(sptr)
  242.   int *sptr;
  243.   {
  244.         int n;
  245.         char *np;
  246.         np = *sptr;
  247.         n = 0;
  248.         while (isdigit(*np)) n = 10 * n + *np++ - '0';
  249.         *sptr = np;
  250.         return n;
  251.   }
  252.  
  253.  
  254.   /*
  255.         Internal function which converts n into an ASCII
  256.         base `base' representation and places the text
  257.         at the location pointed to by the pointer pointed
  258.         to by `string'. Yes, you read that correctly.
  259.   */
  260.  
  261.   uspr(string, n, base)
  262.   int *string, n, base;
  263.   {
  264.       char length, *sp;
  265.       int temp[6], i, old;
  266.       i = 0;
  267.       if (n < 0 )   {
  268.           temp[i++] = n;      /* if neg, fake "unsigned" */
  269.           n = (n >> 1) / (base >> 1);
  270.           }
  271.       while (n > base)   {
  272.           temp[i++] = n;
  273.           n = n / base;
  274.           }
  275.       temp[i++] = n;
  276.       length = i;             /* save return parameter */
  277.       sp = *string;
  278.       old = 0;
  279.       while (i--)   {
  280.           n = temp[i] - old * base;
  281.           if(n < 10)
  282.               *sp++ = n + '0';
  283.           else
  284.               *sp++ = n + 55;
  285.           old = temp[i];
  286.           }
  287.       *string = sp;
  288.       return length;
  289.   }
  290.  
  291.   /*
  292.         fputs:
  293.         This function writes a string out to a buffered
  294.         output file.
  295.         ERROR (-1) returned on error.
  296.   */
  297.  
  298.   fputs(s,iobuf)
  299.   char *s;
  300.   int iobuf;
  301.   {
  302.         char c;
  303.         while (c = *s++) {
  304.                 if (putc(c,iobuf) == ERROR) return ERROR;
  305.         }
  306.         return OK;
  307.   }
  308.                    while (*line = *wptr++)
  309.                         line++;
  310.