diff options
Diffstat (limited to 'libc/stdio')
| -rw-r--r-- | libc/stdio/printf.c | 24 | ||||
| -rw-r--r-- | libc/stdio/stdio.c | 75 | 
2 files changed, 94 insertions, 5 deletions
| diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c index d593f769c..d08ac56b0 100644 --- a/libc/stdio/printf.c +++ b/libc/stdio/printf.c @@ -1103,10 +1103,18 @@ int _do_one_spec(FILE * __restrict stream, register ppfs_t *ppfs, int *count)  	size_t slen;  	int base;  	int numpad; +	int alphacase;  	int numfill = 0;			/* TODO: fix */  	int prefix_num = PREFIX_NONE;  	char padchar = ' '; -	char buf[64]; +#ifdef __UCLIBC_MJN3_ONLY__ +#warning REMINDER: buf size +#endif +	/* TODO: buf needs to be big enough for any possible error return strings +	 * and also for any locale-grouped long long integer strings generated. +	 * This should be large enough for any of the current archs/locales, but +	 * eventually this should be handled robustly. */ +	char buf[128];  #ifdef NDEBUG  	_ppfs_parsespec(ppfs); @@ -1147,8 +1155,16 @@ int _do_one_spec(FILE * __restrict stream, register ppfs_t *ppfs, int *count)  			return 0;  		}  		if (ppfs->conv_num <= CONV_i) {	/* pointer or (un)signed int */ -			base = spec_base[(int)(ppfs->conv_num - CONV_p)]; +			alphacase = __UIM_LOWER; +			if (((base = spec_base[(int)(ppfs->conv_num - CONV_p)]) == 10) +				&& (PRINT_INFO_FLAG_VAL(&(ppfs->info),group)) +				) { +				alphacase = __UIM_GROUP; +			}  			if (ppfs->conv_num <= CONV_u) { /* pointer or unsigned int */ +				if (ppfs->conv_num == CONV_X) { +					alphacase = __UIM_UPPER; +				}  				if (ppfs->conv_num == CONV_p) { /* pointer */  					prefix_num = PREFIX_LWR_X;  				} else {		/* unsigned int */ @@ -1162,9 +1178,7 @@ int _do_one_spec(FILE * __restrict stream, register ppfs_t *ppfs, int *count)  			s = _uintmaxtostr(buf + sizeof(buf) - 1,  							  (uintmax_t)  							  _load_inttype(*argtype & __PA_INTMASK, -											*argptr, base), base, -							  ((ppfs->conv_num == CONV_X) -							   ? __UIM_UPPER : __UIM_LOWER)); +											*argptr, base), base, alphacase);  			if (ppfs->conv_num > CONV_u) { /* signed int */  				if (*s == '-') {  					PRINT_INFO_SET_FLAG(&(ppfs->info),showsign); diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c index b0b046900..f75011aec 100644 --- a/libc/stdio/stdio.c +++ b/libc/stdio/stdio.c @@ -3308,6 +3308,15 @@ void _stdio_fdout(int fd, ...)  #define INTERNAL_DIV_MOD  #endif +#ifdef __UCLIBC_MJN3_ONLY__ +#warning REMINDER: move _uintmaxtostr to locale.c??? +#endif +#include <locale.h> + +#ifndef __LOCALE_C_ONLY +#define CUR_LOCALE			(__global_locale) +#endif /* __LOCALE_C_ONLY */ +  char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,  					int base, __UIM_CASE alphacase)  { @@ -3316,6 +3325,11 @@ char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,  #ifdef INTERNAL_DIV_MOD  	unsigned int H, L, high, low, rh;  #endif +#ifndef __LOCALE_C_ONLY +	int grouping; +	size_t gslen;		   /* This does not need to be initialized. */ +	const char *g;		   /* This does not need to be initialized. */ +#endif /* __LOCALE_C_ONLY */  	negative = 0;  	if (base < 0) {				/* signed value */ @@ -3329,10 +3343,46 @@ char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,  	/* this is an internal routine -- we shouldn't need to check this */  	assert(!((base < 2) || (base > 36))); +#ifndef __LOCALE_C_ONLY +	grouping = -1; +	if (alphacase == __UIM_GROUP) { +		assert(base == 10); +		if (*(g = CUR_LOCALE.grouping) +			&& ((gslen = strlen(CUR_LOCALE.thousands_sep)) > 0) +			) { +			grouping = *g; +		} +	} +#endif /* __LOCALE_C_ONLY */ +      *bufend = '\0';  #ifndef INTERNAL_DIV_MOD      do { +#ifndef __LOCALE_C_ONLY +		if (!grouping) {		/* Finished a group. */ +#ifdef __UCLIBC_MJN3_ONLY__ +#warning REMINDER: decide about memcpy in _uintmaxtostr +#endif +#if 0 +			bufend -= gslen; +			memcpy(bufend, CUR_LOCALE.thousands_sep, gslen); +#else +			grouping = gslen; +			do { +				*--bufend = CUR_LOCALE.thousands_sep[--grouping]; +			} while (grouping); +#endif +			if (g[1] != 0) { 	/* g[1] == 0 means repeat last grouping. */ +				/* Note: g[1] == -1 means no further grouping.  But since +				 * we'll never wrap around, we can set grouping to -1 without +				 * fear of */ +				++g; +			} +			grouping = *g; +		} +		--grouping; +#endif /* __LOCALE_C_ONLY */  		digit = uval % base;  		uval /= base; @@ -3351,6 +3401,31 @@ char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,  	high = (unsigned int) (uval >> (sizeof(unsigned int) * CHAR_BIT));      do { +#ifndef __LOCALE_C_ONLY +		if (!grouping) {		/* Finished a group. */ +#ifdef __UCLIBC_MJN3_ONLY__ +#warning REMINDER: decide about memcpy in _uintmaxtostr +#endif +#if 0 +			bufend -= gslen; +			memcpy(bufend, CUR_LOCALE.thousands_sep, gslen); +#else +			grouping = gslen; +			do { +				*--bufend = CUR_LOCALE.thousands_sep[--grouping]; +			} while (grouping); +#endif +			if (g[1] != 0) { 	/* g[1] == 0 means repeat last grouping. */ +				/* Note: g[1] == -1 means no further grouping.  But since +				 * we'll never wrap around, we can set grouping to -1 without +				 * fear of */ +				++g; +			} +			grouping = *g; +		} +		--grouping; +#endif /* __LOCALE_C_ONLY */ +  		rh = high % base;  		high /= base;  		digit = (low % base) + (L * rh); | 
