Subversion Repositories Kolibri OS

Rev

Rev 1029 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1029 serge 1
/*
2
 * vsprintf - print formatted output without ellipsis on an array
3
 */
4
/* $Header$ */
5
 
6
//#include  "stdio.h"
7
//#include  
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	
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 
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