added QSE_FMTINTMAX_ZEROLEAD.
changed awk printf to use qse_fmtintmax for integer printing. added 'b' and 'B' for awk printf
This commit is contained in:
		| @ -34,27 +34,33 @@ | ||||
|  */ | ||||
| enum qse_fmtintmax_flag_t | ||||
| { | ||||
| 	/* Use lower 6 bits to represent base between 2 and 36 inclusive. | ||||
| 	 * Upper bits are used for these flag options */ | ||||
|  | ||||
| 	/** Don't truncate if the buffer is not large enough */ | ||||
| 	QSE_FMTINTMAX_NOTRUNC = (0x100 << 0), | ||||
| 	QSE_FMTINTMAX_NOTRUNC = (0x40 << 0), | ||||
| 	/** Don't append a terminating null */ | ||||
| 	QSE_FMTINTMAX_NONULL = (0x100 << 1), | ||||
| 	QSE_FMTINTMAX_NONULL = (0x40 << 1), | ||||
| 	/** Produce no digit for a value of zero  */ | ||||
| 	QSE_FMTINTMAX_NOZERO = (0x100 << 2), | ||||
| 	QSE_FMTINTMAX_NOZERO = (0x40 << 2), | ||||
| 	/** Produce a leading zero for a non-zero value */ | ||||
| 	QSE_FMTINTMAX_ZEROLEAD = (0x40 << 3), | ||||
| 	/** Use uppercase letters for alphabetic digits */ | ||||
| 	QSE_FMTINTMAX_UPPERCASE = (0x100 << 3), | ||||
| 	QSE_FMTINTMAX_UPPERCASE = (0x40 << 4), | ||||
| 	/** Insert a plus sign for a positive integer including 0 */ | ||||
| 	QSE_FMTINTMAX_PLUSSIGN = (0x100 << 4), | ||||
| 	QSE_FMTINTMAX_PLUSSIGN = (0x40 << 5), | ||||
| 	/** Insert a space for a positive integer including 0 */ | ||||
| 	QSE_FMTINTMAX_EMPTYSIGN = (0x100 << 5), | ||||
| 	QSE_FMTINTMAX_EMPTYSIGN = (0x40 << 6), | ||||
| 	/** Fill the right part of the string */ | ||||
| 	QSE_FMTINTMAX_FILLRIGHT = (0x100 << 6), | ||||
| 	QSE_FMTINTMAX_FILLRIGHT = (0x40 << 7), | ||||
| 	/** Fill between the sign chacter and the digit part */ | ||||
| 	QSE_FMTINTMAX_FILLCENTER = (0x100 << 7) | ||||
| 	QSE_FMTINTMAX_FILLCENTER = (0x40 << 8) | ||||
| }; | ||||
|  | ||||
| #define QSE_FMTINTMAX_NOTRUNC         QSE_FMTINTMAX_NOTRUNC | ||||
| #define QSE_FMTINTMAX_NONULL          QSE_FMTINTMAX_NONULL | ||||
| #define QSE_FMTINTMAX_NOZERO          QSE_FMTINTMAX_NOZERO | ||||
| #define QSE_FMTINTMAX_ZEROLEAD        QSE_FMTINTMAX_ZEROLEAD | ||||
| #define QSE_FMTINTMAX_UPPERCASE       QSE_FMTINTMAX_UPPERCASE | ||||
| #define QSE_FMTINTMAX_PLUSSIGN        QSE_FMTINTMAX_PLUSSIGN | ||||
| #define QSE_FMTINTMAX_EMPTYSIGN       QSE_FMTINTMAX_EMPTYSIGN | ||||
| @ -64,6 +70,7 @@ enum qse_fmtintmax_flag_t | ||||
| #define QSE_FMTINTMAXTOMBS_NOTRUNC    QSE_FMTINTMAX_NOTRUNC | ||||
| #define QSE_FMTINTMAXTOMBS_NONULL     QSE_FMTINTMAX_NONULL | ||||
| #define QSE_FMTINTMAXTOMBS_NOZERO     QSE_FMTINTMAX_NOZERO | ||||
| #define QSE_FMTINTMAXTOMBS_ZEROLEAD   QSE_FMTINTMAX_ZEROLEAD | ||||
| #define QSE_FMTINTMAXTOMBS_UPPERCASE  QSE_FMTINTMAX_UPPERCASE | ||||
| #define QSE_FMTINTMAXTOMBS_PLUSSIGN   QSE_FMTINTMAX_PLUSSIGN | ||||
| #define QSE_FMTINTMAXTOMBS_EMPTYSIGN  QSE_FMTINTMAX_EMPTYSIGN | ||||
| @ -73,6 +80,7 @@ enum qse_fmtintmax_flag_t | ||||
| #define QSE_FMTINTMAXTOWCS_NOTRUNC    QSE_FMTINTMAX_NOTRUNC | ||||
| #define QSE_FMTINTMAXTOWCS_NONULL     QSE_FMTINTMAX_NONULL | ||||
| #define QSE_FMTINTMAXTOWCS_NOZERO     QSE_FMTINTMAX_NOZERO | ||||
| #define QSE_FMTINTMAXTOWCS_ZEROLEAD   QSE_FMTINTMAX_ZEROLEAD | ||||
| #define QSE_FMTINTMAXTOWCS_UPPERCASE  QSE_FMTINTMAX_UPPERCASE | ||||
| #define QSE_FMTINTMAXTOWCS_PLUSSIGN   QSE_FMTINTMAX_PLUSSIGN | ||||
| #define QSE_FMTINTMAXTOWCS_EMPTYSIGN  QSE_FMTINTMAX_EMPTYSIGN | ||||
|  | ||||
| @ -6782,17 +6782,6 @@ qse_char_t* qse_awk_rtx_format ( | ||||
| 		} | ||||
|  | ||||
| 		/* handle flags */ | ||||
| #if 0 | ||||
| 		while (i < fmt_len && | ||||
| 		       (fmt[i] == QSE_T(' ') || fmt[i] == QSE_T('#') || | ||||
| 		        fmt[i] == QSE_T('0') || fmt[i] == QSE_T('+') || | ||||
| 		        fmt[i] == QSE_T('-'))) | ||||
| 		{ | ||||
| 			if (fmt[i] == QSE_T('-')) minus = 1; | ||||
| 			FMT_CHAR (fmt[i]); i++; | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 		flags = 0; | ||||
| 		while (i < fmt_len) | ||||
| 		{ | ||||
| @ -6923,12 +6912,19 @@ wp_mod_main: | ||||
|  | ||||
| 		if (fmt[i] == QSE_T('d') || fmt[i] == QSE_T('i') ||  | ||||
| 		    fmt[i] == QSE_T('x') || fmt[i] == QSE_T('X') || | ||||
| 		    fmt[i] == QSE_T('b') || fmt[i] == QSE_T('B') || | ||||
| 		    fmt[i] == QSE_T('o')) | ||||
| 		{ | ||||
| 			qse_awk_val_t* v; | ||||
| 			qse_long_t l; | ||||
| 			int n; | ||||
|  | ||||
| 			int fmt_flags; | ||||
| 			int fmt_uint = 0; | ||||
| 			int fmt_width; | ||||
| 			qse_char_t fmt_fill = QSE_T('\0'); | ||||
| 			const qse_char_t* fmt_prefix = QSE_NULL; | ||||
|  | ||||
| 			if (args == QSE_NULL) | ||||
| 			{ | ||||
| 				if (stack_arg_idx >= nargs_on_stack) | ||||
| @ -6961,15 +6957,6 @@ wp_mod_main: | ||||
| 			qse_awk_rtx_refdownval (rtx, v); | ||||
| 			if (n <= -1) return QSE_NULL;  | ||||
|  | ||||
| #if 0 | ||||
| /* TODO: finish this part... replace sprintf */ | ||||
| { | ||||
| int fmt_flags; | ||||
| int fmt_uint = 0; | ||||
| qse_char_t fmt_fill = QSE_T('\0'); | ||||
| const qse_char_t* fmt_prefix = QSE_NULL; | ||||
|  | ||||
| // TODO: WP_WIDTH... | ||||
| 			fmt_flags = QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NONULL; | ||||
|  | ||||
| 			if (l == 0 && wp[WP_PRECISION] == 0) | ||||
| @ -6979,30 +6966,68 @@ const qse_char_t* fmt_prefix = QSE_NULL; | ||||
| 				fmt_flags |= QSE_FMTINTMAX_NOZERO; | ||||
| 			} | ||||
|  | ||||
| 			if ((flags & FLAG_ZERO) &&  | ||||
| 			    wp[WP_PRECISION] == -1 &&  | ||||
| 			    !(flag & FLAG_MINUS))  | ||||
| 			if (wp[WP_WIDTH] != -1) | ||||
| 			{ | ||||
| 				/* if precision is set or the minum flag is set, | ||||
| 				   the zero flag is not honored */ | ||||
| 				fmt_fill = QSE_T('0'); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| /* minus is left justificatin. | ||||
| meaningful iif width is set */ | ||||
| 				if (!(flags & FLAG_MINUS))  | ||||
| 					fmt_flags |= QSE_FMTINTMAX_FILLCENTER; | ||||
| 				QSE_ASSERTX (wp[WP_WIDTH] > 0, "Width must be greater than 0 if specified");  | ||||
|  | ||||
| 				/* justification when width is specified. */ | ||||
| 				if (flags & FLAG_ZERO) | ||||
| 				{ | ||||
| 					if (flags & FLAG_MINUS) | ||||
| 					{ | ||||
| 						 /* FLAG_MINUS wins if both FLAG_ZERO  | ||||
| 						  * and FLAG_MINUS are specified. */ | ||||
| 						fmt_fill = QSE_T(' '); | ||||
| 						if (flags & FLAG_MINUS) | ||||
| 						{ | ||||
| 							/* left justification. need to fill the right side */ | ||||
| 							fmt_flags |= QSE_FMTINTMAX_FILLRIGHT; | ||||
| 						} | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						if (wp[WP_PRECISION] == -1) | ||||
| 						{ | ||||
| 							/* precision not specified.  | ||||
| 							 * FLAG_ZERO can take effect */ | ||||
| 							fmt_fill = QSE_T('0'); | ||||
| 							fmt_flags |= QSE_FMTINTMAX_FILLCENTER; | ||||
| 						} | ||||
| 						else | ||||
| 						{ | ||||
| 							fmt_fill = QSE_T(' '); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					fmt_fill = QSE_T(' '); | ||||
| 					if (flags & FLAG_MINUS) | ||||
| 					{ | ||||
| 						/* left justification. need to fill the right side */ | ||||
| 						fmt_flags |= QSE_FMTINTMAX_FILLRIGHT; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			switch (fmt[i]) | ||||
| 			{ | ||||
| 				case QSE_T('B'): | ||||
| 				case QSE_T('b'): | ||||
| 					fmt_flags |= 2; | ||||
| 					fmt_uint = 1; | ||||
| 					if (l && (flags & FLAG_HASH))  | ||||
| 					{ | ||||
| 						/* A nonzero value is prefixed with 0b */ | ||||
| 						fmt_prefix = QSE_T("0b"); | ||||
| 					} | ||||
| 					break; | ||||
|  | ||||
| 				case QSE_T('X'): | ||||
| 					fmt_flags |= QSE_FMTINTMAX_UPPERCASE; | ||||
| 				case QSE_T('x'): | ||||
| 					fmt_flags |= 16; | ||||
| 					fmt_uint = 1; | ||||
|  | ||||
| 					if (l && (flags & FLAG_HASH))  | ||||
| 					{ | ||||
| 						/* A nonzero value is prefixed with 0x */ | ||||
| @ -7011,15 +7036,15 @@ meaningful iif width is set */ | ||||
| 					break; | ||||
|  | ||||
| 				case QSE_T('o'): | ||||
| 					fmt_flags &= ~QSE_FMTINTMAX_NOZERO; /* weird */ | ||||
| 					fmt_flags |= 8; | ||||
| 					fmt_uint = 1; | ||||
| 					if (l && (flags & FLAG_HASH))  | ||||
| 					if (flags & FLAG_HASH) | ||||
| 					{ | ||||
|                     		/* The precision is increased  | ||||
| 						   (only when necessary) | ||||
|                     		   to force a zero as the first digit. */ | ||||
| 						fmt_prefix = QSE_T("0"); | ||||
| 						/* Force a leading zero digit including zero. | ||||
| 						 * 0 with FLAG_HASH and precision 0 still emits '0'. | ||||
| 						 * On the contrary, 'X' and 'x' emit no digits | ||||
| 						 * for 0 with FLAG_HASH and precision 0. */ | ||||
| 						fmt_flags |= QSE_FMTINTMAX_ZEROLEAD; | ||||
| 					} | ||||
| 					break; | ||||
| 	 | ||||
| @ -7032,6 +7057,15 @@ meaningful iif width is set */ | ||||
| 					break; | ||||
| 			} | ||||
|  | ||||
|  | ||||
| 			if (wp[WP_WIDTH] > 0) | ||||
| 			{ | ||||
| 				if (wp[WP_WIDTH] > rtx->format.tmp.len) | ||||
| 					GROW_WITH_INC (&rtx->format.tmp, wp[WP_WIDTH] - rtx->format.tmp.len); | ||||
| 				fmt_width = wp[WP_WIDTH]; | ||||
| 			} | ||||
| 			else fmt_width = rtx->format.tmp.len; | ||||
| 			 | ||||
| 			do | ||||
| 			{ | ||||
| 				if (fmt_uint) | ||||
| @ -7047,14 +7081,13 @@ meaningful iif width is set */ | ||||
| 					 * each type respectively . | ||||
| 					 *     -1 - 0xFFFFFFFF (qse_long_t) | ||||
| 					 *     -1 - 0xFFFFFFFFFFFFFFFF (qse_uintmax_t) | ||||
| 					 *  | ||||
| 					 * Implicit typecasting of -1 from qse_long_t to | ||||
| 					 * to qse_uintmax_t results in 0xFFFFFFFFFFFFFFFF, | ||||
| 					 * though 0xFFFFFFF is expected in hexadecimal. | ||||
| 					 */ | ||||
| 					n = qse_fmtuintmax ( | ||||
| 						rtx->format.tmp.ptr, | ||||
| 						rtx->format.tmp.len, | ||||
| 						fmt_width, | ||||
| 						(qse_ulong_t)l,  | ||||
| 						fmt_flags, | ||||
| 						wp[WP_PRECISION], | ||||
| @ -7066,7 +7099,7 @@ meaningful iif width is set */ | ||||
| 				{ | ||||
| 					n = qse_fmtintmax ( | ||||
| 						rtx->format.tmp.ptr, | ||||
| 						rtx->format.tmp.len, | ||||
| 						fmt_width, | ||||
| 						l, | ||||
| 						fmt_flags, | ||||
| 						wp[WP_PRECISION], | ||||
| @ -7076,9 +7109,9 @@ meaningful iif width is set */ | ||||
| 				} | ||||
| 				if (n <= -1) | ||||
| 				{ | ||||
| 					/* -n is the number of characters required | ||||
| 					 * including terminating null  */ | ||||
| 					/* -n is the number of characters required */ | ||||
| 					GROW_WITH_INC (&rtx->format.tmp, -n); | ||||
| 					fmt_width = -n; | ||||
| 					continue; | ||||
| 				} | ||||
|  | ||||
| @ -7087,58 +7120,6 @@ meaningful iif width is set */ | ||||
| 			while (1); | ||||
|  | ||||
| 			OUT_STR (rtx->format.tmp.ptr, n); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 1 | ||||
| 		#if QSE_SIZEOF_LONG_LONG > 0 | ||||
| 			FMT_CHAR (QSE_T('l')); | ||||
| 			FMT_CHAR (QSE_T('l')); | ||||
| 			FMT_CHAR (fmt[i]); | ||||
| 		#elif QSE_SIZEOF___INT64 > 0 | ||||
| 			FMT_CHAR (QSE_T('I')); | ||||
| 			FMT_CHAR (QSE_T('6')); | ||||
| 			FMT_CHAR (QSE_T('4')); | ||||
| 			FMT_CHAR (fmt[i]); | ||||
| 		#elif QSE_SIZEOF_LONG > 0 | ||||
| 			FMT_CHAR (QSE_T('l')); | ||||
| 			FMT_CHAR (fmt[i]); | ||||
| 		#elif QSE_SIZEOF_INT > 0 | ||||
| 			FMT_CHAR (fmt[i]); | ||||
| 		#else | ||||
| 			#error unsupported integer size | ||||
| 		#endif	 | ||||
|  | ||||
| 			do | ||||
| 			{ | ||||
| 				n = rtx->awk->prm.sprintf ( | ||||
| 					rtx->awk, | ||||
| 					rtx->format.tmp.ptr, | ||||
| 					rtx->format.tmp.len, | ||||
| 					QSE_STR_PTR(fbu), | ||||
| 				#if QSE_SIZEOF_LONG_LONG > 0 | ||||
| 					(long long)l | ||||
| 				#elif QSE_SIZEOF___INT64 > 0 | ||||
| 					(__int64)l | ||||
| 				#elif QSE_SIZEOF_LONG > 0 | ||||
| 					(long)l | ||||
| 				#elif QSE_SIZEOF_INT > 0 | ||||
| 					(int)l | ||||
| 				#endif | ||||
| 				); | ||||
| 					 | ||||
| 				if (n == -1) | ||||
| 				{ | ||||
| 					GROW (&rtx->format.tmp); | ||||
| 					continue; | ||||
| 				} | ||||
|  | ||||
| 				break; | ||||
| 			} | ||||
| 			while (1); | ||||
|  | ||||
| 			OUT_STR (rtx->format.tmp.ptr, n); | ||||
| #endif | ||||
| 		} | ||||
| 		else if (fmt[i] == QSE_T('e') || fmt[i] == QSE_T('E') || | ||||
| 		         fmt[i] == QSE_T('g') || fmt[i] == QSE_T('G') || | ||||
| @ -7446,10 +7427,6 @@ meaningful iif width is set */ | ||||
| 		else /*if (fmt[i] == QSE_T('%'))*/ | ||||
| 		{ | ||||
| 			OUT_STR (QSE_STR_PTR(fbu), QSE_STR_LEN(fbu)); | ||||
| 		#if 0 | ||||
| 			for (j = 0; j < QSE_STR_LEN(fbu); j++) | ||||
| 				OUT_CHAR (QSE_STR_CHAR(fbu,j)); | ||||
| 		#endif | ||||
| 			OUT_CHAR (fmt[i]); | ||||
| 		} | ||||
|  | ||||
|  | ||||
| @ -22,43 +22,88 @@ | ||||
| #include <qse/cmn/str.h> | ||||
|  | ||||
| /* ==================== multibyte ===================================== */ | ||||
|  | ||||
| static int fmt_unsigned_to_mbs ( | ||||
| 	qse_mchar_t* buf, int size,  | ||||
| 	qse_uintmax_t value, int base_and_flags, int prec, | ||||
| 	qse_mchar_t fillchar, qse_mchar_t signchar, const qse_mchar_t* prefix) | ||||
| { | ||||
| 	qse_mchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; | ||||
| 	int reslen, base, xsize, reqlen, pflen; | ||||
| 	int reslen, base, fillsize, reqlen, pflen, preczero; | ||||
| 	qse_mchar_t* p, * bp, * be; | ||||
| 	const qse_mchar_t* xbasestr; | ||||
|  | ||||
| 	base = base_and_flags & 0xFF; | ||||
| 	base = base_and_flags & 0x3F; | ||||
| 	if (base < 2 || base > 36) return -1; | ||||
|  | ||||
| 	xbasestr = (base_and_flags & QSE_FMTINTMAXTOMBS_UPPERCASE)? | ||||
| 		QSE_MT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"): | ||||
| 		QSE_MT("0123456789abcdefghijklmnopqrstuvwxyz"); | ||||
|  | ||||
| 	/* store the resulting numeric string into 'tmp' first */ | ||||
| 	p = tmp;  | ||||
| 	do | ||||
| 	{ | ||||
| 		*p++ = xbasestr[value % base]; | ||||
| 		value /= base; | ||||
| 	} | ||||
| 	while (value > 0); | ||||
|  | ||||
| 	/* reslen is the length of the resulting string without padding. */ | ||||
| 	reslen = (int)(p - tmp); | ||||
| 	if ((base_and_flags & QSE_FMTINTMAXTOMBS_NOZERO) && value == 0)  | ||||
| 	{ | ||||
| 		p = tmp;  | ||||
| 		if (base_and_flags & QSE_FMTINTMAXTOMBS_ZEROLEAD)  | ||||
| 		{ | ||||
| 			/* NOZERO emits no digit, ZEROLEAD emits 1 digit. | ||||
| 			 * so it emits '0' */ | ||||
| 			reslen = 1; | ||||
| 			preczero = 1; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* since the value is zero, emit no digits */ | ||||
| 			reslen = 0; | ||||
| 			preczero = 0; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* store the resulting numeric string into 'tmp' first */ | ||||
| 		p = tmp;  | ||||
| 		do | ||||
| 		{ | ||||
| 			*p++ = xbasestr[value % base]; | ||||
| 			value /= base; | ||||
| 		} | ||||
| 		while (value > 0); | ||||
|  | ||||
| 		/* reslen is the length of the resulting string without padding. */ | ||||
| 		reslen = (int)(p - tmp); | ||||
| 	 | ||||
| 		/* precision specified the minum number of digits to produce. | ||||
| 		 * so if the precision is larger that the digits produced,  | ||||
| 		 * reslen should be adjusted to precision */ | ||||
| 		if (prec > reslen)  | ||||
| 		{ | ||||
| 			/* if the precision is greater than the actual digits | ||||
| 			 * made from the value, 0 is inserted in front. | ||||
| 			 * ZEROLEAD doesn't have to be handled explicitly | ||||
| 			 * since it's achieved effortlessly */ | ||||
| 			preczero = prec - reslen; | ||||
| 			reslen = prec; | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| 			preczero = 0; | ||||
| 			if (base_and_flags & QSE_FMTINTMAXTOMBS_ZEROLEAD)  | ||||
| 			{ | ||||
| 				preczero++; | ||||
| 				reslen++; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (signchar) reslen++; /* increment reslen for the sign character */ | ||||
| 	if (prefix) | ||||
| 	{ | ||||
| 		/* since the length can be truncated for different type sizes, | ||||
| 		 * don't pass in a very long prefix. */ | ||||
| 		pflen = (int)qse_mbslen(prefix);  | ||||
| 		pflen = (int)qse_mbslen(prefix); | ||||
| 		reslen += pflen; | ||||
| 	} | ||||
|  | ||||
| 	else pflen = 0; | ||||
|  | ||||
| 	/* get the required buffer size for lossless formatting */ | ||||
| 	reqlen = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? reslen: (reslen + 1); | ||||
| @ -69,9 +114,10 @@ static int fmt_unsigned_to_mbs ( | ||||
| 		return -reqlen; | ||||
| 	} | ||||
|  | ||||
| 	xsize = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? size: (size - 1); | ||||
| 	/* get the size to fill with fill characters */ | ||||
| 	fillsize = (base_and_flags & QSE_FMTINTMAXTOMBS_NONULL)? size: (size - 1); | ||||
| 	bp = buf; | ||||
| 	be = buf + xsize; | ||||
| 	be = buf + fillsize; | ||||
|  | ||||
| 	/* fill space */ | ||||
| 	if (fillchar != QSE_MT('\0')) | ||||
| @ -83,14 +129,22 @@ static int fmt_unsigned_to_mbs ( | ||||
|  | ||||
| 			/* copy prefix if necessary */ | ||||
| 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 			/* add 0s for precision */ | ||||
| 			while (preczero > 0 && bp < be)  | ||||
| 			{  | ||||
| 				*bp++ = QSE_MT('0'); | ||||
| 				preczero--;  | ||||
| 			} | ||||
|  | ||||
| 			/* copy the numeric string to the destination buffer */ | ||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | ||||
|  | ||||
| 			/* fill the right side */ | ||||
| 			while (xsize > reslen) | ||||
| 			while (fillsize > reslen) | ||||
| 			{ | ||||
| 				*bp++ = fillchar; | ||||
| 				xsize--; | ||||
| 				fillsize--; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (base_and_flags & QSE_FMTINTMAXTOMBS_FILLCENTER) | ||||
| @ -99,24 +153,32 @@ static int fmt_unsigned_to_mbs ( | ||||
| 			if (signchar && bp < be) *bp++ = signchar; | ||||
|  | ||||
| 			/* fill the left side */ | ||||
| 			while (xsize > reslen) | ||||
| 			while (fillsize > reslen) | ||||
| 			{ | ||||
| 				*bp++ = fillchar; | ||||
| 				xsize--; | ||||
| 				fillsize--; | ||||
| 			} | ||||
|  | ||||
| 			/* copy prefix if necessary */ | ||||
| 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 			/* add 0s for precision */ | ||||
| 			while (preczero > 0 && bp < be)  | ||||
| 			{  | ||||
| 				*bp++ = QSE_MT('0'); | ||||
| 				preczero--;  | ||||
| 			} | ||||
|  | ||||
| 			/* copy the numeric string to the destination buffer */ | ||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* fill the left side */ | ||||
| 			while (xsize > reslen) | ||||
| 			while (fillsize > reslen) | ||||
| 			{ | ||||
| 				*bp++ = fillchar; | ||||
| 				xsize--; | ||||
| 				fillsize--; | ||||
| 			} | ||||
|  | ||||
| 			/* emit sign */ | ||||
| @ -124,6 +186,14 @@ static int fmt_unsigned_to_mbs ( | ||||
|  | ||||
| 			/* copy prefix if necessary */ | ||||
| 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 			/* add 0s for precision */ | ||||
| 			while (preczero > 0 && bp < be)  | ||||
| 			{  | ||||
| 				*bp++ = QSE_MT('0'); | ||||
| 				preczero--;  | ||||
| 			} | ||||
|  | ||||
| 			/* copy the numeric string to the destination buffer */ | ||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | ||||
| 		} | ||||
| @ -135,6 +205,14 @@ static int fmt_unsigned_to_mbs ( | ||||
|  | ||||
| 		/* copy prefix if necessary */ | ||||
| 		if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 		/* add 0s for precision */ | ||||
| 		while (preczero > 0 && bp < be)  | ||||
| 		{  | ||||
| 			*bp++ = QSE_MT('0'); | ||||
| 			preczero--;  | ||||
| 		} | ||||
|  | ||||
| 		/* copy the numeric string to the destination buffer */ | ||||
| 		while (p > tmp && bp < be) *bp++ = *--p; | ||||
| 	} | ||||
| @ -210,51 +288,71 @@ static int fmt_unsigned_to_wcs ( | ||||
| 	qse_wchar_t fillchar, qse_wchar_t signchar, const qse_wchar_t* prefix) | ||||
| { | ||||
| 	qse_wchar_t tmp[(QSE_SIZEOF(qse_uintmax_t) * 8)]; | ||||
| 	int reslen, base, xsize, reqlen, pflen, preczero; | ||||
| 	int reslen, base, fillsize, reqlen, pflen, preczero; | ||||
| 	qse_wchar_t* p, * bp, * be; | ||||
| 	const qse_wchar_t* xbasestr; | ||||
|  | ||||
| 	base = base_and_flags & 0xFF; | ||||
| 	base = base_and_flags & 0x3F; | ||||
| 	if (base < 2 || base > 36) return -1; | ||||
|  | ||||
| 	xbasestr = (base_and_flags & QSE_FMTINTMAXTOWCS_UPPERCASE)? | ||||
| 		QSE_WT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"): | ||||
| 		QSE_WT("0123456789abcdefghijklmnopqrstuvwxyz"); | ||||
|  | ||||
| /*if (prec == 0 && value == 0) */ | ||||
| if ((base_and_flags & QSE_FMTINTMAXTOWCS_NOZERO) && value == 0)  | ||||
| { | ||||
| 	reslen = 0; | ||||
| 	preczero = 0; | ||||
| 	p = tmp;  | ||||
| } | ||||
| else | ||||
| { | ||||
| 	/* store the resulting numeric string into 'tmp' first */ | ||||
| 	p = tmp;  | ||||
| 	do | ||||
| 	{ | ||||
| 		*p++ = xbasestr[value % base]; | ||||
| 		value /= base; | ||||
| 	} | ||||
| 	while (value > 0); | ||||
|  | ||||
| 	/* reslen is the length of the resulting string without padding. */ | ||||
| 	reslen = (int)(p - tmp); | ||||
| 	if ((base_and_flags & QSE_FMTINTMAXTOWCS_NOZERO) && value == 0)  | ||||
| 	{ | ||||
| 		p = tmp;  | ||||
| 		if (base_and_flags & QSE_FMTINTMAXTOWCS_ZEROLEAD)  | ||||
| 		{ | ||||
| 			/* NOZERO emits no digit, ZEROLEAD emits 1 digit. | ||||
| 			 * so it emits '0' */ | ||||
| 			reslen = 1; | ||||
| 			preczero = 1; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			/* since the value is zero, emit no digits */ | ||||
| 			reslen = 0; | ||||
| 			preczero = 0; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* store the resulting numeric string into 'tmp' first */ | ||||
| 		p = tmp;  | ||||
| 		do | ||||
| 		{ | ||||
| 			*p++ = xbasestr[value % base]; | ||||
| 			value /= base; | ||||
| 		} | ||||
| 		while (value > 0); | ||||
|  | ||||
| 	/* precision specified the minum number of digits to produce. | ||||
| 	 * so if the precision is larger that the digits produced,  | ||||
| 	 * reslen should be adjusted to precision */ | ||||
| 	if (prec > reslen)  | ||||
| 	{ | ||||
| 		preczero = prec - reslen; | ||||
| 		reslen = prec; | ||||
| 		/* reslen is the length of the resulting string without padding. */ | ||||
| 		reslen = (int)(p - tmp); | ||||
| 	 | ||||
| 		/* precision specified the minum number of digits to produce. | ||||
| 		 * so if the precision is larger that the digits produced,  | ||||
| 		 * reslen should be adjusted to precision */ | ||||
| 		if (prec > reslen)  | ||||
| 		{ | ||||
| 			/* if the precision is greater than the actual digits | ||||
| 			 * made from the value, 0 is inserted in front. | ||||
| 			 * ZEROLEAD doesn't have to be handled explicitly | ||||
| 			 * since it's achieved effortlessly */ | ||||
| 			preczero = prec - reslen; | ||||
| 			reslen = prec; | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| 			preczero = 0; | ||||
| 			if (base_and_flags & QSE_FMTINTMAXTOWCS_ZEROLEAD)  | ||||
| 			{ | ||||
| 				preczero++; | ||||
| 				reslen++; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	else  | ||||
| 	{ | ||||
| 		preczero = 0; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 	if (signchar) reslen++; /* increment reslen for the sign character */ | ||||
| 	if (prefix) | ||||
| @ -276,9 +374,9 @@ else | ||||
| 	} | ||||
|  | ||||
| 	/* get the size to fill with fill characters */ | ||||
| 	xsize = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? size: (size - 1); | ||||
| 	fillsize = (base_and_flags & QSE_FMTINTMAXTOWCS_NONULL)? size: (size - 1); | ||||
| 	bp = buf; | ||||
| 	be = buf + xsize; | ||||
| 	be = buf + fillsize; | ||||
|  | ||||
| 	/* fill space */ | ||||
| 	if (fillchar != QSE_WT('\0')) | ||||
| @ -289,19 +387,12 @@ else | ||||
| 			if (signchar && bp < be) *bp++ = signchar; | ||||
|  | ||||
| 			/* copy prefix if necessary */ | ||||
| 			if (prefix)  | ||||
| 			{ | ||||
| /*if (preczero > 0 && pflen == 1 && prefix[0] == QSE_WT('0')) goto skip; */ | ||||
| if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| { | ||||
| 				while (*prefix && bp < be) *bp++ = *prefix++; | ||||
| } | ||||
| 			} | ||||
| 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 			/* add 0s for precision */ | ||||
| 			while (preczero > 0 && bp < be)  | ||||
| 			{  | ||||
| 				*bp++ = QSE_T('0'); | ||||
| 				*bp++ = QSE_WT('0'); | ||||
| 				preczero--;  | ||||
| 			} | ||||
|  | ||||
| @ -309,10 +400,10 @@ if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| 			while (p > tmp && bp < be) *bp++ = *--p; | ||||
|  | ||||
| 			/* fill the right side */ | ||||
| 			while (xsize > reslen) | ||||
| 			while (fillsize > reslen) | ||||
| 			{ | ||||
| 				*bp++ = fillchar; | ||||
| 				xsize--; | ||||
| 				fillsize--; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (base_and_flags & QSE_FMTINTMAXTOWCS_FILLCENTER) | ||||
| @ -321,26 +412,19 @@ if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| 			if (signchar && bp < be) *bp++ = signchar; | ||||
|  | ||||
| 			/* fill the left side */ | ||||
| 			while (xsize > reslen) | ||||
| 			while (fillsize > reslen) | ||||
| 			{ | ||||
| 				*bp++ = fillchar; | ||||
| 				xsize--; | ||||
| 				fillsize--; | ||||
| 			} | ||||
|  | ||||
| 			/* copy prefix if necessary */ | ||||
| 			if (prefix)  | ||||
| 			{ | ||||
| /*if (preczero > 0 && pflen == 1 && prefix[0] == QSE_WT('0')) goto skip; */ | ||||
| if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| { | ||||
| 				while (*prefix && bp < be) *bp++ = *prefix++; | ||||
| } | ||||
| 			} | ||||
| 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 			/* add 0s for precision */ | ||||
| 			while (preczero > 0 && bp < be)  | ||||
| 			{  | ||||
| 				*bp++ = QSE_T('0'); | ||||
| 				*bp++ = QSE_WT('0'); | ||||
| 				preczero--;  | ||||
| 			} | ||||
|  | ||||
| @ -350,29 +434,22 @@ if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| 		else | ||||
| 		{ | ||||
| 			/* fill the left side */ | ||||
| 			while (xsize > reslen) | ||||
| 			while (fillsize > reslen) | ||||
| 			{ | ||||
| 				*bp++ = fillchar; | ||||
| 				xsize--; | ||||
| 				fillsize--; | ||||
| 			} | ||||
|  | ||||
| 			/* emit sign */ | ||||
| 			if (signchar && bp < be) *bp++ = signchar; | ||||
|  | ||||
| 			/* copy prefix if necessary */ | ||||
| 			if (prefix)  | ||||
| 			{ | ||||
| /*if (preczero > 0 && pflen == 1 && prefix[0] == QSE_WT('0')) goto skip; */ | ||||
| if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| { | ||||
| 				while (*prefix && bp < be) *bp++ = *prefix++; | ||||
| } | ||||
| 			} | ||||
| 			if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 			/* add 0s for precision */ | ||||
| 			while (preczero > 0 && bp < be)  | ||||
| 			{  | ||||
| 				*bp++ = QSE_T('0'); | ||||
| 				*bp++ = QSE_WT('0'); | ||||
| 				preczero--;  | ||||
| 			} | ||||
|  | ||||
| @ -386,18 +463,12 @@ if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| 		if (signchar && bp < be) *bp++ = signchar; | ||||
|  | ||||
| 		/* copy prefix if necessary */ | ||||
| 		if (prefix)  | ||||
| 		{ | ||||
| if (preczero <= 0 || pflen != 1 || prefix[0] != QSE_WT('0')) | ||||
| { | ||||
| 			while (*prefix && bp < be) *bp++ = *prefix++; | ||||
| } | ||||
| 		} | ||||
| 		if (prefix) while (*prefix && bp < be) *bp++ = *prefix++; | ||||
|  | ||||
| 		/* add 0s for precision */ | ||||
| 		while (preczero > 0 && bp < be)  | ||||
| 		{  | ||||
| 			*bp++ = QSE_T('0'); | ||||
| 			*bp++ = QSE_WT('0'); | ||||
| 			preczero--;  | ||||
| 		} | ||||
|  | ||||
|  | ||||
| @ -1958,7 +1958,7 @@ static int comp_cand (qse_lda_t* lda, | ||||
| { | ||||
| 	cand_t* c1 = (cand_t*)dptr1; | ||||
| 	cand_t* c2 = (cand_t*)dptr2; | ||||
| //qse_printf (QSE_T("%p(%d) %p(%d), %p %p, %d %d\n"), c1->node,c1->node->id, c2->node,c1->node->id, c1->mptr, c2->mptr, (int)c1->occ, (int)c2->occ); | ||||
| /*qse_printf (QSE_T("%p(%d) %p(%d), %p %p, %d %d\n"), c1->node,c1->node->id, c2->node,c1->node->id, c1->mptr, c2->mptr, (int)c1->occ, (int)c2->occ);*/ | ||||
| 	return (c1->node == c2->node &&  | ||||
| 	        c1->mptr == c2->mptr && | ||||
| 	        c1->occ == c2->occ)? 0: 1; | ||||
|  | ||||
| @ -75,9 +75,9 @@ qse_size_t qse_mbsfncpy ( | ||||
| 	{ | ||||
| 		if (*f == QSE_MT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_MT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_MT('$')) | ||||
| @ -133,9 +133,9 @@ qse_size_t qse_mbsxfcpy ( | ||||
| 	{ | ||||
| 		if (*f == QSE_MT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_MT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_MT('$')) | ||||
| @ -195,9 +195,9 @@ qse_size_t qse_mbsxfncpy ( | ||||
| 	{ | ||||
| 		if (*f == QSE_MT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_MT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_MT('$')) | ||||
| @ -300,9 +300,9 @@ qse_size_t qse_wcsfncpy ( | ||||
| 	{ | ||||
| 		if (*f == QSE_WT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_WT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_WT('$')) | ||||
| @ -358,9 +358,9 @@ qse_size_t qse_wcsxfcpy ( | ||||
| 	{ | ||||
| 		if (*f == QSE_WT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_WT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_WT('$')) | ||||
| @ -420,9 +420,9 @@ qse_size_t qse_wcsxfncpy ( | ||||
| 	{ | ||||
| 		if (*f == QSE_WT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_WT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_WT('$')) | ||||
|  | ||||
| @ -34,9 +34,9 @@ qse_size_t qse_mbsxsubst ( | ||||
| 	{ | ||||
| 		if (*f == QSE_MT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_MT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_MT('$')) | ||||
| @ -96,9 +96,9 @@ qse_size_t qse_wcsxsubst ( | ||||
| 	{ | ||||
| 		if (*f == QSE_WT('\\')) | ||||
| 		{ | ||||
| 			// get the escaped character and treat it normally. | ||||
| 			// if the escaper is the last character, treat it  | ||||
| 			// normally also. | ||||
| 			/* get the escaped character and treat it normally. | ||||
| 			 * if the escaper is the last character, treat it  | ||||
| 			 * normally also. */ | ||||
| 			if (f[1] != QSE_WT('\0')) f++; | ||||
| 		} | ||||
| 		else if (*f == QSE_WT('$')) | ||||
|  | ||||
| @ -36,11 +36,11 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | ||||
| 			int n = qse_fmtuintmax (buf, QSE_COUNTOF(buf), num, bases[i] | flags[j], -1, QSE_T('.'), prefix[i]); | ||||
| 			if (n <= -1) | ||||
| 			{ | ||||
| 				qse_printf (QSE_T("%8X => [%4d:%04X] ERROR[%d]\n"), num, bases[i], flags[j],  n); | ||||
| 				qse_printf (QSE_T("%8X => [%4d:%05X] ERROR[%d]\n"), num, bases[i], flags[j],  n); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				qse_printf (QSE_T("%8X => [%4d:%04X] [%.*s][%d]\n"), num, bases[i], flags[j], n, buf, n); | ||||
| 				qse_printf (QSE_T("%8X => [%4d:%05X] [%.*s][%d]\n"), num, bases[i], flags[j], n, buf, n); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -32,11 +32,11 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | ||||
| 				int n = qse_fmtintmax (buf, QSE_COUNTOF(buf), nums[k], bases[i] | flags[j] | QSE_FMTINTMAX_NOTRUNC, -1, QSE_T('.'), prefix[i]); | ||||
| 				if (n <= -1) | ||||
| 				{ | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%04X] ERROR[%d]\n"), (int)nums[k], bases[i], flags[j],  n); | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%05X] ERROR[%d]\n"), (int)nums[k], bases[i], flags[j],  n); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%04X] [%s]\n"), (int)nums[k], bases[i], flags[j],  buf); | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%05X] [%s]\n"), (int)nums[k], bases[i], flags[j],  buf); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @ -53,11 +53,11 @@ static int test_main (int argc, qse_char_t* argv[], qse_char_t* envp[]) | ||||
| 				int n = qse_fmtintmax (buf, QSE_COUNTOF(buf), nums[k], bases[i] | flags[j] | QSE_FMTINTMAX_NOTRUNC | QSE_FMTINTMAX_NOZERO, 0, QSE_T('*'), prefix[i]); | ||||
| 				if (n <= -1) | ||||
| 				{ | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%04X] ERROR[%d]\n"), (int)nums[k], bases[i], flags[j],  n); | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%05X] ERROR[%d]\n"), (int)nums[k], bases[i], flags[j],  n); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%04X] [%s]\n"), (int)nums[k], bases[i], flags[j],  buf); | ||||
| 					qse_printf (QSE_T("%8d => [%4d:%05X] [%s]\n"), (int)nums[k], bases[i], flags[j],  buf); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
		Reference in New Issue
	
	Block a user