diff --git a/lib/stdio/doprnt.c b/lib/stdio/doprnt.c index a0248b688..9c4aba2fe 100644 --- a/lib/stdio/doprnt.c +++ b/lib/stdio/doprnt.c @@ -42,12 +42,12 @@ gnum(register const char *f, int *ip, va_list *app) static char * o_print(va_list *ap, int flags, char *s, char c, int precision, int is_signed) { - long signed_val; - unsigned long unsigned_val; + printval_s_t signed_val; + printval_u_t unsigned_val; char *old_s = s; int base; - switch (flags & (FL_SHORT | FL_LONG)) { + switch (flags & (FL_SHORT | FL_LONG | FL_LONGLONG)) { case FL_SHORT: if (is_signed) { signed_val = (short) va_arg(*ap, int); @@ -62,6 +62,15 @@ o_print(va_list *ap, int flags, char *s, char c, int precision, int is_signed) unsigned_val = va_arg(*ap, unsigned long); } break; +#if defined(__LONG_LONG_SUPPORTED) + case FL_LONG | FL_LONGLONG: + if (is_signed) { + signed_val = va_arg(*ap, long long); + } else { + unsigned_val = va_arg(*ap, unsigned long long); + } + break; +#endif default: if (is_signed) { signed_val = va_arg(*ap, int); @@ -171,11 +180,27 @@ _doprnt(register const char *fmt, va_list ap, FILE *stream) s = s1 = buf; - switch (*fmt) { - case 'h': flags |= FL_SHORT; fmt++; break; - case 'l': flags |= FL_LONG; fmt++; break; - case 'L': flags |= FL_LONGDOUBLE; fmt++; break; - } + flags &= ~FL_NOMORE; + do { + switch (*fmt) { + case 'h': + flags |= FL_SHORT; + break; + case 'l': + if(flags & FL_LONG) + flags |= FL_LONGLONG; + else + flags |= FL_LONG; + break; + case 'L': + flags |= FL_LONGDOUBLE; + break; + default: + flags |= FL_NOMORE; + continue; + } + fmt++; + } while(!(flags & FL_NOMORE)); switch (c = *fmt++) { default: diff --git a/lib/stdio/icompute.c b/lib/stdio/icompute.c index 5e7fa80f6..6d2f33092 100644 --- a/lib/stdio/icompute.c +++ b/lib/stdio/icompute.c @@ -8,7 +8,7 @@ /* This routine is used in doprnt.c as well as in tmpfile.c and tmpnam.c. */ char * -_i_compute(unsigned long val, int base, char *s, int nrdigits) +_i_compute(printval_u_t val, int base, char *s, int nrdigits) { int c; diff --git a/lib/stdio/loc_incl.h b/lib/stdio/loc_incl.h index 77dee58a3..157800310 100644 --- a/lib/stdio/loc_incl.h +++ b/lib/stdio/loc_incl.h @@ -4,15 +4,24 @@ /* $Header$ */ #include +#include #define io_testflag(p,x) ((p)->_flags & (x)) #include +#if defined(__LONG_LONG_SUPPORTED) +typedef long long printval_s_t; +typedef unsigned long long printval_u_t; +#else +typedef long printval_s_t; +typedef unsigned long printval_u_t; +#endif + #ifdef _ANSI int _doprnt(const char *format, va_list ap, FILE *stream); int _doscan(FILE * stream, const char *format, va_list ap); -char *_i_compute(unsigned long val, int base, char *s, int nrdigits); +char *_i_compute(printval_u_t val, int base, char *s, int nrdigits); char *_f_print(va_list *ap, int flags, char *s, char c, int precision); void __cleanup(void); @@ -38,3 +47,4 @@ char *_fcvt(long double value, int ndigit, int *decpt, int *sign); #define FL_SIGNEDCONV 0x0400 /* may contain a sign */ #define FL_NOASSIGN 0x0800 /* do not assign (in scanf) */ #define FL_NOMORE 0x1000 /* all flags collected */ +#define FL_LONGLONG 0x2000 /* 64-bit for ints */