enhanced formatted output function
This commit is contained in:
		| @ -56,9 +56,21 @@ static struct | |||||||
| 	{ LF_Z, 0 }, /* z */ | 	{ LF_Z, 0 }, /* z */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | enum  | ||||||
|  | { | ||||||
|  | 	FLAGC_DOT       = (1 << 0), | ||||||
|  | 	FLAGC_SHARP     = (1 << 1), | ||||||
|  | 	FLAGC_SIGN      = (1 << 2), | ||||||
|  | 	FLAGC_SPACE     = (1 << 3), | ||||||
|  | 	FLAGC_LEFTADJ   = (1 << 4), | ||||||
|  | 	FLAGC_ZEROPAD   = (1 << 5), | ||||||
|  | 	FLAGC_WIDTH     = (1 << 6) | ||||||
|  | }; | ||||||
|  |  | ||||||
| #include <stdio.h> /* TODO: remove dependency on this */ | #include <stdio.h> /* TODO: remove dependency on this */ | ||||||
|  |  | ||||||
| static void xputwchar (qse_wchar_t c, void *arg) | static void put_wchar (qse_wchar_t c, void *arg) | ||||||
| { | { | ||||||
| 	qse_cmgr_t* cmgr; | 	qse_cmgr_t* cmgr; | ||||||
| 	qse_mchar_t mbsbuf[QSE_MBLEN_MAX + 1]; | 	qse_mchar_t mbsbuf[QSE_MBLEN_MAX + 1]; | ||||||
| @ -77,7 +89,7 @@ static void xputwchar (qse_wchar_t c, void *arg) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| static void xputmchar (qse_mchar_t c, void *arg) | static void put_mchar (qse_mchar_t c, void *arg) | ||||||
| { | { | ||||||
| 	putchar (c); | 	putchar (c); | ||||||
| } | } | ||||||
| @ -111,14 +123,14 @@ int qse_mprintf (const char_t *fmt, ...) | |||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 	int n; | 	int n; | ||||||
| 	va_start (ap, fmt); | 	va_start (ap, fmt); | ||||||
| 	n = qse_mxprintf (fmt, xputmchar, xputwchar, QSE_NULL, ap); | 	n = qse_mxprintf (fmt, put_mchar, put_wchar, QSE_NULL, ap); | ||||||
| 	va_end (ap); | 	va_end (ap); | ||||||
| 	return n; | 	return n; | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_mvprintf (const char_t* fmt, va_list ap) | int qse_mvprintf (const char_t* fmt, va_list ap) | ||||||
| { | { | ||||||
| 	return qse_mxprintf (fmt, xputmchar, xputwchar, QSE_NULL, ap); | 	return qse_mxprintf (fmt, put_mchar, put_wchar, QSE_NULL, ap); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------ */ | /* ------------------------------------------------------------------ */ | ||||||
| @ -142,7 +154,8 @@ int qse_mvprintf (const char_t* fmt, va_list ap) | |||||||
| #define sprintn w_sprintn | #define sprintn w_sprintn | ||||||
| #define xprintf qse_wxprintf  | #define xprintf qse_wxprintf  | ||||||
|  |  | ||||||
| static const qse_wchar_t w_hex2ascii[] = QSE_WT("0123456789abcdefghijklmnopqrstuvwxyz"); | static const qse_wchar_t w_hex2ascii[] =  | ||||||
|  | 	QSE_WT("0123456789abcdefghijklmnopqrstuvwxyz"); | ||||||
| #define hex2ascii(hex)  (w_hex2ascii[hex]) | #define hex2ascii(hex)  (w_hex2ascii[hex]) | ||||||
|  |  | ||||||
| #include "printf.h" | #include "printf.h" | ||||||
| @ -152,12 +165,12 @@ int qse_wprintf (const char_t *fmt, ...) | |||||||
| 	va_list ap; | 	va_list ap; | ||||||
| 	int n; | 	int n; | ||||||
| 	va_start (ap, fmt); | 	va_start (ap, fmt); | ||||||
| 	n = qse_wxprintf (fmt, xputwchar, xputmchar, QSE_NULL, ap); | 	n = qse_wxprintf (fmt, put_wchar, put_mchar, QSE_NULL, ap); | ||||||
| 	va_end (ap); | 	va_end (ap); | ||||||
| 	return n; | 	return n; | ||||||
| } | } | ||||||
|  |  | ||||||
| int qse_wvprintf (const char_t* fmt, va_list ap) | int qse_wvprintf (const char_t* fmt, va_list ap) | ||||||
| { | { | ||||||
| 	return qse_wxprintf (fmt, xputwchar, xputmchar, QSE_NULL, ap); | 	return qse_wxprintf (fmt, put_wchar, put_mchar, QSE_NULL, ap); | ||||||
| } | } | ||||||
|  | |||||||
| @ -59,97 +59,143 @@ static char_t* sprintn (char_t* nbuf, qse_uintmax_t num, int base, int *lenp, in | |||||||
| 	while (num /= base); | 	while (num /= base); | ||||||
|  |  | ||||||
| 	if (lenp) *lenp = p - nbuf; | 	if (lenp) *lenp = p - nbuf; | ||||||
| 	return (p); | 	return p; | ||||||
| } | } | ||||||
|  |  | ||||||
| #define PCHAR(c) do { \ | #undef PUT_CHAR | ||||||
| 	func (c, arg); \ | #undef PUT_OCHAR | ||||||
|  |  | ||||||
|  | /* TODO: error check */ | ||||||
|  | #define PUT_CHAR(c) do { \ | ||||||
|  | 	put_char (c, arg); \ | ||||||
| 	retval++; \ | 	retval++; \ | ||||||
| } while (0) | } while (0) | ||||||
|  |  | ||||||
| #define OPCHAR(c) do { \ | #define PUT_OCHAR(c) do { \ | ||||||
| 	ofunc (c, arg); \ | 	put_ochar (c, arg); \ | ||||||
| 	retval++; \ | 	retval++; \ | ||||||
| } while (0) | } while (0) | ||||||
|  |  | ||||||
| int xprintf (char_t const *fmt, void (*func)(char_t, void*), void (*ofunc) (ochar_t, void*), void *arg, va_list ap) | int xprintf (char_t const *fmt, void (*put_char)(char_t, void*), void (*put_ochar) (ochar_t, void*), void *arg, va_list ap) | ||||||
| { | { | ||||||
| 	char_t nbuf[MAXNBUF]; | 	char_t nbuf[MAXNBUF]; | ||||||
| 	const char_t* p, * percent; | 	const char_t* p, * percent; | ||||||
| 	uchar_t ch;  | 	uchar_t ch;  | ||||||
| 	int n; | 	int n; | ||||||
| 	qse_uintmax_t num; | 	qse_uintmax_t num; | ||||||
| 	int base, tmp, width, ladjust, sharpflag, neg, sign, dot; | 	int base, tmp, width, neg, sign; | ||||||
| 	int dwidth, upper; | 	int precision, upper; | ||||||
| 	char_t padc, * sp; | 	char_t padc, * sp; | ||||||
| 	ochar_t opadc, * osp; | 	ochar_t opadc, * osp; | ||||||
| 	int stop = 0, retval = 0; | 	int stop = 0, retval = 0; | ||||||
| 	int lm_flag, lm_dflag; | 	int lm_flag, lm_dflag, flagc; | ||||||
|  | 	int numlen; | ||||||
|  |  | ||||||
| 	num = 0; | 	num = 0; | ||||||
|  |  | ||||||
| 	if (fmt == QSE_NULL) fmt = T("(fmt null)\n"); | 	/*if (fmt == QSE_NULL) fmt = T("(fmt null)\n");*/ | ||||||
|  |  | ||||||
| 	while (1) | 	while (1) | ||||||
| 	{ | 	{ | ||||||
| 		padc = T(' '); |  | ||||||
| 		opadc = OT(' '); |  | ||||||
|  |  | ||||||
| 		width = 0; |  | ||||||
| 		while ((ch = (uchar_t)*fmt++) != T('%') || stop)  | 		while ((ch = (uchar_t)*fmt++) != T('%') || stop)  | ||||||
| 		{ | 		{ | ||||||
| 			if (ch == T('\0')) return (retval); | 			if (ch == T('\0')) return retval; | ||||||
| 			PCHAR(ch); | 			PUT_CHAR(ch); | ||||||
| 		} | 		} | ||||||
| 		percent = fmt - 1; | 		percent = fmt - 1; | ||||||
| 		ladjust = 0; sharpflag = 0; neg = 0; |  | ||||||
| 		sign = 0; dot = 0; dwidth = 0; upper = 0; |  | ||||||
|  |  | ||||||
| 		lm_flag = 0; lm_dflag = 0; | 		padc = T(' '); opadc = OT(' '); | ||||||
|  | 		width = 0; precision = 0; | ||||||
|  | 		neg = 0; sign = 0; upper = 0; | ||||||
|  |  | ||||||
|  | 		lm_flag = 0; lm_dflag = 0; flagc = 0;  | ||||||
|  |  | ||||||
| reswitch:	 | reswitch:	 | ||||||
| 		switch (ch = (uchar_t)*fmt++)  | 		switch (ch = (uchar_t)*fmt++)  | ||||||
| 		{ | 		{ | ||||||
| 		case T('%'): /* %% */ | 		case T('%'): /* %% */ | ||||||
| 			PCHAR(ch); | 			PUT_CHAR(ch); | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
|  | 		/* flag characters */ | ||||||
| 		case T('.'): | 		case T('.'): | ||||||
| 			dot = 1; | 			flagc |= FLAGC_DOT; | ||||||
| 			goto reswitch; |  | ||||||
| 		case T('#'): |  | ||||||
| 			sharpflag = 1; |  | ||||||
| 			goto reswitch; |  | ||||||
| 		case T('+'): |  | ||||||
| 			sign = 1; |  | ||||||
| 			goto reswitch; |  | ||||||
| 		case T('-'): |  | ||||||
| 			ladjust = 1; |  | ||||||
| 			goto reswitch; | 			goto reswitch; | ||||||
|  |  | ||||||
| 		case T('*'): | 		case T('#'):  | ||||||
| 			if (!dot)  | 			if (flagc & (FLAGC_WIDTH | FLAGC_DOT)) goto invalid_format; | ||||||
|  | 			flagc |= FLAGC_SHARP; | ||||||
|  | 			goto reswitch; | ||||||
|  |  | ||||||
|  | 		case T(' '): | ||||||
|  | 			if (flagc & (FLAGC_WIDTH | FLAGC_DOT)) goto invalid_format; | ||||||
|  | 			flagc |= FLAGC_SPACE; | ||||||
|  | 			goto reswitch; | ||||||
|  |  | ||||||
|  | 		case T('+'): /* place sign for signed conversion */ | ||||||
|  | 			if (flagc & (FLAGC_WIDTH | FLAGC_DOT)) goto invalid_format; | ||||||
|  | 			flagc |= FLAGC_SIGN; | ||||||
|  | 			goto reswitch; | ||||||
|  |  | ||||||
|  | 		case T('-'): /* left adjusted */ | ||||||
|  | 			if (flagc & (FLAGC_WIDTH | FLAGC_DOT)) goto invalid_format; | ||||||
|  | 			if (flagc & FLAGC_DOT) | ||||||
|  | 			{ | ||||||
|  | 				goto invalid_format; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				flagc |= FLAGC_LEFTADJ; | ||||||
|  | 				if (flagc & FLAGC_ZEROPAD) | ||||||
|  | 				{ | ||||||
|  | 					padc = T(' '); | ||||||
|  | 					opadc = OT(' '); | ||||||
|  | 					flagc &= ~FLAGC_ZEROPAD; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			 | ||||||
|  | 			goto reswitch; | ||||||
|  |  | ||||||
|  | 		case T('*'): /* take the length from the parameter */ | ||||||
|  | 			if (!(flagc & FLAGC_DOT))  | ||||||
| 			{ | 			{ | ||||||
| 				width = va_arg(ap, int); | 				width = va_arg(ap, int); | ||||||
| 				if (width < 0)  | 				if (width < 0)  | ||||||
| 				{ | 				{ | ||||||
| 					ladjust = !ladjust; | 					/* | ||||||
|  | 					if (flagc & FLAGC_LEFTADJ)  | ||||||
|  | 						flagc  &= ~FLAGC_LEFTADJ; | ||||||
|  | 					else | ||||||
|  | 					*/ | ||||||
|  | 						flagc |= FLAGC_LEFTADJ; | ||||||
| 					width = -width; | 					width = -width; | ||||||
| 				} | 				} | ||||||
| 			}  | 			}  | ||||||
| 			else  | 			else  | ||||||
| 			{ | 			{ | ||||||
| 				dwidth = va_arg(ap, int); | 				precision = va_arg(ap, int); | ||||||
|  | 				if (precision < 0)  | ||||||
|  | 				{ | ||||||
|  | 					/* if precision is less than 0,  | ||||||
|  | 					 * treat it as if no .precision is specified */ | ||||||
|  | 					flagc &= ~FLAGC_DOT; | ||||||
|  | 					precision = 0; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			goto reswitch; | 			goto reswitch; | ||||||
|  |  | ||||||
| 		case T('0'): | 		case T('0'): /* zero pad */ | ||||||
| 			if (!dot)  | 			if (flagc & (FLAGC_WIDTH | FLAGC_DOT)) goto invalid_format; | ||||||
|  | 			if (!(flagc & FLAGC_LEFTADJ)) | ||||||
| 			{ | 			{ | ||||||
| 				padc = T('0'); | 				padc = T('0'); | ||||||
| 				opadc = OT('0'); | 				opadc = OT('0'); | ||||||
|  | 				flagc |= FLAGC_ZEROPAD; | ||||||
| 				goto reswitch; | 				goto reswitch; | ||||||
| 			} | 			} | ||||||
|  | 		/* end of flags characters */ | ||||||
|  |  | ||||||
| 		case T('1'): case T('2'): case T('3'): case T('4'): | 		case T('1'): case T('2'): case T('3'): case T('4'): | ||||||
| 		case T('5'): case T('6'): case T('7'): case T('8'): case T('9'): | 		case T('5'): case T('6'): case T('7'): case T('8'): case T('9'): | ||||||
| 			for (n = 0;; ++fmt)  | 			for (n = 0;; ++fmt)  | ||||||
| @ -158,32 +204,15 @@ reswitch: | |||||||
| 				ch = *fmt; | 				ch = *fmt; | ||||||
| 				if (ch < T('0') || ch > T('9')) break; | 				if (ch < T('0') || ch > T('9')) break; | ||||||
| 			} | 			} | ||||||
| 			if (dot) dwidth = n; | 			if (flagc & FLAGC_DOT) precision = n; | ||||||
| 			else width = n; | 			else  | ||||||
|  | 			{ | ||||||
|  | 				width = n; | ||||||
|  | 				flagc |= FLAGC_WIDTH; | ||||||
|  | 			} | ||||||
| 			goto reswitch; | 			goto reswitch; | ||||||
|  |  | ||||||
| 		case T('c'): | 		/* length modifiers */ | ||||||
| 			if (((lm_flag & LF_H) && (QSE_SIZEOF(char_t) > QSE_SIZEOF(ochar_t))) || |  | ||||||
| 			    ((lm_flag & LF_L) && (QSE_SIZEOF(char_t) < QSE_SIZEOF(ochar_t)))) goto uppercase_c; |  | ||||||
| 		lowercase_c: |  | ||||||
| 			if (QSE_SIZEOF(char_t) < QSE_SIZEOF(int)) |  | ||||||
| 				PCHAR(va_arg(ap, int)); |  | ||||||
| 			else |  | ||||||
| 				PCHAR(va_arg(ap, char_t)); |  | ||||||
| 			break; |  | ||||||
|  |  | ||||||
| 		case T('C'): |  | ||||||
| 			if (((lm_flag & LF_H) && (QSE_SIZEOF(char_t) < QSE_SIZEOF(ochar_t))) || |  | ||||||
| 			    ((lm_flag & LF_L) && (QSE_SIZEOF(char_t) > QSE_SIZEOF(ochar_t)))) goto lowercase_c; |  | ||||||
| 		uppercase_c: |  | ||||||
| 			if (QSE_SIZEOF(ochar_t) < QSE_SIZEOF(int)) |  | ||||||
| 				OPCHAR(va_arg(ap, int)); |  | ||||||
| 			else |  | ||||||
| 				OPCHAR(va_arg(ap, ochar_t)); |  | ||||||
| 			break; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* length modifiers */ |  | ||||||
| 		case T('h'): /* short int */ | 		case T('h'): /* short int */ | ||||||
| 		case T('l'): /* long int */ | 		case T('l'): /* long int */ | ||||||
| 		case T('q'): /* long long int */ | 		case T('q'): /* long long int */ | ||||||
| @ -193,10 +222,10 @@ reswitch: | |||||||
| 			if (lm_dflag) | 			if (lm_dflag) | ||||||
| 			{ | 			{ | ||||||
| 				/* error */ | 				/* error */ | ||||||
| 				PCHAR (fmt[-4]); | 				PUT_CHAR (fmt[-4]); | ||||||
| 				PCHAR (fmt[-3]); | 				PUT_CHAR (fmt[-3]); | ||||||
| 				PCHAR (fmt[-2]); | 				PUT_CHAR (fmt[-2]); | ||||||
| 				PCHAR (fmt[-1]); | 				PUT_CHAR (fmt[-1]); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			else if (lm_flag) | 			else if (lm_flag) | ||||||
| @ -211,9 +240,9 @@ reswitch: | |||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| 					/* error */ | 					/* error */ | ||||||
| 					PCHAR (fmt[-3]); | 					PUT_CHAR (fmt[-3]); | ||||||
| 					PCHAR (fmt[-2]); | 					PUT_CHAR (fmt[-2]); | ||||||
| 					PCHAR (fmt[-1]); | 					PUT_CHAR (fmt[-1]); | ||||||
| 					break; | 					break; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| @ -223,7 +252,7 @@ reswitch: | |||||||
| 				goto reswitch; | 				goto reswitch; | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| /* end of length modifiers */ | 		/* end of length modifiers */ | ||||||
|  |  | ||||||
| 		case T('n'): | 		case T('n'): | ||||||
| 			if (lm_flag & LF_J) | 			if (lm_flag & LF_J) | ||||||
| @ -244,14 +273,19 @@ reswitch: | |||||||
| 				*(va_arg(ap, int*)) = retval; | 				*(va_arg(ap, int*)) = retval; | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		case T('o'): |  | ||||||
| 			base = 8; | 		/* signed integer conversions */ | ||||||
| 			goto handle_nosign; |  | ||||||
| 		case T('d'): | 		case T('d'): | ||||||
| 		case T('i'): | 		case T('i'): /* signed conversion */ | ||||||
| 			base = 10; | 			base = 10; | ||||||
| 			sign = 1; | 			sign = 1; | ||||||
| 			goto handle_sign; | 			goto handle_sign; | ||||||
|  | 		/* end of signed integer conversions */ | ||||||
|  |  | ||||||
|  | 		/* unsigned integer conversions */ | ||||||
|  | 		case T('o'):  | ||||||
|  | 			base = 8; | ||||||
|  | 			goto handle_nosign; | ||||||
| 		case T('u'): | 		case T('u'): | ||||||
| 			base = 10; | 			base = 10; | ||||||
| 			goto handle_nosign; | 			goto handle_nosign; | ||||||
| @ -260,18 +294,37 @@ reswitch: | |||||||
| 		case T('x'): | 		case T('x'): | ||||||
| 			base = 16; | 			base = 16; | ||||||
| 			goto handle_nosign; | 			goto handle_nosign; | ||||||
| 		case T('y'): | 		/* end of unsigned integer conversions */ | ||||||
| 			base = 16; |  | ||||||
| 			sign = 1; |  | ||||||
| 			goto handle_sign; |  | ||||||
|  |  | ||||||
| 		case T('p'): | 		case T('p'): /* pointer */ | ||||||
| 			base = 16; | 			base = 16; | ||||||
| 			sharpflag = (width == 0); |  | ||||||
| 			sign = 0; | 			if (width == 0) flagc |= FLAGC_SHARP; | ||||||
| 			num = (qse_uintptr_t)va_arg(ap, void *); | 			else flagc &= ~FLAGC_SHARP; | ||||||
|  |  | ||||||
|  | 			num = (qse_uintptr_t)va_arg(ap, void*); | ||||||
| 			goto number; | 			goto number; | ||||||
|  |  | ||||||
|  | 		case T('c'): | ||||||
|  | 			if (((lm_flag & LF_H) && (QSE_SIZEOF(char_t) > QSE_SIZEOF(ochar_t))) || | ||||||
|  | 			    ((lm_flag & LF_L) && (QSE_SIZEOF(char_t) < QSE_SIZEOF(ochar_t)))) goto uppercase_c; | ||||||
|  | 		lowercase_c: | ||||||
|  | 			if (QSE_SIZEOF(char_t) < QSE_SIZEOF(int)) | ||||||
|  | 				PUT_CHAR(va_arg(ap, int)); | ||||||
|  | 			else | ||||||
|  | 				PUT_CHAR(va_arg(ap, char_t)); | ||||||
|  | 			break; | ||||||
|  |  | ||||||
|  | 		case T('C'): | ||||||
|  | 			if (((lm_flag & LF_H) && (QSE_SIZEOF(char_t) < QSE_SIZEOF(ochar_t))) || | ||||||
|  | 			    ((lm_flag & LF_L) && (QSE_SIZEOF(char_t) > QSE_SIZEOF(ochar_t)))) goto lowercase_c; | ||||||
|  | 		uppercase_c: | ||||||
|  | 			if (QSE_SIZEOF(ochar_t) < QSE_SIZEOF(int)) | ||||||
|  | 				PUT_OCHAR(va_arg(ap, int)); | ||||||
|  | 			else | ||||||
|  | 				PUT_OCHAR(va_arg(ap, ochar_t)); | ||||||
|  | 			break; | ||||||
|  |  | ||||||
| 		case T('s'): | 		case T('s'): | ||||||
| 		{ | 		{ | ||||||
| 			if (((lm_flag & LF_H) && (QSE_SIZEOF(char_t) > QSE_SIZEOF(ochar_t))) || | 			if (((lm_flag & LF_H) && (QSE_SIZEOF(char_t) > QSE_SIZEOF(ochar_t))) || | ||||||
| @ -279,7 +332,7 @@ reswitch: | |||||||
| 		lowercase_s: | 		lowercase_s: | ||||||
| 			sp = va_arg (ap, char_t *); | 			sp = va_arg (ap, char_t *); | ||||||
| 			if (sp == QSE_NULL) p = T("(null)"); | 			if (sp == QSE_NULL) p = T("(null)"); | ||||||
| 			if (!dot)  | 			if (!(flagc & FLAGC_DOT))  | ||||||
| 			{ | 			{ | ||||||
| 				char_t* p = sp; | 				char_t* p = sp; | ||||||
| 				while (*p) p++; | 				while (*p) p++; | ||||||
| @ -287,19 +340,19 @@ reswitch: | |||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				for (n = 0; n < dwidth && sp[n]; n++) continue; | 				for (n = 0; n < precision && sp[n]; n++) continue; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			width -= n; | 			width -= n; | ||||||
|  |  | ||||||
| 			if (!ladjust && width > 0) | 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) | ||||||
| 			{ | 			{ | ||||||
| 				while (width--) PCHAR(padc); | 				while (width--) PUT_CHAR(padc); | ||||||
| 			} | 			} | ||||||
| 			while (n--) PCHAR(*sp++); | 			while (n--) PUT_CHAR(*sp++); | ||||||
| 			if (ladjust && width > 0) | 			if ((flagc & FLAGC_LEFTADJ) && width > 0) | ||||||
| 			{ | 			{ | ||||||
| 				while (width--) PCHAR(padc); | 				while (width--) PUT_CHAR(padc); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| @ -311,7 +364,7 @@ reswitch: | |||||||
| 		uppercase_s: | 		uppercase_s: | ||||||
| 			osp = va_arg (ap, ochar_t*); | 			osp = va_arg (ap, ochar_t*); | ||||||
| 			if (osp == QSE_NULL) osp = OT("(null)"); | 			if (osp == QSE_NULL) osp = OT("(null)"); | ||||||
| 			if (!dot) | 			if (!(flagc & FLAGC_DOT))  | ||||||
| 			{ | 			{ | ||||||
| 				ochar_t* p = osp; | 				ochar_t* p = osp; | ||||||
| 				while (*p) p++; | 				while (*p) p++; | ||||||
| @ -319,19 +372,19 @@ reswitch: | |||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				for (n = 0; n < dwidth && osp[n]; n++) continue; | 				for (n = 0; n < precision && osp[n]; n++) continue; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			width -= n; | 			width -= n; | ||||||
|  |  | ||||||
| 			if (!ladjust && width > 0) | 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) | ||||||
| 			{ | 			{ | ||||||
| 				while (width--) OPCHAR (opadc); | 				while (width--) PUT_OCHAR (opadc); | ||||||
| 			} | 			} | ||||||
| 			while (n--) OPCHAR(*osp++); | 			while (n--) PUT_OCHAR(*osp++); | ||||||
| 			if (ladjust && width > 0) | 			if ((flagc & FLAGC_LEFTADJ) && width > 0) | ||||||
| 			{ | 			{ | ||||||
| 				while (width--) OPCHAR (opadc); | 				while (width--) PUT_OCHAR (opadc); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| @ -391,46 +444,71 @@ number: | |||||||
| 				num = -(qse_intmax_t)num; | 				num = -(qse_intmax_t)num; | ||||||
| 			} | 			} | ||||||
| 			p = sprintn (nbuf, num, base, &tmp, upper); | 			p = sprintn (nbuf, num, base, &tmp, upper); | ||||||
| 			if (sharpflag && num != 0)  | 			if ((flagc & FLAGC_SHARP) && num != 0)  | ||||||
| 			{ | 			{ | ||||||
| 				if (base == 8) tmp++; | 				if (base == 8) tmp++; | ||||||
| 				else if (base == 16) tmp += 2; | 				else if (base == 16) tmp += 2; | ||||||
| 			} | 			} | ||||||
| 			if (neg) tmp++; | 			if (neg) tmp++; | ||||||
|  | 			else if (flagc & FLAGC_SIGN) tmp++; | ||||||
|  | 			else if (flagc & FLAGC_SPACE) tmp++; | ||||||
|  |  | ||||||
| 			if (!ladjust && padc != T('0') && width && (width -= tmp) > 0) | 			numlen = p - nbuf; | ||||||
|  | 			if ((flagc & FLAGC_DOT) && precision > numlen)  | ||||||
| 			{ | 			{ | ||||||
| 				while (width--) PCHAR(padc); | 				/* extra zeros fro precision specified */ | ||||||
|  | 				tmp += (precision - numlen); | ||||||
| 			} | 			} | ||||||
| 			if (neg) PCHAR(T('-')); |  | ||||||
|  |  | ||||||
| 			if (sharpflag && num != 0)  | 			if (!(flagc & FLAGC_LEFTADJ) && !(flagc & FLAGC_ZEROPAD) && width > 0 && (width -= tmp) > 0) | ||||||
| 			{ | 			{ | ||||||
| 				if (base == 8) { | 				while (width--) PUT_CHAR(padc); | ||||||
| 					PCHAR(T('0')); | 			} | ||||||
|  |  | ||||||
|  | 			if (neg) PUT_CHAR(T('-')); | ||||||
|  | 			else if (flagc & FLAGC_SIGN) PUT_CHAR(T('+')); | ||||||
|  | 			else if (flagc & FLAGC_SPACE) PUT_CHAR(T(' ')); | ||||||
|  |  | ||||||
|  | 			if ((flagc & FLAGC_SHARP) && num != 0)  | ||||||
|  | 			{ | ||||||
|  | 				if (base == 8)  | ||||||
|  | 				{ | ||||||
|  | 					PUT_CHAR(T('0')); | ||||||
| 				}  | 				}  | ||||||
| 				else if (base == 16)  | 				else if (base == 16)  | ||||||
| 				{ | 				{ | ||||||
| 					PCHAR(T('0')); | 					PUT_CHAR(T('0')); | ||||||
| 					PCHAR(T('x')); | 					PUT_CHAR(T('x')); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if (!ladjust && width && (width -= tmp) > 0) |  | ||||||
|  | 			if ((flagc & FLAGC_DOT) && precision > numlen) | ||||||
| 			{ | 			{ | ||||||
| 				while (width--) PCHAR(padc); | 				/* extra zeros for precision specified */ | ||||||
|  | 				while (numlen < precision)  | ||||||
|  | 				{ | ||||||
|  | 					PUT_CHAR (T('0')); | ||||||
|  | 					numlen++; | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			while (*p) PCHAR(*p--); | 			if (!(flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0) | ||||||
|  |  | ||||||
| 			if (ladjust && width && (width -= tmp) > 0) |  | ||||||
| 			{ | 			{ | ||||||
| 				while (width--) PCHAR(padc); | 				while (width-- > 0) PUT_CHAR (padc); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			while (*p) PUT_CHAR(*p--); /* output actual digits */ | ||||||
|  |  | ||||||
|  | 			if ((flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0) | ||||||
|  | 			{ | ||||||
|  | 				while (width-- > 0) PUT_CHAR (padc); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		default: | 		default: | ||||||
| 			while (percent < fmt) PCHAR(*percent++); | invalid_format: | ||||||
|  | 			while (percent < fmt) PUT_CHAR(*percent++); | ||||||
| 			/* | 			/* | ||||||
| 			 * Since we ignore an formatting argument it is no | 			 * Since we ignore an formatting argument it is no | ||||||
| 			 * longer safe to obey the remaining formatting | 			 * longer safe to obey the remaining formatting | ||||||
| @ -442,6 +520,6 @@ number: | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| #undef PCHAR | #undef PUT_CHAR | ||||||
| #undef OPCHAR | #undef PUT_OCHAR | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user