Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * vsprintf - print formatted output without ellipsis on an array
  3.  */
  4. /* $Header$ */
  5.  
  6. //#include  "stdio.h"
  7. //#include  <stdarg.h>
  8.  
  9. typedef unsigned size_t;
  10.  
  11. typedef struct
  12. {
  13.   char *_ptr;
  14.   unsigned _count;
  15. }__str;
  16.  
  17.  
  18. #define va_start(v,l) __builtin_va_start(v,l)
  19. #define va_end(v)       __builtin_va_end(v)
  20. #define va_arg(v,l)     __builtin_va_arg(v,l)
  21. #if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
  22. #define va_copy(d,s)    __builtin_va_copy(d,s)
  23. #endif
  24. #define __va_copy(d,s)  __builtin_va_copy(d,s)
  25.  
  26. typedef __builtin_va_list __gnuc_va_list;
  27. typedef __gnuc_va_list va_list;
  28.  
  29. #define arg(x) va_arg (ap, u32)
  30.  
  31. #define io_testflag(p,x)        ((p)->_flags & (x))
  32.  
  33. char *_i_compute(unsigned long val, int base, char *s, int nrdigits);
  34. char *_f_print(va_list *ap, int flags, char *s, char c, int precision);
  35. void __cleanup(void);
  36.  
  37.  
  38. void *calloc( size_t num, size_t size );
  39. int memcmp(const void *s1, const void *s2, size_t n);
  40. void * memcpy(void * _dest, const void *_src, size_t _n);
  41. char * strcpy(char *to, const char *from);
  42. char * strcat(char *s, const char *append);
  43. int strcmp(const char *s1, const char *s2);
  44. size_t strlen(const char *str);
  45. char * strdup(const char *_s);
  46. char * strchr(const char *s, int c);
  47.  
  48.  
  49. #define FL_LJUST        0x0001          /* left-justify field */
  50. #define FL_SIGN         0x0002          /* sign in signed conversions */
  51. #define FL_SPACE        0x0004          /* space in signed conversions */
  52. #define FL_ALT          0x0008          /* alternate form */
  53. #define FL_ZEROFILL     0x0010          /* fill with zero's */
  54. #define FL_SHORT        0x0020          /* optional h */
  55. #define FL_LONG         0x0040          /* optional l */
  56. #define FL_LONGDOUBLE   0x0080          /* optional L */
  57. #define FL_WIDTHSPEC    0x0100          /* field width is specified */
  58. #define FL_PRECSPEC     0x0200          /* precision is specified */
  59. #define FL_SIGNEDCONV   0x0400          /* may contain a sign */
  60. #define FL_NOASSIGN     0x0800          /* do not assign (in scanf) */
  61. #define FL_NOMORE 0x1000    /* all flags collected */
  62.  
  63. #define _IOFBF          0x000
  64. #define _IOREAD         0x001
  65. #define _IOWRITE        0x002
  66. #define _IONBF          0x004
  67. #define _IOMYBUF        0x008
  68. #define _IOEOF          0x010
  69. #define _IOERR          0x020
  70. #define _IOLBF          0x040
  71. #define _IOREADING      0x080
  72. #define _IOWRITING      0x100
  73. #define _IOAPPEND       0x200
  74. #define _IOFIFO         0x400
  75.  
  76. #define SGL_MAX      254  /*  standard definition */
  77. #define SGL_MIN              1  /*      standard definition     */
  78. #define DBL_MAX           2046  /*      standard definition     */
  79. #define DBL_MIN              1  /*      standard definition     */
  80. #define EXT_MAX          16383  /*      standard minimum        */
  81. #define EXT_MIN   -16382  /*  standard minimum  */
  82. #include        <limits.h>
  83.  
  84. static char *cvt();
  85. #define NDIGITS 128
  86.  
  87. unsigned char __dj_ctype_toupper[] = {
  88.   0x00,
  89.   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  90.   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  91.   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  92.   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  93.   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  94.   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  95.   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  96.   0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  97.   0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  98.   0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  99.   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  100.   0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
  101.   0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  102.   0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
  103.   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
  104.   0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
  105.   0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
  106.   0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
  107.   0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
  108.   0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
  109.   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  110.   0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  111.   0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  112.   0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  113.   0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
  114.   0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  115.   0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
  116.   0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
  117.   0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
  118.   0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
  119.   0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
  120.   0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
  121. };
  122. #define toupper(c) (__dj_ctype_toupper[(int)(c)+1])
  123.  
  124. int (toupper)(int c)
  125. {
  126.   return toupper(c);
  127. }
  128.  
  129. char *
  130. _ecvt(value, ndigit, decpt, sign)
  131.         double value;
  132.         int ndigit, *decpt, *sign;
  133. {
  134.         return cvt(value, ndigit, decpt, sign, 1);
  135. }
  136.  
  137. char *
  138. _fcvt(value, ndigit, decpt, sign)
  139.         double value;
  140.         int ndigit, *decpt, *sign;
  141. {
  142.         return cvt(value, ndigit, decpt, sign, 0);
  143. }
  144.  
  145. static struct powers_of_10 {
  146.         double pval;
  147.         double rpval;
  148.         int exp;
  149. } p10[] = {
  150.         1.0e32, 1.0e-32, 32,
  151.         1.0e16, 1.0e-16, 16,
  152.         1.0e8, 1.0e-8, 8,
  153.         1.0e4, 1.0e-4, 4,
  154.         1.0e2, 1.0e-2, 2,
  155.         1.0e1, 1.0e-1, 1,
  156.         1.0e0, 1.0e0, 0
  157. };
  158.  
  159. static char *
  160. cvt(value, ndigit, decpt, sign, ecvtflag)
  161.         double value;
  162.         int ndigit, *decpt, *sign;
  163. {
  164.         static char buf[NDIGITS+1];
  165.         register char *p = buf;
  166.         register char *pe;
  167.  
  168.         if (ndigit < 0) ndigit = 0;
  169.         if (ndigit > NDIGITS) ndigit = NDIGITS;
  170.         pe = &buf[ndigit];
  171.         buf[0] = '\0';
  172.  
  173.         *sign = 0;
  174.         if (value < 0) {
  175.                 *sign = 1;
  176.                 value = -value;
  177.         }
  178.  
  179.         *decpt = 0;
  180.         if (value >= DBL_MAX) {
  181.                 value = DBL_MAX;
  182.         }
  183.         if (value != 0.0) {
  184.                 register struct powers_of_10 *pp = &p10[0];
  185.  
  186.                 if (value >= 10.0) do {
  187.                         while (value >= pp->pval) {
  188.                                 value *= pp->rpval;
  189.                                 *decpt += pp->exp;
  190.                         }
  191.                 } while ((++pp)->exp > 0);
  192.  
  193.                 pp = &p10[0];
  194.                 if (value < 1.0) do {
  195.                         while (value * pp->pval < 10.0) {
  196.                                 value *= pp->pval;
  197.                                 *decpt -= pp->exp;
  198.                         }
  199.                 } while ((++pp)->exp > 0);
  200.  
  201.                 (*decpt)++;     /* because now value in [1.0, 10.0) */
  202.         }
  203.         if (! ecvtflag) {
  204.                 /* for fcvt() we need ndigit digits behind the dot */
  205.                 pe += *decpt;
  206.                 if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
  207.         }
  208.         while (p <= pe) {
  209.                 *p++ = (int)value + '0';
  210.                 value = 10.0 * (value - (int)value);
  211.         }
  212.         if (pe >= buf) {
  213.                 p = pe;
  214.                 *p += 5;        /* round of at the end */
  215.                 while (*p > '9') {
  216.                         *p = '0';
  217.                         if (p > buf) ++*--p;
  218.                         else {
  219.                                 *p = '1';
  220.                                 ++*decpt;
  221.                                 if (! ecvtflag) {
  222.                                         /* maybe add another digit at the end,
  223.                                            because the point was shifted right
  224.                                         */
  225.                                         if (pe > buf) *pe = '0';
  226.                                         pe++;
  227.                                 }
  228.                         }
  229.                 }
  230.                 *pe = '\0';
  231.         }
  232.         return buf;
  233. }
  234.  
  235.  
  236. int _fp_hook = 1;
  237.  
  238. static char *
  239. _pfloat(double r, register char *s, int n, int flags)
  240. {
  241.         register char *s1;
  242.         int sign, dp;
  243.         register int i;
  244.  
  245.         s1 = _fcvt(r, n, &dp, &sign);
  246.         if (sign)
  247.                 *s++ = '-';
  248.         else if (flags & FL_SIGN)
  249.                 *s++ = '+';
  250.         else if (flags & FL_SPACE)
  251.                 *s++ = ' ';
  252.  
  253.         if (dp<=0)
  254.                 *s++ = '0';
  255.         for (i=dp; i>0; i--)
  256.                 if (*s1) *s++ = *s1++;
  257.                 else *s++ = '0';
  258.         if (((i=n) > 0) || (flags & FL_ALT))
  259.                 *s++ = '.';
  260.         while (++dp <= 0) {
  261.                 if (--i<0)
  262.                         break;
  263.                 *s++ = '0';
  264.         }
  265.         while (--i >= 0)
  266.                 if (*s1) *s++ = *s1++;
  267.                 else *s++ = '0';
  268.         return s;
  269. }
  270.  
  271. static char *
  272. _pscien(double r, register char *s, int n, int flags)
  273. {
  274.         int sign, dp;
  275.         register char *s1;
  276.  
  277.         s1 = _ecvt(r, n + 1, &dp, &sign);
  278.         if (sign)
  279.                 *s++ = '-';
  280.         else if (flags & FL_SIGN)
  281.                 *s++ = '+';
  282.         else if (flags & FL_SPACE)
  283.                 *s++ = ' ';
  284.  
  285.         *s++ = *s1++;
  286.         if ((n > 0) || (flags & FL_ALT))
  287.                 *s++ = '.';
  288.         while (--n >= 0)
  289.                 if (*s1) *s++ = *s1++;
  290.                 else *s++ = '0';
  291.         *s++ = 'e';
  292.         if ( r != 0 ) --dp ;
  293.         if ( dp<0 ) {
  294.                 *s++ = '-' ; dp= -dp ;
  295.         } else {
  296.                 *s++ = '+' ;
  297.         }
  298.         if (dp >= 100) {
  299.                 *s++ = '0' + (dp / 100);
  300.                 dp %= 100;
  301.         }
  302.         *s++ = '0' + (dp/10);
  303.         *s++ = '0' + (dp%10);
  304.         return s;
  305. }
  306.  
  307. #define NDIGINEXP(exp)          (((exp) >= 100 || (exp) <= -100) ? 3 : 2)
  308. #define LOW_EXP                 -4
  309. #define USE_EXP(exp, ndigits)   (((exp) < LOW_EXP + 1) || (exp >= ndigits + 1))
  310.  
  311. static char *
  312. _gcvt(double value, int ndigit, char *s, int flags)
  313. {
  314.         int sign, dp;
  315.         register char *s1, *s2;
  316.         register int i;
  317.         register int nndigit = ndigit;
  318.  
  319.         s1 = _ecvt(value, ndigit, &dp, &sign);
  320.         s2 = s;
  321.         if (sign) *s2++ = '-';
  322.         else if (flags & FL_SIGN)
  323.                 *s2++ = '+';
  324.         else if (flags & FL_SPACE)
  325.                 *s2++ = ' ';
  326.  
  327.         if (!(flags & FL_ALT))
  328.                 for (i = nndigit - 1; i > 0 && s1[i] == '0'; i--)
  329.                         nndigit--;
  330.  
  331.         if (USE_EXP(dp,ndigit)) {
  332.                 /* Use E format */
  333.                 dp--;
  334.                 *s2++ = *s1++;
  335.                 if ((nndigit > 1) || (flags & FL_ALT)) *s2++ = '.';
  336.                 while (--nndigit > 0) *s2++ = *s1++;
  337.                 *s2++ = 'e';
  338.                 if (dp < 0) {
  339.                         *s2++ = '-';
  340.                         dp = -dp;
  341.                 }
  342.                 else     *s2++ = '+';
  343.                 s2 += NDIGINEXP(dp);
  344.                 *s2 = 0;
  345.                 for (i = NDIGINEXP(dp); i > 0; i--) {
  346.                         *--s2 = dp % 10 + '0';
  347.                         dp /= 10;
  348.                 }
  349.                 return s;
  350.         }
  351.         /* Use f format */
  352.         if (dp <= 0) {
  353.                 if (*s1 != '0') {
  354.                         /* otherwise the whole number is 0 */
  355.                         *s2++ = '0';
  356.                         *s2++ = '.';
  357.                 }
  358.                 while (dp < 0) {
  359.                         dp++;
  360.                         *s2++ = '0';
  361.                 }
  362.         }
  363.         for (i = 1; i <= nndigit; i++) {
  364.                 *s2++ = *s1++;
  365.                 if (i == dp) *s2++ = '.';
  366.         }
  367.         if (i <= dp) {
  368.                 while (i++ <= dp) *s2++ = '0';
  369.                 *s2++ = '.';
  370.         }
  371.         if ((s2[-1]=='.') && !(flags & FL_ALT)) s2--;
  372.         *s2 = '\0';
  373.         return s;
  374. }
  375.  
  376. char *
  377. _f_print(va_list *ap, int flags, char *s, char c, int precision)
  378. {
  379.         register char *old_s = s;
  380.   double ld_val;
  381.  
  382.  // if (flags & FL_LONGDOUBLE) ld_val = va_arg(*ap, double);
  383. //  else
  384.    ld_val = (double) va_arg(*ap, double);
  385.  
  386.         switch(c) {
  387.         case 'f':
  388.                 s = _pfloat(ld_val, s, precision, flags);
  389.                 break;
  390.         case 'e':
  391.         case 'E':
  392.                 s = _pscien(ld_val, s, precision , flags);
  393.                 break;
  394.         case 'g':
  395.         case 'G':
  396.                 s = _gcvt(ld_val, precision, s, flags);
  397.                 s += strlen(s);
  398.                 break;
  399.         }
  400.         if ( c == 'E' || c == 'G') {
  401.                 while (*old_s && *old_s != 'e') old_s++;
  402.                 if (*old_s == 'e') *old_s = 'E';
  403.         }
  404.         return s;
  405. }
  406.  
  407. //#endif  /* NOFLOAT */
  408. /* $Header$ */
  409.  
  410. //#include <stdlib.h>
  411. //#include "../ansi/ext_fmt.h"
  412.  
  413. //void _str_ext_cvt(const char *s, char **ss, struct EXTEND *e);
  414. //double _ext_dbl_cvt(struct EXTEND *e);
  415.  
  416. //double
  417. //strtod(const char *p, char **pp)
  418. //{
  419. //  struct EXTEND e;
  420.  
  421. //  _str_ext_cvt(p, pp, &e);
  422. //  return _ext_dbl_cvt(&e);
  423. //}
  424.  
  425. #define BUFSIZ    4096
  426. #define NULL            ((void *)0)
  427. #define EOF             (-1)
  428.  
  429.  
  430. /* gnum() is used to get the width and precision fields of a format. */
  431. static const char *
  432. gnum(register const char *f, int *ip, va_list *app)
  433. {
  434.         register int    i, c;
  435.  
  436.         if (*f == '*') {
  437.                 *ip = va_arg((*app), int);
  438.                 f++;
  439.         } else {
  440.                 i = 0;
  441.                 while ((c = *f - '0') >= 0 && c <= 9) {
  442.                         i = i*10 + c;
  443.                         f++;
  444.                 }
  445.                 *ip = i;
  446.         }
  447.         return f;
  448. }
  449.  
  450. #if     _EM_WSIZE == _EM_PSIZE
  451. #define set_pointer(flags)                              /* nothing */
  452. #elif   _EM_LSIZE == _EM_PSIZE
  453. #define set_pointer(flags)      (flags |= FL_LONG)
  454. #else
  455. #error garbage pointer size
  456. #define set_pointer(flags)              /* compilation might continue */
  457. #endif
  458.  
  459. /* print an ordinal number */
  460. static char *
  461. o_print(va_list *ap, int flags, char *s, char c, int precision, int is_signed)
  462. {
  463.         long signed_val;
  464.         unsigned long unsigned_val;
  465.         char *old_s = s;
  466.         int base;
  467.  
  468.         switch (flags & (FL_SHORT | FL_LONG)) {
  469.         case FL_SHORT:
  470.                 if (is_signed) {
  471.                         signed_val = (short) va_arg(*ap, int);
  472.                 } else {
  473.                         unsigned_val = (unsigned short) va_arg(*ap, unsigned);
  474.                 }
  475.                 break;
  476.         case FL_LONG:
  477.                 if (is_signed) {
  478.                         signed_val = va_arg(*ap, long);
  479.                 } else {
  480.                         unsigned_val = va_arg(*ap, unsigned long);
  481.                 }
  482.                 break;
  483.         default:
  484.                 if (is_signed) {
  485.                         signed_val = va_arg(*ap, int);
  486.                 } else {
  487.                         unsigned_val = va_arg(*ap, unsigned int);
  488.                 }
  489.                 break;
  490.         }
  491.  
  492.         if (is_signed) {
  493.                 if (signed_val < 0) {
  494.                         *s++ = '-';
  495.                         signed_val = -signed_val;
  496.                 } else if (flags & FL_SIGN) *s++ = '+';
  497.                 else if (flags & FL_SPACE) *s++ = ' ';
  498.                 unsigned_val = signed_val;
  499.         }
  500.         if ((flags & FL_ALT) && (c == 'o')) *s++ = '0';
  501.         if (!unsigned_val && c != 'p') {
  502.                  if (!precision)
  503.                         return s;
  504.         } else if (((flags & FL_ALT) && (c == 'x' || c == 'X'))
  505.                     || c == 'p') {
  506.                 *s++ = '0';
  507.                 *s++ = (c == 'X' ? 'X' : 'x');
  508.         }
  509.  
  510.         switch (c) {
  511.         case 'b':       base = 2;       break;
  512.         case 'o':       base = 8;       break;
  513.         case 'd':
  514.         case 'i':
  515.         case 'u':       base = 10;      break;
  516.         case 'x':
  517.         case 'X':
  518.         case 'p':       base = 16;      break;
  519.         }
  520.  
  521.         s = _i_compute(unsigned_val, base, s, precision);
  522.  
  523.         if (c == 'X')
  524.                 while (old_s != s) {
  525.                         *old_s = toupper(*old_s);
  526.                         old_s++;
  527.                 }
  528.  
  529.         return s;
  530. }
  531.  
  532.  
  533. #define putc(c, p)  (--(p)->_count >= 0 ?  (int) (*(p)->_ptr++ = (c)) : EOF)
  534.  
  535. int
  536. _doprnt(register const char *fmt, va_list ap, __str *stream)
  537. {
  538.         register char   *s;
  539.         register int    j;
  540.         int             i, c, width, precision, zfill, flags, between_fill;
  541.         int             nrchars=0;
  542.         const char      *oldfmt;
  543.   char    *s1, buf[512];
  544.  
  545.   while (c = *fmt++)
  546.   {
  547.     if (c != '%')
  548.     {
  549.       if (c == '\n')
  550.       {
  551.                                 if (putc('\r', stream) == EOF)
  552.                                         return nrchars ? -nrchars : -1;
  553.                                 nrchars++;
  554.       }
  555.                         if (putc(c, stream) == EOF)
  556.                                 return nrchars ? -nrchars : -1;
  557.                         nrchars++;
  558.                         continue;
  559.                 }
  560.                 flags = 0;
  561.                 do {
  562.                         switch(*fmt) {
  563.                         case '-':       flags |= FL_LJUST;      break;
  564.                         case '+':       flags |= FL_SIGN;       break;
  565.                         case ' ':       flags |= FL_SPACE;      break;
  566.                         case '#':       flags |= FL_ALT;        break;
  567.                         case '0':       flags |= FL_ZEROFILL;   break;
  568.                         default:        flags |= FL_NOMORE;     continue;
  569.                         }
  570.                         fmt++;
  571.                 } while(!(flags & FL_NOMORE));
  572.  
  573.                 oldfmt = fmt;
  574.                 fmt = gnum(fmt, &width, &ap);
  575.                 if (fmt != oldfmt) flags |= FL_WIDTHSPEC;
  576.  
  577.                 if (*fmt == '.') {
  578.                         fmt++; oldfmt = fmt;
  579.                         fmt = gnum(fmt, &precision, &ap);
  580.                         if (precision >= 0) flags |= FL_PRECSPEC;
  581.                 }
  582.  
  583.                 if ((flags & FL_WIDTHSPEC) && width < 0) {
  584.                         width = -width;
  585.                         flags |= FL_LJUST;
  586.                 }
  587.                 if (!(flags & FL_WIDTHSPEC)) width = 0;
  588.  
  589.                 if (flags & FL_SIGN) flags &= ~FL_SPACE;
  590.  
  591.                 if (flags & FL_LJUST) flags &= ~FL_ZEROFILL;
  592.  
  593.  
  594.                 s = s1 = buf;
  595.  
  596.                 switch (*fmt) {
  597.                 case 'h':       flags |= FL_SHORT; fmt++; break;
  598.                 case 'l':       flags |= FL_LONG; fmt++; break;
  599.                 case 'L':       flags |= FL_LONGDOUBLE; fmt++; break;
  600.                 }
  601.  
  602.                 switch (c = *fmt++) {
  603.                 default:
  604.       if (c == '\n') {
  605.                                 if (putc('\r', stream) == EOF)
  606.                                         return nrchars ? -nrchars : -1;
  607.                                 nrchars++;
  608.                         }
  609.                         if (putc(c, stream) == EOF)
  610.                                 return nrchars ? -nrchars : -1;
  611.                         nrchars++;
  612.                         continue;
  613.                 case 'n':
  614.                         if (flags & FL_SHORT)
  615.                                 *va_arg(ap, short *) = (short) nrchars;
  616.                         else if (flags & FL_LONG)
  617.                                 *va_arg(ap, long *) = (long) nrchars;
  618.                         else
  619.                                 *va_arg(ap, int *) = (int) nrchars;
  620.                         continue;
  621.                 case 's':
  622.                         s1 = va_arg(ap, char *);
  623.                         if (s1 == NULL)
  624.                                 s1 = "(null)";
  625.                         s = s1;
  626.                         while (precision || !(flags & FL_PRECSPEC)) {
  627.                                 if (*s == '\0')
  628.                                         break;
  629.                                 s++;
  630.                                 precision--;
  631.                         }
  632.                         break;
  633.                 case 'p':
  634.                         set_pointer(flags);
  635.                         /* fallthrough */
  636.                 case 'b':
  637.                 case 'o':
  638.                 case 'u':
  639.                 case 'x':
  640.                 case 'X':
  641.                         if (!(flags & FL_PRECSPEC)) precision = 1;
  642.                         else if (c != 'p') flags &= ~FL_ZEROFILL;
  643.                         s = o_print(&ap, flags, s, c, precision, 0);
  644.                         break;
  645.                 case 'd':
  646.                 case 'i':
  647.                         flags |= FL_SIGNEDCONV;
  648.                         if (!(flags & FL_PRECSPEC)) precision = 1;
  649.                         else flags &= ~FL_ZEROFILL;
  650.                         s = o_print(&ap, flags, s, c, precision, 1);
  651.                         break;
  652.                 case 'c':
  653.                         *s++ = va_arg(ap, int);
  654.                         break;
  655.  
  656.                 case 'G':
  657.                 case 'g':
  658.                         if ((flags & FL_PRECSPEC) && (precision == 0))
  659.                                 precision = 1;
  660.                 case 'f':
  661.                 case 'E':
  662.                 case 'e':
  663.                         if (!(flags & FL_PRECSPEC))
  664.                                 precision = 6;
  665.  
  666.                         if (precision >= sizeof(buf))
  667.                                 precision = sizeof(buf) - 1;
  668.  
  669.                         flags |= FL_SIGNEDCONV;
  670.                         s = _f_print(&ap, flags, s, c, precision);
  671.                         break;
  672.     case 'r':
  673.                         ap = va_arg(ap, va_list);
  674.                         fmt = va_arg(ap, char *);
  675.                         continue;
  676.                 }
  677.                 zfill = ' ';
  678.                 if (flags & FL_ZEROFILL) zfill = '0';
  679.                 j = s - s1;
  680.  
  681.                 /* between_fill is true under the following conditions:
  682.                  * 1- the fill character is '0'
  683.                  * and
  684.                  * 2a- the number is of the form 0x... or 0X...
  685.                  * or
  686.                  * 2b- the number contains a sign or space
  687.                  */
  688.                 between_fill = 0;
  689.                 if ((flags & FL_ZEROFILL)
  690.                     && (((c == 'x' || c == 'X') && (flags & FL_ALT) && j > 1)
  691.                         || (c == 'p')
  692.                         || ((flags & FL_SIGNEDCONV)
  693.                             && ( *s1 == '+' || *s1 == '-' || *s1 == ' '))))
  694.                         between_fill++;
  695.  
  696.                 if ((i = width - j) > 0)
  697.                         if (!(flags & FL_LJUST)) {      /* right justify */
  698.                                 nrchars += i;
  699.                                 if (between_fill) {
  700.                                     if (flags & FL_SIGNEDCONV) {
  701.                                         j--; nrchars++;
  702.                                         if (putc(*s1++, stream) == EOF)
  703.                                                 return nrchars ? -nrchars : -1;
  704.                                     } else {
  705.                                         j -= 2; nrchars += 2;
  706.                                         if ((putc(*s1++, stream) == EOF)
  707.                                             || (putc(*s1++, stream) == EOF))
  708.                                                 return nrchars ? -nrchars : -1;
  709.                                     }
  710.                                 }
  711.                                 do {
  712.                                         if (putc(zfill, stream) == EOF)
  713.                                                 return nrchars ? -nrchars : -1;
  714.                                 } while (--i);
  715.                         }
  716.  
  717.                 nrchars += j;
  718.                 while (--j >= 0) {
  719.                         if (putc(*s1++, stream) == EOF)
  720.                                 return nrchars ? -nrchars : -1;
  721.                 }
  722.  
  723.                 if (i > 0) nrchars += i;
  724.                 while (--i >= 0)
  725.                         if (putc(zfill, stream) == EOF)
  726.                                 return nrchars ? -nrchars : -1;
  727.         }
  728.         return nrchars;
  729. }
  730.  
  731. int
  732. vsnprintf(char *s, size_t n, const char *format, va_list arg)
  733. {
  734.         int retval;
  735.   __str tmp_stream;
  736.  
  737.   //tmp_stream._buf    = (unsigned char *) s;
  738.         tmp_stream._ptr    = (unsigned char *) s;
  739.         tmp_stream._count  = n-1;
  740.  
  741.         retval = _doprnt(format, arg, &tmp_stream);
  742.         tmp_stream._count  = 1;
  743.         putc('\0',&tmp_stream);
  744.  
  745.         return retval;
  746. }
  747.  
  748. int
  749. vsprintf(char *s, const char *format, va_list arg)
  750. {
  751.         return vsnprintf(s, INT_MAX, format, arg);
  752. }
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.