home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / online / source / c / compilers / C_Interp.sit.hqx / C_Interp / FormatStr.c < prev    next >
Text File  |  1992-05-01  |  6KB  |  234 lines

  1. /*
  2.     Terminal 2.2
  3.     "FormatStr.c"
  4.  
  5.     In the spirit of printf() but using pascal strings.
  6.  
  7.     Format specifiers begin with the character % and include zero or more
  8.     of the following conversion specification elements:
  9.  
  10.     % [justify flag] [0 pad character] [field size] [type of variable]
  11.  
  12.     Justify flag (optional):
  13.         -    Left justify output in field, pad on right (default is to
  14.             right justify).
  15.     Pad character (optional):
  16.         0    Use zero rather than space (default) for the pad character.
  17.     Type of variable:
  18.         i    int
  19.         l    long
  20.         c    single character
  21.         s    pascal string
  22.         a    character array
  23.         %    print a %, no argument used
  24.         
  25. */
  26.  
  27. #include "Compatibility.h"
  28.  
  29. Byte *FormatStr(Byte *string, Byte *template);
  30. Byte *SFormatStr(Byte *string, Byte *template, long *param);
  31.  
  32.  
  33. static void MoveBytes(
  34.     register Byte *source,
  35.     register Byte **destination,
  36.     register Byte *limit,
  37.     register short count)
  38. {
  39.     while (*destination <= limit && count--)
  40.         *(*destination)++ = *source++;
  41. }
  42.  
  43. static void MoveBlanks(
  44.     register Byte **destination,
  45.     register Byte *limit,
  46.     register short count,
  47.     register Byte pad)
  48. {
  49.     if (count <= 0)
  50.         return;
  51.     while (*destination <= limit && count--)
  52.         *(*destination)++ = pad;
  53. }
  54.  
  55. Byte *FormatStr(
  56.     Byte *result,            /* Result string */
  57.     Byte *template)            /* Template string */
  58. {
  59.     va_list ap;
  60.     Byte *p = result + 1;
  61.     Byte *max = template + *template;
  62.     Byte num[30];
  63.     short fieldWidth;
  64.     Byte pad;
  65.     Boolean leftJustify;
  66.  
  67.     va_start(ap, template);
  68.  
  69.     while (template < max) {
  70.         template++;
  71.         if (*template == '%') {
  72.             template++;
  73.             fieldWidth = 0;
  74.             leftJustify = FALSE;
  75.             pad = ' ';
  76.             if (*template == '-') {
  77.                 template++;
  78.                 leftJustify = TRUE;
  79.             }
  80.             if (*template >= '0' && *template <= '9') {
  81.                 if (*template == '0')
  82.                     pad = '0';
  83.                 do
  84.                     fieldWidth = 10*fieldWidth + (*template++ & 0x0F);
  85.                 while (*template >= '0' && *template <= '9');
  86.             }
  87.             switch (*template) {
  88.                 case 'a':            /* Character array */
  89.                     MoveBytes(va_arg(ap, Byte *), &p, result + 255, fieldWidth);
  90.                     break;
  91.                 case 'c':            /* Character */
  92.                     {
  93.                         Byte c;
  94.  
  95.                         if (!leftJustify)
  96.                             MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  97. #ifndef THINK_C
  98.                         /* In MPW C char is passed in 4 bytes on the stack! */
  99.                         c = va_arg(ap, long);
  100. #else
  101.                         /* In THINK C char is passed in 2 bytes on the stack! */
  102.                         c = va_arg(ap, short);
  103. #endif
  104.                         MoveBytes(&c, &p, result + 255, 1);
  105.                         if (leftJustify)
  106.                             MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  107.                         }
  108.                     break;
  109.                 case 's':            /* String */
  110.                     {
  111.                         register Byte *sp;
  112.  
  113.                         sp = va_arg(ap, Byte *);
  114.                         if (!leftJustify)
  115.                             MoveBlanks(&p, result + 255, fieldWidth - strlen((char *) sp),
  116.                                 pad);
  117.                         MoveBytes(sp + 1, &p, result + 255, strlen((char *) sp));
  118.                         if (leftJustify)
  119.                             MoveBlanks(&p, result + 255, fieldWidth - strlen((char *) sp),
  120.                                 pad);
  121.                     }
  122.                     break;
  123.                 case 'i':            /* int */
  124. #ifndef THINK_C
  125.                     /* In MPW C short is passed in 4 bytes on the stack! */
  126. #else
  127.                     sprintf((char *) num,"%d",va_arg(ap, short));
  128.                     goto integer;
  129. #endif
  130.                 case 'l':            /* long */
  131.                     sprintf((char *) num,"%ld",va_arg(ap, long));
  132.                 integer:
  133.                     if (!leftJustify)
  134.                         MoveBlanks(&p, result + 255, fieldWidth - strlen((char *) num),
  135.                             pad);
  136.                     MoveBytes(num + 1, &p, result + 255, strlen((char *) num));
  137.                     if (leftJustify)
  138.                         MoveBlanks(&p, result + 255, fieldWidth - strlen((char *) num),
  139.                             pad);
  140.                     break;
  141.                 default:
  142.                     *p++ = *template;
  143.             }
  144.         } else                        /* Copy character */
  145.             *p++ = *template;
  146.     }
  147.     va_end(pa);
  148.     *result = p - result - 1;
  149.     return result;
  150. }
  151.  
  152. Byte *SFormatStr(                /* Special version for scripts */
  153.     Byte *result,                /* Result string (C string) */
  154.     register Byte *template,    /* Template string (C-string) */
  155.     long params[])                /* Array with parameters (char, long or C-string) */
  156. {
  157.     Byte *p = result;
  158.     register long *s = params;
  159.     Byte num[30];
  160.     short fieldWidth;
  161.     Byte pad;
  162.     Boolean leftJustify;
  163.  
  164.     while (*template) {
  165.         if (*template == '%') {
  166.             template++;
  167.             if (!*template)
  168.                 break;
  169.             fieldWidth = 0;
  170.             leftJustify = FALSE;
  171.             pad = ' ';
  172.             if (*template == '-') {
  173.                 template++;
  174.                 if (!*template)
  175.                     break;
  176.                 leftJustify = TRUE;
  177.             }
  178.             if (*template >= '0' && *template <= '9') {
  179.                 if (*template == '0')
  180.                     pad = '0';
  181.                 do
  182.                     fieldWidth = 10*fieldWidth + (*template++ & 0x0F);
  183.                 while (*template >= '0' && *template <= '9');
  184.                 if (!*template)
  185.                     break;
  186.             }
  187.             switch (*template) {
  188.                 case 'c':            /* Character */
  189.                     if (!leftJustify)
  190.                         MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  191.                     MoveBytes((Byte *)s + 3, &p, result + 255, 1);
  192.                     if (leftJustify)
  193.                         MoveBlanks(&p, result + 255, fieldWidth - 1, pad);
  194.                     s++;
  195.                     break;
  196.                 case 's':            /* C-string */
  197.                     {
  198.                         register Byte *sp;
  199.  
  200.                         sp = (Byte *)*s;
  201.                         if (!leftJustify)
  202.                             MoveBlanks(&p, result + 255, fieldWidth - strlen((char *)sp),
  203.                                 pad);
  204.                         MoveBytes(sp, &p, result + 255, strlen((char *)sp));
  205.                         if (leftJustify)
  206.                             MoveBlanks(&p, result + 255, fieldWidth - strlen((char *)sp),
  207.                                 pad);
  208.                     }
  209.                     s++;
  210.                     break;
  211.                 case 'd':
  212.                 case 'i':            /* int */
  213.                     sprintf((char *) num, "%ld", *s);
  214.                     s++;
  215.                     if (!leftJustify)
  216.                         MoveBlanks(&p, result + 255, fieldWidth - strlen((char *) num),
  217.                             pad);
  218.                     MoveBytes(num, &p, result + 255, strlen((char *) num));
  219.                     if (leftJustify)
  220.                         MoveBlanks(&p, result + 255, fieldWidth - strlen((char *) num),
  221.                             pad);
  222.                     break;
  223.                 default:
  224.                     *p++ = *template;
  225.             }
  226.         } else                        /* Copy character */
  227.             *p++ = *template;
  228.         template++;
  229.     }
  230. done:
  231.     *p='\0';
  232.     return result;
  233. }
  234.