2 * doprnt.c - print formatted output
12 /* gnum() is used to get the width and precision fields of a format. */
14 gnum(register const char *f
, int *ip
, va_list *app
)
19 *ip
= va_arg((*app
), int);
23 while ((c
= *f
- '0') >= 0 && c
<= 9) {
32 #if _EM_WSIZE == _EM_PSIZE
33 #define set_pointer(flags) /* nothing */
34 #elif _EM_LSIZE == _EM_PSIZE
35 #define set_pointer(flags) (flags |= FL_LONG)
37 #error garbage pointer size
38 #define set_pointer(flags) /* compilation might continue */
41 /* print an ordinal number */
43 o_print(va_list *ap
, int flags
, char *s
, char c
, int precision
, int is_signed
)
46 unsigned long unsigned_val
;
50 switch (flags
& (FL_SHORT
| FL_LONG
)) {
53 signed_val
= (short) va_arg(*ap
, int);
55 unsigned_val
= (unsigned short) va_arg(*ap
, unsigned);
60 signed_val
= va_arg(*ap
, long);
62 unsigned_val
= va_arg(*ap
, unsigned long);
67 signed_val
= va_arg(*ap
, int);
69 unsigned_val
= va_arg(*ap
, unsigned int);
77 signed_val
= -signed_val
;
78 } else if (flags
& FL_SIGN
) *s
++ = '+';
79 else if (flags
& FL_SPACE
) *s
++ = ' ';
80 unsigned_val
= signed_val
;
82 if ((flags
& FL_ALT
) && (c
== 'o')) *s
++ = '0';
83 if (!unsigned_val
&& c
!= 'p') {
86 } else if (((flags
& FL_ALT
) && (c
== 'x' || c
== 'X'))
89 *s
++ = (c
== 'X' ? 'X' : 'x');
93 case 'b': base
= 2; break;
94 case 'o': base
= 8; break;
97 case 'u': base
= 10; break;
100 case 'p': base
= 16; break;
103 s
= _i_compute(unsigned_val
, base
, s
, precision
);
107 *old_s
= toupper(*old_s
);
115 _doprnt(register const char *fmt
, va_list ap
, FILE *stream
)
119 int i
, c
, width
, precision
, zfill
, flags
, between_fill
;
128 if (putc('\r', stream
) == EOF
)
129 return nrchars
? -nrchars
: -1;
133 if (putc(c
, stream
) == EOF
)
134 return nrchars
? -nrchars
: -1;
141 case '-': flags
|= FL_LJUST
; break;
142 case '+': flags
|= FL_SIGN
; break;
143 case ' ': flags
|= FL_SPACE
; break;
144 case '#': flags
|= FL_ALT
; break;
145 case '0': flags
|= FL_ZEROFILL
; break;
146 default: flags
|= FL_NOMORE
; continue;
149 } while(!(flags
& FL_NOMORE
));
152 fmt
= gnum(fmt
, &width
, &ap
);
153 if (fmt
!= oldfmt
) flags
|= FL_WIDTHSPEC
;
157 fmt
= gnum(fmt
, &precision
, &ap
);
158 if (precision
>= 0) flags
|= FL_PRECSPEC
;
161 if ((flags
& FL_WIDTHSPEC
) && width
< 0) {
165 if (!(flags
& FL_WIDTHSPEC
)) width
= 0;
167 if (flags
& FL_SIGN
) flags
&= ~FL_SPACE
;
169 if (flags
& FL_LJUST
) flags
&= ~FL_ZEROFILL
;
175 case 'h': flags
|= FL_SHORT
; fmt
++; break;
176 case 'l': flags
|= FL_LONG
; fmt
++; break;
177 case 'L': flags
|= FL_LONGDOUBLE
; fmt
++; break;
180 switch (c
= *fmt
++) {
184 if (putc('\r', stream
) == EOF
)
185 return nrchars
? -nrchars
: -1;
189 if (putc(c
, stream
) == EOF
)
190 return nrchars
? -nrchars
: -1;
194 if (flags
& FL_SHORT
)
195 *va_arg(ap
, short *) = (short) nrchars
;
196 else if (flags
& FL_LONG
)
197 *va_arg(ap
, long *) = (long) nrchars
;
199 *va_arg(ap
, int *) = (int) nrchars
;
202 s1
= va_arg(ap
, char *);
206 while (precision
|| !(flags
& FL_PRECSPEC
)) {
221 if (!(flags
& FL_PRECSPEC
)) precision
= 1;
222 else if (c
!= 'p') flags
&= ~FL_ZEROFILL
;
223 s
= o_print(&ap
, flags
, s
, c
, precision
, 0);
227 flags
|= FL_SIGNEDCONV
;
228 if (!(flags
& FL_PRECSPEC
)) precision
= 1;
229 else flags
&= ~FL_ZEROFILL
;
230 s
= o_print(&ap
, flags
, s
, c
, precision
, 1);
233 *s
++ = va_arg(ap
, int);
238 if ((flags
& FL_PRECSPEC
) && (precision
== 0))
243 if (!(flags
& FL_PRECSPEC
))
246 if (precision
>= sizeof(buf
))
247 precision
= sizeof(buf
) - 1;
249 flags
|= FL_SIGNEDCONV
;
250 s
= _f_print(&ap
, flags
, s
, c
, precision
);
254 ap
= va_arg(ap
, va_list);
255 fmt
= va_arg(ap
, char *);
259 if (flags
& FL_ZEROFILL
) zfill
= '0';
262 /* between_fill is true under the following conditions:
263 * 1- the fill character is '0'
265 * 2a- the number is of the form 0x... or 0X...
267 * 2b- the number contains a sign or space
270 if ((flags
& FL_ZEROFILL
)
271 && (((c
== 'x' || c
== 'X') && (flags
& FL_ALT
) && j
> 1)
273 || ((flags
& FL_SIGNEDCONV
)
274 && ( *s1
== '+' || *s1
== '-' || *s1
== ' '))))
277 if ((i
= width
- j
) > 0)
278 if (!(flags
& FL_LJUST
)) { /* right justify */
281 if (flags
& FL_SIGNEDCONV
) {
283 if (putc(*s1
++, stream
) == EOF
)
284 return nrchars
? -nrchars
: -1;
286 j
-= 2; nrchars
+= 2;
287 if ((putc(*s1
++, stream
) == EOF
)
288 || (putc(*s1
++, stream
) == EOF
))
289 return nrchars
? -nrchars
: -1;
293 if (putc(zfill
, stream
) == EOF
)
294 return nrchars
? -nrchars
: -1;
300 if (putc(*s1
++, stream
) == EOF
)
301 return nrchars
? -nrchars
: -1;
304 if (i
> 0) nrchars
+= i
;
306 if (putc(zfill
, stream
) == EOF
)
307 return nrchars
? -nrchars
: -1;