fixed a bug in printing a single character when hcl_ooch_t is hcl_bch_t
implemented the primitive printf function partially
This commit is contained in:
		| @ -331,14 +331,18 @@ typedef struct hcl_bcs_t hcl_bcs_t; | |||||||
|  |  | ||||||
| #if defined(HCL_ENABLE_UNICODE) | #if defined(HCL_ENABLE_UNICODE) | ||||||
| 	typedef hcl_uch_t               hcl_ooch_t; | 	typedef hcl_uch_t               hcl_ooch_t; | ||||||
|  | 	typedef hcl_uchu_t              hcl_oochu_t; | ||||||
| 	typedef hcl_uci_t               hcl_ooci_t; | 	typedef hcl_uci_t               hcl_ooci_t; | ||||||
| 	typedef hcl_ucs_t               hcl_oocs_t; | 	typedef hcl_ucs_t               hcl_oocs_t; | ||||||
| #	define HCL_OOCH_IS_UCH | #	define HCL_OOCH_IS_UCH | ||||||
|  | #	define HCL_SIZEOF_OOCH_T HCL_SIZEOF_UCH_T | ||||||
| #else | #else | ||||||
| 	typedef hcl_bch_t               hcl_ooch_t; | 	typedef hcl_bch_t               hcl_ooch_t; | ||||||
|  | 	typedef hcl_bchu_t              hcl_oochu_t; | ||||||
| 	typedef hcl_bci_t               hcl_ooci_t; | 	typedef hcl_bci_t               hcl_ooci_t; | ||||||
| 	typedef hcl_bcs_t               hcl_oocs_t; | 	typedef hcl_bcs_t               hcl_oocs_t; | ||||||
| #	define HCL_OOCH_IS_BCH | #	define HCL_OOCH_IS_BCH | ||||||
|  | #	define HCL_SIZEOF_OOCH_T HCL_SIZEOF_BCH_T | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* ========================================================================= | /* ========================================================================= | ||||||
|  | |||||||
| @ -1720,6 +1720,18 @@ HCL_EXPORT hcl_oop_t hcl_oowtoint ( | |||||||
| 	hcl_oow_t  w | 	hcl_oow_t  w | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | HCL_EXPORT int hcl_inttoooi ( | ||||||
|  | 	hcl_t*     hcl, | ||||||
|  | 	hcl_oop_t  x, | ||||||
|  | 	hcl_ooi_t* i | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | HCL_EXPORT hcl_oop_t hcl_ooitoint ( | ||||||
|  | 	hcl_t*    hcl, | ||||||
|  | 	hcl_ooi_t i | ||||||
|  | ); | ||||||
|  |  | ||||||
| /* ========================================================================= | /* ========================================================================= | ||||||
|  * CONS OBJECT UTILITIES |  * CONS OBJECT UTILITIES | ||||||
|  * ========================================================================= */ |  * ========================================================================= */ | ||||||
|  | |||||||
							
								
								
									
										350
									
								
								hcl/lib/logfmt.c
									
									
									
									
									
								
							
							
						
						
									
										350
									
								
								hcl/lib/logfmt.c
									
									
									
									
									
								
							| @ -723,7 +723,7 @@ void hcl_seterrufmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, va_ | |||||||
|  * SUPPORT FOR THE BUILTIN PRINTF PRIMITIVE FUNCTION |  * SUPPORT FOR THE BUILTIN PRINTF PRIMITIVE FUNCTION | ||||||
|  * -------------------------------------------------------------------------- */ |  * -------------------------------------------------------------------------- */ | ||||||
|  |  | ||||||
| #if 0 | #if 1 | ||||||
| static int put_formatted_chars (hcl_t* hcl, int mask, const hcl_ooch_t ch, hcl_oow_t len) | static int put_formatted_chars (hcl_t* hcl, int mask, const hcl_ooch_t ch, hcl_oow_t len) | ||||||
| { | { | ||||||
| /* TODO: better error handling, buffering. | /* TODO: better error handling, buffering. | ||||||
| @ -791,23 +791,21 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t | |||||||
| 	hcl_oop_char_t fmtoop; | 	hcl_oop_char_t fmtoop; | ||||||
| 	hcl_ooi_t i; | 	hcl_ooi_t i; | ||||||
|  |  | ||||||
| 	const fmtchar_t* percent; | 	//hcl_bch_t nbuf[MAXNBUF], bch; | ||||||
| 	const fmtchar_t* checkpoint; |  | ||||||
| 	hcl_bch_t nbuf[MAXNBUF], bch; |  | ||||||
| 	const hcl_bch_t* nbufp; |  | ||||||
| 	int n, base, neg, sign; | 	int n, base, neg, sign; | ||||||
| 	hcl_ooi_t tmp, width, precision; | 	hcl_ooi_t tmp, width, precision; | ||||||
| 	hcl_ooch_t ch, padc; | 	hcl_ooch_t ch, padc, ooch; | ||||||
| 	fmtchar_t fch; | 	int lm_flag, lm_dflag, flagc; | ||||||
| 	int lm_flag, lm_dflag, flagc, numlen; |  | ||||||
| 	hcl_uintmax_t num = 0; | 	hcl_uintmax_t num = 0; | ||||||
| 	int stop = 0; | 	int stop = 0; | ||||||
|  |  | ||||||
| 	hcl_ooch_t* fmt, * fmtend; | 	hcl_ooch_t* fmt, * fmtend; | ||||||
|  | 	const hcl_ooch_t* checkpoint, * percent; | ||||||
|  |  | ||||||
| 	hcl_bch_t* (*sprintn) (hcl_bch_t* nbuf, hcl_uintmax_t num, int base, hcl_ooi_t* lenp); | 	hcl_oop_t arg; | ||||||
|  | 	hcl_ooi_t argidx = 0; | ||||||
|  |  | ||||||
| 	fmtoop = (hcl_oop_char_t)HCL_STACK_GETARG(hcl, nargs, 0); | 	fmtoop = (hcl_oop_char_t)HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; | ||||||
| 	HCL_ASSERT (hcl, HCL_IS_STRING(hcl, fmtoop)); | 	HCL_ASSERT (hcl, HCL_IS_STRING(hcl, fmtoop)); | ||||||
|  |  | ||||||
| 	fmt = HCL_OBJ_GET_CHAR_SLOT(fmtoop); | 	fmt = HCL_OBJ_GET_CHAR_SLOT(fmtoop); | ||||||
| @ -835,14 +833,14 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t | |||||||
| 		neg = 0; sign = 0; | 		neg = 0; sign = 0; | ||||||
|  |  | ||||||
| 		lm_flag = 0; lm_dflag = 0; flagc = 0;  | 		lm_flag = 0; lm_dflag = 0; flagc = 0;  | ||||||
| 		sprintn = sprintn_lower; | 		//sprintn = sprintn_lower; | ||||||
|  |  | ||||||
| reswitch: | reswitch: | ||||||
| 		switch (ch = *fmt++)  | 		switch (ch = *fmt++)  | ||||||
| 		{ | 		{ | ||||||
| 		case '%': /* %% */ | 		case '%': /* %% */ | ||||||
| 			bch = ch; | 			ooch = ch; | ||||||
| 			goto print_lowercase_c; | 			goto print_char; | ||||||
|  |  | ||||||
| 		/* flag characters */ | 		/* flag characters */ | ||||||
| 		case '.': | 		case '.': | ||||||
| @ -889,7 +887,8 @@ reswitch: | |||||||
| 				if (flagc & (FLAGC_STAR2 | FLAGC_PRECISION)) goto invalid_format; | 				if (flagc & (FLAGC_STAR2 | FLAGC_PRECISION)) goto invalid_format; | ||||||
| 				flagc |= FLAGC_STAR2; | 				flagc |= FLAGC_STAR2; | ||||||
|  |  | ||||||
| 				precision = va_arg(ap, hcl_ooi_t); /* this deviates from the standard printf that accepts 'int' */ | 				arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; | ||||||
|  | 				if (hcl_inttoooi(hcl, arg, &precision) <= -1) goto oops; | ||||||
| 				if (precision < 0)  | 				if (precision < 0)  | ||||||
| 				{ | 				{ | ||||||
| 					/* if precision is less than 0,  | 					/* if precision is less than 0,  | ||||||
| @ -903,7 +902,8 @@ reswitch: | |||||||
| 				if (flagc & (FLAGC_STAR1 | FLAGC_WIDTH)) goto invalid_format; | 				if (flagc & (FLAGC_STAR1 | FLAGC_WIDTH)) goto invalid_format; | ||||||
| 				flagc |= FLAGC_STAR1; | 				flagc |= FLAGC_STAR1; | ||||||
|  |  | ||||||
| 				width = va_arg(ap, hcl_ooi_t); /* it deviates from the standard printf that accepts 'int' */ | 				arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; | ||||||
|  | 				if (hcl_inttoooi(hcl, arg, &width) <= -1) goto oops; | ||||||
| 				if (width < 0)  | 				if (width < 0)  | ||||||
| 				{ | 				{ | ||||||
| 					/* | 					/* | ||||||
| @ -973,79 +973,43 @@ reswitch: | |||||||
| 			break; | 			break; | ||||||
| #endif | #endif | ||||||
|   |   | ||||||
| 		/* signed integer conversions */ | 		/* integer conversions */ | ||||||
| 		case 'd': | 		case 'd': | ||||||
| 		case 'i': /* signed conversion */ | 		case 'i': /* signed conversion */ | ||||||
| 			base = 10; | 			base = 10; | ||||||
| 			sign = 1; | 			sign = 1; | ||||||
| 			goto handle_sign; | 			goto number; | ||||||
| 		/* end of signed integer conversions */ |  | ||||||
|  |  | ||||||
| 		/* unsigned integer conversions */ |  | ||||||
| 		case 'o':  | 		case 'o':  | ||||||
| 			base = 8; | 			base = 8; | ||||||
| 			goto handle_nosign; | 			goto number; | ||||||
| 		case 'u': | 		case 'u': | ||||||
| 			base = 10; | 			base = 10; | ||||||
| 			goto handle_nosign; | 			goto number; | ||||||
| 		case 'X': | 		case 'X': | ||||||
| 			sprintn = sprintn_upper; | 			//sprintn = sprintn_upper; | ||||||
| 		case 'x': | 		case 'x': | ||||||
| 			base = 16; | 			base = 16; | ||||||
| 			goto handle_nosign; | 			goto number; | ||||||
| 		case 'b': | 		case 'b': | ||||||
| 			base = 2; | 			base = 2; | ||||||
| 			goto handle_nosign; |  | ||||||
| 		/* end of unsigned integer conversions */ |  | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| 		case 'p': /* pointer */ |  | ||||||
| 			base = 16; |  | ||||||
|  |  | ||||||
| 			if (width == 0) flagc |= FLAGC_SHARP; |  | ||||||
| 			else flagc &= ~FLAGC_SHARP; |  | ||||||
|  |  | ||||||
| 			num = (hcl_uintptr_t)va_arg(ap, void*); |  | ||||||
| 			goto number; | 			goto number; | ||||||
| #endif | 		/* end of integer conversions */ | ||||||
|  |  | ||||||
| 		case 'c': | 		case 'c': | ||||||
| 		{ | 		case 'C': | ||||||
|  | 		print_char: | ||||||
|  |  | ||||||
| 			/* zeropad must not take effect for 'c' */ | 			/* zeropad must not take effect for 'c' */ | ||||||
| 			if (flagc & FLAGC_ZEROPAD) padc = ' ';  | 			if (flagc & FLAGC_ZEROPAD) padc = ' ';  | ||||||
| 			if (lm_flag & LF_L) goto uppercase_c; |  | ||||||
| 		#if defined(HCL_OOCH_IS_UCH) |  | ||||||
| 			if (lm_flag & LF_J) goto uppercase_c; |  | ||||||
| 		#endif |  | ||||||
| 		lowercase_c: |  | ||||||
|  |  | ||||||
| 			//bch = HCL_SIZEOF(hcl_bch_t) < HCL_SIZEOF(int)? va_arg(ap, int): va_arg(ap, hcl_bch_t); | 			//bch = HCL_SIZEOF(hcl_bch_t) < HCL_SIZEOF(int)? va_arg(ap, int): va_arg(ap, hcl_bch_t); | ||||||
| 			arg = HCL_STACK_GETARG(hcl, nargs, cur_arg); | 			arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; | ||||||
| 			if (HCL_OOP_IS_CHAR(arg)) | 			if (!HCL_OOP_IS_CHAR(arg)) | ||||||
| 			{ | 			{ | ||||||
|  | 				/* TODO: error code ... */ | ||||||
|  | 				goto oops; | ||||||
| 			} | 			} | ||||||
|  | 			ooch = HCL_OOP_TO_CHAR(arg); | ||||||
| 		print_lowercase_c: |  | ||||||
| 			/* precision 0 doesn't kill the letter */ |  | ||||||
| 			width--; |  | ||||||
| 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); |  | ||||||
| 			PRINT_OOCH (bch, 1); |  | ||||||
| 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		case 'C': |  | ||||||
| 		{ |  | ||||||
| 			hcl_uch_t ooch; |  | ||||||
|  |  | ||||||
| 			/* zeropad must not take effect for 'C' */ |  | ||||||
| 			if (flagc & FLAGC_ZEROPAD) padc = ' '; |  | ||||||
| 			if (lm_flag & LF_H) goto lowercase_c; |  | ||||||
| 		#if defined(HCL_OOCH_IS_BCH) |  | ||||||
| 			if (lm_flag & LF_J) goto lowercase_c; |  | ||||||
| 		#endif |  | ||||||
| 		uppercase_c: |  | ||||||
| 			ooch = HCL_SIZEOF(hcl_uch_t) < HCL_SIZEOF(int)? va_arg(ap, int): va_arg(ap, hcl_uch_t); |  | ||||||
|  |  | ||||||
| 			/* precision 0 doesn't kill the letter */ | 			/* precision 0 doesn't kill the letter */ | ||||||
| 			width--; | 			width--; | ||||||
| @ -1053,239 +1017,62 @@ reswitch: | |||||||
| 			PRINT_OOCH (ooch, 1); | 			PRINT_OOCH (ooch, 1); | ||||||
| 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); | 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); | ||||||
| 			break; | 			break; | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		case 's': | 		case 's': | ||||||
|  | 		case 'S': | ||||||
| 		{ | 		{ | ||||||
| 			const hcl_bch_t* bsp; | 			const hcl_ooch_t* oosp; | ||||||
| 			hcl_oow_t bslen, slen; | 			hcl_oow_t oosl; | ||||||
|  |  | ||||||
| 			/* zeropad must not take effect for 'S' */ | 			/* zeropad must not take effect for 'S' */ | ||||||
| 			if (flagc & FLAGC_ZEROPAD) padc = ' '; | 			if (flagc & FLAGC_ZEROPAD) padc = ' '; | ||||||
| 			if (lm_flag & LF_L) goto uppercase_s; |  | ||||||
| 		#if defined(HCL_OOCH_IS_UCH) |  | ||||||
| 			if (lm_flag & LF_J) goto uppercase_s; |  | ||||||
| 		#endif |  | ||||||
| 		lowercase_s: |  | ||||||
|  |  | ||||||
| 			bsp = va_arg (ap, hcl_bch_t*); |  | ||||||
| 			if (bsp == HCL_NULL) bsp = bch_nullstr; |  | ||||||
|  |  | ||||||
| 		#if defined(HCL_OOCH_IS_UCH) |  | ||||||
| 			/* get the length */ |  | ||||||
| 			for (bslen = 0; bsp[bslen]; bslen++); |  | ||||||
|  |  | ||||||
| 			if (hcl_convbtooochars(hcl, bsp, &bslen, HCL_NULL, &slen) <= -1) goto oops; |  | ||||||
|  |  | ||||||
| 			/* slen holds the length after conversion */ |  | ||||||
| 			n = slen; |  | ||||||
| 			if ((flagc & FLAGC_DOT) && precision < slen) n = precision; |  | ||||||
| 			width -= n; |  | ||||||
|  |  | ||||||
| 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); |  | ||||||
|  |  | ||||||
|  | 			arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; | ||||||
|  | 			if (!HCL_OOP_IS_POINTER(arg) || HCL_OBJ_GET_FLAGS_TYPE(arg) != HCL_OBJ_TYPE_CHAR) | ||||||
| 			{ | 			{ | ||||||
| 				hcl_ooch_t conv_buf[32];  | 				goto oops; | ||||||
| 				hcl_oow_t conv_len, src_len, tot_len = 0; |  | ||||||
| 				while (n > 0) |  | ||||||
| 				{ |  | ||||||
| 					HCL_ASSERT (hcl, bslen > tot_len); |  | ||||||
|  |  | ||||||
| 					src_len = bslen - tot_len; |  | ||||||
| 					conv_len = HCL_COUNTOF(conv_buf); |  | ||||||
|  |  | ||||||
| 					/* this must not fail since the dry-run above was successful */ |  | ||||||
| 					hcl_convbtooochars (hcl, &bsp[tot_len], &src_len, conv_buf, &conv_len); |  | ||||||
| 					tot_len += src_len; |  | ||||||
|  |  | ||||||
| 					if (conv_len > n) conv_len = n; |  | ||||||
| 					PRINT_OOCS (conv_buf, conv_len); |  | ||||||
|  |  | ||||||
| 					n -= conv_len; |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); | 			oosp = HCL_OBJ_GET_CHAR_SLOT(arg); | ||||||
| 		#else | 			oosl = HCL_OBJ_GET_SIZE(arg); | ||||||
|  |  | ||||||
| 			if (flagc & FLAGC_DOT) | 			if (flagc & FLAGC_DOT) | ||||||
| 			{ | 			{ | ||||||
| 				for (n = 0; n < precision && bsp[n]; n++); | 				if (oosl > precision) oosl = precision; | ||||||
| 			} | 			} | ||||||
| 			else | 			width -= oosl; | ||||||
| 			{ |  | ||||||
| 				for (n = 0; bsp[n]; n++); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			width -= n; |  | ||||||
|  |  | ||||||
| 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); | 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); | ||||||
| 			PRINT_OOCS (bsp, n); | 			PRINT_OOCS (oosp, oosl); | ||||||
| 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); | 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); | ||||||
| 		#endif |  | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		case 'S': |  | ||||||
| 		{ |  | ||||||
| 			const hcl_uch_t* usp; |  | ||||||
| 			hcl_oow_t uslen, slen; |  | ||||||
|  |  | ||||||
| 			/* zeropad must not take effect for 's' */ |  | ||||||
| 			if (flagc & FLAGC_ZEROPAD) padc = ' '; |  | ||||||
| 			if (lm_flag & LF_H) goto lowercase_s; |  | ||||||
| 		#if defined(HCL_OOCH_IS_UCH) |  | ||||||
| 			if (lm_flag & LF_J) goto lowercase_s; |  | ||||||
| 		#endif |  | ||||||
| 		uppercase_s: |  | ||||||
| 			usp = va_arg (ap, hcl_uch_t*); |  | ||||||
| 			if (usp == HCL_NULL) usp = uch_nullstr; |  | ||||||
|  |  | ||||||
| 		#if defined(HCL_OOCH_IS_BCH) |  | ||||||
| 			/* get the length */ |  | ||||||
| 			for (uslen = 0; usp[uslen]; uslen++); |  | ||||||
|  |  | ||||||
| 			if (hcl_convutooochars(hcl, usp, &uslen, HCL_NULL, &slen) <= -1) goto oops; |  | ||||||
|  |  | ||||||
| 			/* slen holds the length after conversion */ |  | ||||||
| 			n = slen; |  | ||||||
| 			if ((flagc & FLAGC_DOT) && precision < slen) n = precision; |  | ||||||
| 			width -= n; |  | ||||||
|  |  | ||||||
| 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); |  | ||||||
| 			{ |  | ||||||
| 				hcl_ooch_t conv_buf[32];  |  | ||||||
| 				hcl_oow_t conv_len, src_len, tot_len = 0; |  | ||||||
| 				while (n > 0) |  | ||||||
| 				{ |  | ||||||
| 					HCL_ASSERT (hcl, uslen > tot_len); |  | ||||||
|  |  | ||||||
| 					src_len = uslen - tot_len; |  | ||||||
| 					conv_len = HCL_COUNTOF(conv_buf); |  | ||||||
|  |  | ||||||
| 					/* this must not fail since the dry-run above was successful */ |  | ||||||
| 					hcl_convutooochars (hcl, &usp[tot_len], &src_len, conv_buf, &conv_len); |  | ||||||
| 					tot_len += src_len; |  | ||||||
|  |  | ||||||
| 					if (conv_len > n) conv_len = n; |  | ||||||
| 					PRINT_OOCS (conv_buf, conv_len); |  | ||||||
|  |  | ||||||
| 					n -= conv_len; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); |  | ||||||
| 		#else |  | ||||||
| 			if (flagc & FLAGC_DOT) |  | ||||||
| 			{ |  | ||||||
| 				for (n = 0; n < precision && usp[n]; n++); |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				for (n = 0; usp[n]; n++); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			width -= n; |  | ||||||
|  |  | ||||||
| 			if (!(flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); |  | ||||||
| 			PRINT_OOCS (usp, n); |  | ||||||
| 			if ((flagc & FLAGC_LEFTADJ) && width > 0) PRINT_OOCH (padc, width); |  | ||||||
| 		#endif |  | ||||||
| 			break; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		case 'O': /* object - ignore precision, width, adjustment */ | 		case 'O': /* object - ignore precision, width, adjustment */ | ||||||
| 			if (hcl_outfmtobj(hcl, data->mask, va_arg(ap, hcl_oop_t), outbfmt) <= -1) goto oops; | 			arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; | ||||||
|  | 			if (hcl_outfmtobj(hcl, 0, arg, hcl_proutbfmt) <= -1) goto oops; | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| handle_nosign: | 		number: | ||||||
| 			sign = 0; |  | ||||||
| 			if (lm_flag & LF_J) |  | ||||||
| 		{ | 		{ | ||||||
| 			#if defined(__GNUC__) && \ | 			const hcl_ooch_t* nsptr; | ||||||
| 			    (HCL_SIZEOF_UINTMAX_T > HCL_SIZEOF_OOW_T) && \ | 			hcl_oow_t nslen; | ||||||
| 			    (HCL_SIZEOF_UINTMAX_T != HCL_SIZEOF_LONG_LONG) && \ | 			arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; | ||||||
| 			    (HCL_SIZEOF_UINTMAX_T != HCL_SIZEOF_LONG) |  | ||||||
| 				/* GCC-compiled binaries crashed when getting hcl_uintmax_t with va_arg. |  | ||||||
| 				 * This is just a work-around for it */ |  | ||||||
| 				int i; |  | ||||||
| 				for (i = 0, num = 0; i < HCL_SIZEOF(hcl_uintmax_t) / HCL_SIZEOF(hcl_oow_t); i++) |  | ||||||
| 				{ |  | ||||||
| 				#if defined(HCL_ENDIAN_BIG) |  | ||||||
| 					num = num << (8 * HCL_SIZEOF(hcl_oow_t)) | (va_arg (ap, hcl_oow_t)); |  | ||||||
| 				#else |  | ||||||
| 					register int shift = i * HCL_SIZEOF(hcl_oow_t); |  | ||||||
| 					hcl_oow_t x = va_arg (ap, hcl_oow_t); |  | ||||||
| 					num |= (hcl_uintmax_t)x << (shift * 8); |  | ||||||
| 				#endif |  | ||||||
| 				} |  | ||||||
| 			#else |  | ||||||
| 				num = va_arg (ap, hcl_uintmax_t); |  | ||||||
| 			#endif |  | ||||||
| 			} |  | ||||||
| #if 0 |  | ||||||
| 			else if (lm_flag & LF_T) |  | ||||||
| 				num = va_arg (ap, hcl_ptrdiff_t); |  | ||||||
| #endif |  | ||||||
| 			else if (lm_flag & LF_Z) |  | ||||||
| 				num = va_arg (ap, hcl_oow_t); |  | ||||||
| 			#if (HCL_SIZEOF_LONG_LONG > 0) |  | ||||||
| 			else if (lm_flag & LF_Q) |  | ||||||
| 				num = va_arg (ap, unsigned long long int); |  | ||||||
| 			#endif |  | ||||||
| 			else if (lm_flag & (LF_L | LF_LD)) |  | ||||||
| 				num = va_arg (ap, unsigned long int); |  | ||||||
| 			else if (lm_flag & LF_H) |  | ||||||
| 				num = (unsigned short int)va_arg (ap, int); |  | ||||||
| 			else if (lm_flag & LF_C) |  | ||||||
| 				num = (unsigned char)va_arg (ap, int); |  | ||||||
| 			else |  | ||||||
| 				num = va_arg (ap, unsigned int); |  | ||||||
| 			goto number; |  | ||||||
|  |  | ||||||
| handle_sign: | 			if (HCL_OOP_IS_CHAR(arg)) arg = HCL_SMOOI_TO_OOP(HCL_OOP_TO_CHAR(arg)); | ||||||
| 			if (lm_flag & LF_J) | 			 | ||||||
|  | 			if (!hcl_inttostr(hcl, arg, base, -1))  | ||||||
| 			{ | 			{ | ||||||
| 			#if defined(__GNUC__) && \ | 				hcl_seterrbfmt (hcl, HCL_EINVAL, "not a valid number - %O", arg); | ||||||
| 			    (HCL_SIZEOF_INTMAX_T > HCL_SIZEOF_OOI_T) && \ | 				goto oops; | ||||||
| 			    (HCL_SIZEOF_UINTMAX_T != HCL_SIZEOF_LONG_LONG) && \ |  | ||||||
| 			    (HCL_SIZEOF_UINTMAX_T != HCL_SIZEOF_LONG) |  | ||||||
| 				/* GCC-compiled binraries crashed when getting hcl_uintmax_t with va_arg. |  | ||||||
| 				 * This is just a work-around for it */ |  | ||||||
| 				int i; |  | ||||||
| 				for (i = 0, num = 0; i < HCL_SIZEOF(hcl_intmax_t) / HCL_SIZEOF(hcl_oow_t); i++) |  | ||||||
| 				{ |  | ||||||
| 				#if defined(HCL_ENDIAN_BIG) |  | ||||||
| 					num = num << (8 * HCL_SIZEOF(hcl_oow_t)) | (va_arg (ap, hcl_oow_t)); |  | ||||||
| 				#else |  | ||||||
| 					register int shift = i * HCL_SIZEOF(hcl_oow_t); |  | ||||||
| 					hcl_oow_t x = va_arg (ap, hcl_oow_t); |  | ||||||
| 					num |= (hcl_uintmax_t)x << (shift * 8); |  | ||||||
| 				#endif |  | ||||||
| 				} |  | ||||||
| 			#else |  | ||||||
| 				num = va_arg (ap, hcl_intmax_t); |  | ||||||
| 			#endif |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| #if 0 | 			nsptr = hcl->inttostr.xbuf.ptr; | ||||||
| 			else if (lm_flag & LF_T) | 			nslen = hcl->inttostr.xbuf.len; | ||||||
| 				num = va_arg(ap, hcl_ptrdiff_t); |  | ||||||
| #endif |  | ||||||
| 			else if (lm_flag & LF_Z) |  | ||||||
| 				num = va_arg (ap, hcl_ooi_t); |  | ||||||
| 			#if (HCL_SIZEOF_LONG_LONG > 0) |  | ||||||
| 			else if (lm_flag & LF_Q) |  | ||||||
| 				num = va_arg (ap, long long int); |  | ||||||
| 			#endif |  | ||||||
| 			else if (lm_flag & (LF_L | LF_LD)) |  | ||||||
| 				num = va_arg (ap, long int); |  | ||||||
| 			else if (lm_flag & LF_H) |  | ||||||
| 				num = (short int)va_arg (ap, int); |  | ||||||
| 			else if (lm_flag & LF_C) |  | ||||||
| 				num = (char)va_arg (ap, int); |  | ||||||
| 			else |  | ||||||
| 				num = va_arg (ap, int); |  | ||||||
|  |  | ||||||
| number: | 			tmp = nslen; | ||||||
|  | /* | ||||||
| 			if (sign && (hcl_intmax_t)num < 0)  | 			if (sign && (hcl_intmax_t)num < 0)  | ||||||
| 			{ | 			{ | ||||||
| 				neg = 1; | 				neg = 1; | ||||||
| @ -1293,6 +1080,8 @@ number: | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			nbufp = sprintn (nbuf, num, base, &tmp); | 			nbufp = sprintn (nbuf, num, base, &tmp); | ||||||
|  | */ | ||||||
|  |  | ||||||
| 			if ((flagc & FLAGC_SHARP) && num != 0)  | 			if ((flagc & FLAGC_SHARP) && num != 0)  | ||||||
| 			{ | 			{ | ||||||
| 				if (base == 8) tmp++; | 				if (base == 8) tmp++; | ||||||
| @ -1302,11 +1091,13 @@ number: | |||||||
| 			else if (flagc & FLAGC_SIGN) tmp++; | 			else if (flagc & FLAGC_SIGN) tmp++; | ||||||
| 			else if (flagc & FLAGC_SPACE) tmp++; | 			else if (flagc & FLAGC_SPACE) tmp++; | ||||||
|  |  | ||||||
|  | /* | ||||||
| 			numlen = (int)((const hcl_bch_t*)nbufp - (const hcl_bch_t*)nbuf); | 			numlen = (int)((const hcl_bch_t*)nbufp - (const hcl_bch_t*)nbuf); | ||||||
| 			if ((flagc & FLAGC_DOT) && precision > numlen)  | */ | ||||||
|  | 			if ((flagc & FLAGC_DOT) && precision > nslen)  | ||||||
| 			{ | 			{ | ||||||
| 				/* extra zeros for precision specified */ | 				/* extra zeros for precision specified */ | ||||||
| 				tmp += (precision - numlen); | 				tmp += (precision - nslen); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (!(flagc & FLAGC_LEFTADJ) && !(flagc & FLAGC_ZEROPAD) && width > 0 && (width -= tmp) > 0) | 			if (!(flagc & FLAGC_LEFTADJ) && !(flagc & FLAGC_ZEROPAD) && width > 0 && (width -= tmp) > 0) | ||||||
| @ -1337,10 +1128,10 @@ number: | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if ((flagc & FLAGC_DOT) && precision > numlen) | 			if ((flagc & FLAGC_DOT) && precision > nslen) | ||||||
| 			{ | 			{ | ||||||
| 				/* extra zeros for precision specified */ | 				/* extra zeros for precision specified */ | ||||||
| 				PRINT_OOCH ('0', precision - numlen); | 				PRINT_OOCH ('0', precision - nslen); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			if (!(flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0) | 			if (!(flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0) | ||||||
| @ -1348,13 +1139,15 @@ number: | |||||||
| 				PRINT_OOCH (padc, width); | 				PRINT_OOCH (padc, width); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			while (*nbufp) PRINT_OOCH (*nbufp--, 1); /* output actual digits */ | 			//while (*nbufp) PRINT_OOCH (*nbufp--, 1); /* output actual digits */ | ||||||
|  | 			PRINT_OOCS (nsptr, nslen); | ||||||
|  |  | ||||||
| 			if ((flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0) | 			if ((flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0) | ||||||
| 			{ | 			{ | ||||||
| 				PRINT_OOCH (padc, width); | 				PRINT_OOCH (padc, width); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| invalid_format: | invalid_format: | ||||||
| 		#if defined(FMTCHAR_IS_OOCH) | 		#if defined(FMTCHAR_IS_OOCH) | ||||||
| @ -1387,4 +1180,11 @@ done: | |||||||
| oops: | oops: | ||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int hcl_print_formatted (hcl_t* hcl, hcl_ooi_t nargs) | ||||||
|  | { | ||||||
|  | 	hcl_fmtout_t fo; | ||||||
|  | 	HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo)); | ||||||
|  | 	return print_formatted (hcl, nargs, &fo); | ||||||
|  | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -394,9 +394,16 @@ static hcl_pfrc_t pf_printf (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs) | |||||||
| 		return HCL_PF_SUCCESS; | 		return HCL_PF_SUCCESS; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| //	print_formatted (hcl, nargs); | 	if (hcl_print_formatted(hcl, nargs) <= -1) | ||||||
|  | 	{ | ||||||
|  | 		HCL_STACK_SETRETTOERRNUM (hcl, nargs); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | /* TODO: better return code? */ | ||||||
| 		HCL_STACK_SETRET (hcl, nargs, hcl->_nil); | 		HCL_STACK_SETRET (hcl, nargs, hcl->_nil); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return HCL_PF_SUCCESS; | 	return HCL_PF_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -113,14 +113,18 @@ static struct | |||||||
| 	{  12, { '#','<','S','E','M','A','P','H','O','R','E','>' } } | 	{  12, { '#','<','S','E','M','A','P','H','O','R','E','>' } } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| static HCL_INLINE int print_single_char (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_outbfmt_t outbfmt) | static HCL_INLINE int print_single_char (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_outbfmt_t outbfmt) | ||||||
| { | { | ||||||
| 	if (ch < ' ')  | 	hcl_oochu_t chu = (hcl_oochu_t)ch; | ||||||
|  | #if defined(HCL_OOCH_IS_UCH) | ||||||
|  | 	if (chu < ' ')  | ||||||
|  | #else | ||||||
|  | 	if (chu < ' ' || chu >= 0x80)  | ||||||
|  | #endif | ||||||
| 	{ | 	{ | ||||||
| 		hcl_ooch_t escaped; | 		hcl_ooch_t escaped; | ||||||
|  |  | ||||||
| 		switch (ch) | 		switch (chu) | ||||||
| 		{ | 		{ | ||||||
| 			case '\0': | 			case '\0': | ||||||
| 				escaped = '0'; | 				escaped = '0'; | ||||||
| @ -153,7 +157,7 @@ static HCL_INLINE int print_single_char (hcl_t* hcl, int mask, hcl_ooch_t ch, hc | |||||||
|  |  | ||||||
| 		if (escaped == ch) | 		if (escaped == ch) | ||||||
| 		{ | 		{ | ||||||
| 			if (outbfmt(hcl, mask, "\\x%X", ch) <= -1) return -1; | 			if (outbfmt(hcl, mask, "\\x%X", chu) <= -1) return -1; | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
| @ -803,6 +803,7 @@ static int get_sharp_token (hcl_t* hcl) | |||||||
| 								"invalid hexadecimal character in %.*js", TOKEN_NAME_LEN(hcl), TOKEN_NAME_PTR(hcl)); | 								"invalid hexadecimal character in %.*js", TOKEN_NAME_LEN(hcl), TOKEN_NAME_PTR(hcl)); | ||||||
| 							return -1; | 							return -1; | ||||||
| 						} | 						} | ||||||
|  | /* TODO: check for the max charcter value and raise an error... */ | ||||||
| 						c = c * 16 + CHAR_TO_NUM(hcl->c->tok.name.ptr[i], 16); /* don't care if it is for 'p' */ | 						c = c * 16 + CHAR_TO_NUM(hcl->c->tok.name.ptr[i], 16); /* don't care if it is for 'p' */ | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user