home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / mytinfo / part02 / sprintf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-26  |  8.4 KB  |  432 lines

  1. /*
  2.  * sprintf.c
  3.  *
  4.  * By Ross Ridge
  5.  * Public Domain
  6.  * 92/02/01 07:30:16
  7.  *
  8.  */
  9.  
  10. #include "defs.h"
  11.  
  12. #include <ctype.h>
  13.  
  14. #ifdef USE_SCCS_IDS
  15. static const char SCCSid[] = "@(#) mytinfo sprintf.c 3.2 92/02/01 public domain, By Ross Ridge";
  16. #endif
  17.  
  18. #ifdef TEST
  19. #define USE_FAKE_STDIO
  20. #undef PRINTF
  21. #define sprintf _sprintf
  22. #endif
  23.  
  24. #ifdef USE_FAKE_STDIO
  25.  
  26. #ifdef PRINTF
  27. #undef putchar
  28. #define PUTCHAR(c) (cnt++, putchar(c))
  29. #else
  30. #define PUTCHAR(c) (*s++ = c)
  31. #endif
  32.  
  33. #ifdef PRINTF
  34. #ifdef USE_STDARG
  35. #ifdef USE_PROTOTYPES
  36. int
  37. printf(char *fmt, ...) {
  38. #else
  39. int printf(fmt)
  40. char *fmt; {
  41. #endif
  42. #else
  43. int printf(va_alist)
  44. va_dcl {
  45.     register char *fmt;
  46. #endif
  47.     register int cnt;
  48. #else /* PRINTF */
  49. #ifdef lint
  50. /* VARARGS1 */
  51. int
  52. sprintf(str, fmt)
  53. char *str;
  54. char *fmt; {
  55. #else /* lint */
  56. #ifdef USE_STDARG
  57. #ifdef USE_PROTOTYPES
  58. int sprintf(char *str, char *fmt, ...) {
  59. #else /* USE_PROTOTYPES */
  60. int sprintf(str, fmt)
  61. char *str;
  62. char *fmt; {
  63. #endif /* else USE_PROTOTYPES */
  64. #else /* USE_STDARG */
  65. int sprintf(va_alist)
  66. va_dcl {
  67.     register char *fmt;
  68.     char *str;
  69. #endif /* else USE_STDARG */
  70. #endif /* else lint */
  71.     register char *s;
  72. #endif /* else PRINTF */
  73.     int minus;
  74.     int sharp;
  75.     int space;
  76.     int plus;
  77.     int zero;
  78.     int ell;
  79.     int prec;
  80.     int width;
  81.     int sign;
  82.     int pad;
  83.     char buf[100];
  84.     register long n;
  85.     register unsigned long u;
  86.     register char *d;
  87.     int l;
  88.     int k;
  89.     va_list args;
  90.  
  91. #ifdef lint
  92.     args = (va_list) 0;
  93. #else
  94. #ifdef USE_STDARG
  95.     va_start(args, fmt);
  96. #else
  97.     va_start(args);
  98. #ifndef PRINTF
  99.     str = va_arg(args, char *);
  100. #endif
  101.     fmt = va_arg(args, char *);
  102. #endif
  103. #endif /* else lint */
  104.     
  105.  
  106. #ifdef PRINTF
  107.     cnt = 0;
  108. #else
  109.     s = str;
  110. #endif
  111.  
  112.     while(*fmt != '\0') {
  113.         if (*fmt == '%') {
  114.             fmt++;
  115.             if (*fmt == '%' || *fmt == '\0') {
  116.                 PUTCHAR('%');
  117.                 fmt++;
  118.                 continue;
  119.             }
  120.             minus = plus = sharp = space = zero = ell = 0;
  121.             width = 0;
  122.             prec = -1;
  123.             do {
  124.                 switch(*fmt) {
  125.                 case '-': minus = 1; continue;
  126.                 case '+': plus = 1; continue;
  127.                 case ' ': space = 1; continue;
  128.                 case '#': sharp = 1; continue;
  129.                 }
  130.                 break;
  131.             } while (*++fmt != '\0');
  132.             if (*fmt == '0') {
  133.                 zero = 1;
  134.                 fmt++;
  135.             }
  136.             if (*fmt == '*') {
  137.                 width = va_arg(args, int);
  138.                 fmt++;
  139.             } else if (isdigit(*fmt)) {
  140.                 width = *fmt++ - '0';
  141.                 while(isdigit(*fmt))
  142.                     width = 10 * width + *fmt++ - '0';
  143.             }
  144.             if (*fmt == '.') {
  145.                 prec = 0;
  146.                 fmt++;
  147.                 if (*fmt == '*') {
  148.                     prec = va_arg(args, int);
  149.                     fmt++;
  150.                 } else {
  151.                     while(isdigit(*fmt))
  152.                         prec = 10 * prec + *fmt++ - '0';
  153.                 }
  154.             }
  155.             if (*fmt == 'l') {
  156.                 ell = 1;
  157.                 fmt++;
  158.             }
  159.             sign = 0;
  160.             l = 0;
  161.             d = buf;
  162.             switch(*fmt) {
  163.             case 'd':
  164.             case 'i':
  165.                 if (ell)
  166.                     n = va_arg(args, long);
  167.                 else
  168.                     n = va_arg(args, int);
  169.                 if (n < 0) {
  170.                     sign = -1;
  171.                     n = -n;
  172.                 } else {
  173.                     sign = 1;
  174.                 }
  175.                 while(n != 0) {
  176.                     *d++ = (n % 10) + '0';
  177.                     n /= 10;
  178.                 }
  179.                 break;
  180.             case 'o':
  181.                 if (ell)
  182.                     u = va_arg(args, unsigned long);
  183.                 else
  184.                     u = va_arg(args, unsigned );
  185.                 while(u != 0) {
  186.                     *d++ = (u & 7) + '0';
  187.                     u >>= 3;
  188.                 }
  189.                 if (sharp)
  190.                     l = 1;
  191.                 break;
  192.             case 'u':
  193.                 if (ell)
  194.                     u = va_arg(args, unsigned long);
  195.                 else
  196.                     u = va_arg(args, unsigned );
  197.                 while(u != 0) {
  198.                     *d++ = (u % 10) + '0';
  199.                     u /= 10;
  200.                 }
  201.                 break;
  202.             case 'x':
  203.                 if (ell)
  204.                     u = va_arg(args, unsigned long);
  205.                 else
  206.                     u = va_arg(args, unsigned );
  207.                 while(u != 0) {
  208.                     *d++ = "0123456789abcdef"[u & 15];
  209.                     u >>= 4;
  210.                 }
  211.                 if (sharp)
  212.                     l += 2;
  213.                 break;
  214.             case 'X':
  215.                 if (ell)
  216.                     u = va_arg(args, unsigned long);
  217.                 else
  218.                     u = va_arg(args, unsigned );
  219.                 while(u != 0) {
  220.                     /* just to be silly... */
  221.                     *d++ = (u & 15)["0123456789ABCDEF"];
  222.                     u >>= 4;
  223.                 }
  224.                 if (sharp)
  225.                     l += 2;
  226.                 break;
  227.             case 's':
  228.                 d = va_arg(args, char *);
  229.                 l = strlen(d);
  230.                 break;
  231.             case 'c':
  232.                 buf[0] = va_arg(args, int);
  233.                 l = 1;
  234.                 break;
  235.             default:
  236.                 PUTCHAR(*fmt++);
  237.                 continue;
  238.             }
  239.             if (*fmt == 's' || *fmt == 'c') {
  240.                 if (prec != -1 && l > prec) 
  241.                     l = prec;
  242.                 pad = width - l;
  243.                 if (zero) 
  244.                     while(pad-- > 0)
  245.                         PUTCHAR('0');
  246.                 else if (!minus)
  247.                     while(pad-- > 0)
  248.                         PUTCHAR(' ');
  249.                 while(l-- > 0)
  250.                     PUTCHAR(*d++);
  251.                 if (minus)
  252.                     while(pad-- > 0)
  253.                         PUTCHAR(' ');
  254.             } else {
  255.                 if (prec == -1)
  256.                     prec = 1;
  257.                 k = d - buf;
  258.                 if (k < prec)
  259.                     l += prec;
  260.                 else
  261.                     l += k;
  262.                 if (sign == -1)
  263.                     l++;
  264.                 else if (sign == 1 && (space || plus))
  265.                     l++;
  266.                 pad = width - l;
  267.                 if (zero)
  268.                     while(pad-- > 0)
  269.                         PUTCHAR('0');
  270.                 else if (!minus)
  271.                     while(pad-- > 0)
  272.                         PUTCHAR(' ');
  273.                 if (*fmt == 'x' && sharp) {
  274.                     PUTCHAR('0');
  275.                     PUTCHAR('x');
  276.                 } else if (*fmt == 'X' && sharp) {
  277.                     PUTCHAR('0');
  278.                     PUTCHAR('X');
  279.                 } else if (*fmt == 'o' && sharp) {
  280.                     PUTCHAR('0');
  281.                 } else if (sign == -1) {
  282.                     PUTCHAR('-');
  283.                 } else if (sign == 1 && space) {
  284.                     PUTCHAR(' ');
  285.                 } else if (sign == 1 && plus) {
  286.                     PUTCHAR('+');
  287.                 }
  288.                 while(k++ < prec)
  289.                     PUTCHAR('0');
  290.                 while(d > buf)
  291.                     PUTCHAR(*--d);
  292.                 if (!zero && minus)
  293.                     while(pad-- > 0)
  294.                         PUTCHAR(' ');
  295.             }
  296.             fmt++;
  297.         } else {
  298.             PUTCHAR(*fmt++);
  299.         }
  300.     }
  301. #ifdef PRINTF
  302.     return cnt;
  303. #else
  304.     *s = '\0';
  305.     return s - str;
  306. #endif
  307. }
  308.  
  309. #endif /* USE_FAKE_STDIO */
  310.  
  311. #ifdef TEST
  312. #ifndef PRINTF
  313. #undef sprintf
  314. main(argc, argv)
  315. int argc;
  316. char *argv; {
  317.     char buf[256];
  318.  
  319.     _sprintf(buf, "%d", 2);
  320.     printf("'%s'\n", buf);
  321.     sprintf(buf, "%d", 2);
  322.     printf("'%s'\n", buf);
  323.     _sprintf(buf, "%05d", 2);
  324.     printf("'%s'\n", buf);
  325.     sprintf(buf, "%05d", 2);
  326.     printf("'%s'\n", buf);
  327.     _sprintf(buf, "% 5d", 2);
  328.     printf("'%s'\n", buf);
  329.     sprintf(buf, "% 5d", 2);
  330.     printf("'%s'\n", buf);
  331.     _sprintf(buf, "%-5d", 2);
  332.     printf("'%s'\n", buf);
  333.     sprintf(buf, "%-5d", 2);
  334.     printf("'%s'\n", buf);
  335.     _sprintf(buf, "%5.3d", 2);
  336.     printf("'%s'\n", buf);
  337.     sprintf(buf, "%5.3d", 2);
  338.     printf("'%s'\n", buf);
  339.     _sprintf(buf, "%+d", 2);
  340.     printf("'%s'\n", buf);
  341.     sprintf(buf, "%+d", 2);
  342.     printf("'%s'\n", buf);
  343.     _sprintf(buf, "%#-1.2d", 2);
  344.     printf("'%s'\n", buf);
  345.     sprintf(buf, "%#-1.2d", 2);
  346.     printf("'%s'\n", buf);
  347.     _sprintf(buf, "% 5d", -2);
  348.     printf("'%s'\n", buf);
  349.     sprintf(buf, "% 5d", -2);
  350.     printf("'%s'\n", buf);
  351.     _sprintf(buf, "%-5d", -2);
  352.     printf("'%s'\n", buf);
  353.     sprintf(buf, "%-5d", -2);
  354.     printf("'%s'\n", buf);
  355.     _sprintf(buf, "%5.3d", -2);
  356.     printf("'%s'\n", buf);
  357.     sprintf(buf, "%5.3d", -2);
  358.     printf("'%s'\n", buf);
  359.     _sprintf(buf, "%%:%o:%x:%X:%ld:%u:%i", 10, 22, 333, -456L, 50000, 6);
  360.     printf("'%s'\n", buf);
  361.     sprintf(buf, "%%:%o:%x:%X:%ld:%u:%i", 10, 22, 333, -456L, 50000, 6);
  362.     printf("'%s'\n", buf);
  363.     _sprintf(buf, "%06o:%#6x:%#012.4X:%-5ld:%*u:%*.*i",
  364.         10, 22, 333, -456L, 8, 50000, 4, 2, 6);
  365.     printf("'%s'\n", buf);
  366.     sprintf(buf, "%06o:%#6x:%#012.4X:%-5ld:%*u:%*.*i",
  367.         10, 22, 333, -456L, 8, 50000, 4, 2, 6);
  368.     printf("'%s'\n", buf);
  369.     _sprintf(buf, "%s", "abcdefghi");
  370.     printf("'%s'\n", buf);
  371.     sprintf(buf, "%s", "abcdefghi");
  372.     printf("'%s'\n", buf);
  373.     _sprintf(buf, "%.4s", "abcdefghi");
  374.     printf("'%s'\n", buf);
  375.     sprintf(buf, "%.4s", "abcdefghi");
  376.     printf("'%s'\n", buf);
  377.     _sprintf(buf, "%4.4s", "abcdefghi");
  378.     printf("'%s'\n", buf);
  379.     sprintf(buf, "%4.4s", "abcdefghi");
  380.     printf("'%s'\n", buf);
  381.     _sprintf(buf, "%20s", "abcdefghi");
  382.     printf("'%s'\n", buf);
  383.     sprintf(buf, "%20s", "abcdefghi");
  384.     printf("'%s'\n", buf);
  385.     _sprintf(buf, "%-20s", "abcdefghi");
  386.     printf("'%s'\n", buf);
  387.     sprintf(buf, "%-20s", "abcdefghi");
  388.     printf("'%s'\n", buf);
  389.     _sprintf(buf, "%-20.20s", "abcdefghi");
  390.     printf("'%s'\n", buf);
  391.     sprintf(buf, "%-20.20s", "abcdefghi");
  392.     printf("'%s'\n", buf);
  393.     _sprintf(buf, "%#-0.20s", "abcdefghi");
  394.     printf("'%s'\n", buf);
  395.     sprintf(buf, "%#-0.20s", "abcdefghi");
  396.     printf("'%s'\n", buf);
  397.     _sprintf(buf, "%5s", "abcdefghi");
  398.     printf("'%s'\n", buf);
  399.     sprintf(buf, "%5s", "abcdefghi");
  400.     printf("'%s'\n", buf);
  401.     _sprintf(buf, "%015s", "abcdefghi");
  402.     printf("'%s'\n", buf);
  403.     sprintf(buf, "%015s", "abcdefghi");
  404.     printf("'%s'\n", buf);
  405.     _sprintf(buf, "%c", 'C');
  406.     printf("'%s'\n", buf);
  407.     sprintf(buf, "%c", 'C');
  408.     printf("'%s'\n", buf);
  409.     _sprintf(buf, "%5c", 'C');
  410.     printf("'%s'\n", buf);
  411.     sprintf(buf, "%5c", 'C');
  412.     printf("'%s'\n", buf);
  413.     _sprintf(buf, "%-5c", 'C');
  414.     printf("'%s'\n", buf);
  415.     sprintf(buf, "%-5c", 'C');
  416.     printf("'%s'\n", buf);
  417.     _sprintf(buf, "%d", 0);
  418.     printf("'%s'\n", buf);
  419.     sprintf(buf, "%d", 0);
  420.     printf("'%s'\n", buf);
  421.     _sprintf(buf, "%.d", 0);
  422.     printf("'%s'\n", buf);
  423.     sprintf(buf, "%.d", 0);
  424.     printf("'%s'\n", buf);
  425.     _sprintf(buf, "%5.0d", 0);
  426.     printf("'%s'\n", buf);
  427.     sprintf(buf, "%5.0d", 0);
  428.     printf("'%s'\n", buf);
  429. }
  430. #endif /* !PRINTF */
  431. #endif /* TEST */
  432.