added a few string formatting functions
This commit is contained in:
		| @ -200,7 +200,7 @@ static int store_temporary_variable_count_for_block (hcl_t* hcl, hcl_oow_t tmpr_ | ||||
|  | ||||
| 		newcapa = HCL_ALIGN(hcl->c->blk.depth + 1, BLK_INFO_BUFFER_ALIGN); | ||||
| 		tmp = (hcl_blk_info_t*)hcl_reallocmem(hcl, hcl->c->blk.info, newcapa * HCL_SIZEOF(*tmp)); | ||||
| 		if (!tmp) return -1; | ||||
| 		if (HCL_UNLIKELY(!tmp)) return -1; | ||||
|  | ||||
| 		hcl->c->blk.info_capa = newcapa; | ||||
| 		hcl->c->blk.info = tmp; | ||||
| @ -1755,6 +1755,7 @@ static int compile_try (hcl_t* hcl, hcl_cnode_t* src) | ||||
| 	/* (try | ||||
| 	 *   (perform this) | ||||
| 	 *   (perform that) | ||||
| 	 *   (throw 10) | ||||
| 	 *  catch (x) | ||||
| 	 *   (perform xxx) | ||||
| 	 *   (perform yyy) | ||||
|  | ||||
							
								
								
									
										186
									
								
								hcl/lib/fmt.c
									
									
									
									
									
								
							
							
						
						
									
										186
									
								
								hcl/lib/fmt.c
									
									
									
									
									
								
							| @ -2841,3 +2841,189 @@ int hcl_logfmtcallstack (hcl_t* hcl, hcl_ooi_t nargs) | ||||
|  | ||||
| 	return format_stack_args(&fo, nargs, 0); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* -------------------------------------------------------------------------- | ||||
|  * DYNAMIC STRING FORMATTING | ||||
|  * -------------------------------------------------------------------------- */ | ||||
|  | ||||
| struct fmt_uch_buf_t | ||||
| { | ||||
| 	hcl_t* hcl; | ||||
| 	hcl_uch_t* ptr; | ||||
| 	hcl_oow_t len; | ||||
| 	hcl_oow_t capa; | ||||
| }; | ||||
| typedef struct fmt_uch_buf_t fmt_uch_buf_t; | ||||
|  | ||||
| static int fmt_put_bchars_to_uch_buf (hcl_fmtout_t* fmtout, const hcl_bch_t* ptr, hcl_oow_t len) | ||||
| { | ||||
| 	fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; | ||||
| 	hcl_oow_t bcslen, ucslen; | ||||
| 	int n; | ||||
|  | ||||
| 	bcslen = len; | ||||
| 	ucslen = b->capa - b->len; | ||||
| 	n = hcl_conv_bchars_to_uchars_with_cmgr(ptr, &bcslen, &b->ptr[b->len], &ucslen, b->hcl->_cmgr, 1); | ||||
| 	b->len += ucslen; | ||||
| 	if (n <= -1)  | ||||
| 	{ | ||||
| 		if (n == -2)  | ||||
| 		{ | ||||
| 			return 0; /* buffer full. stop */ | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			hcl_seterrnum (b->hcl, HCL_EECERR); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 1; /* success. carry on */ | ||||
| } | ||||
|  | ||||
| static int fmt_put_uchars_to_uch_buf (hcl_fmtout_t* fmtout, const hcl_uch_t* ptr, hcl_oow_t len) | ||||
| { | ||||
| 	fmt_uch_buf_t* b = (fmt_uch_buf_t*)fmtout->ctx; | ||||
| 	hcl_oow_t n; | ||||
|  | ||||
| 	/* this function null-terminates the destination. so give the restored buffer size */ | ||||
| 	n = hcl_copy_uchars_to_ucstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); | ||||
| 	b->len += n; | ||||
| 	if (n < len) | ||||
| 	{ | ||||
| 		hcl_seterrnum (b->hcl, HCL_EBUFFULL); | ||||
| 		return 0; /* stop. insufficient buffer */ | ||||
| 	} | ||||
|  | ||||
| 	return 1; /* success */ | ||||
| } | ||||
|  | ||||
| hcl_oow_t hcl_vfmttoucstr (hcl_t* hcl, hcl_uch_t* buf, hcl_oow_t bufsz, const hcl_uch_t* fmt, va_list ap) | ||||
| { | ||||
| 	hcl_fmtout_t fo; | ||||
| 	fmt_uch_buf_t fb; | ||||
|  | ||||
| 	if (bufsz <= 0) return 0; | ||||
|  | ||||
| 	HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo)); | ||||
| 	fo.mmgr = hcl->_mmgr; | ||||
| 	fo.putbchars = fmt_put_bchars_to_uch_buf; | ||||
| 	fo.putuchars = fmt_put_uchars_to_uch_buf; | ||||
| 	fo.ctx = &fb; | ||||
|  | ||||
| 	HCL_MEMSET (&fb, 0, HCL_SIZEOF(fb)); | ||||
| 	fb.hcl = hcl; | ||||
| 	fb.ptr = buf; | ||||
| 	fb.capa = bufsz - 1; | ||||
|  | ||||
| 	if (hcl_ufmt_outv(&fo, fmt, ap) <= -1) return -1; | ||||
|  | ||||
| 	buf[fb.len] = '\0'; | ||||
| 	return fb.len; | ||||
| } | ||||
|  | ||||
| hcl_oow_t hcl_fmttoucstr (hcl_t* hcl, hcl_uch_t* buf, hcl_oow_t bufsz, const hcl_uch_t* fmt, ...) | ||||
| { | ||||
| 	hcl_oow_t x; | ||||
| 	va_list ap; | ||||
|  | ||||
| 	va_start (ap, fmt); | ||||
| 	x = hcl_vfmttoucstr(hcl, buf, bufsz, fmt, ap); | ||||
| 	va_end (ap); | ||||
|  | ||||
| 	return x; | ||||
| } | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| struct fmt_bch_buf_t | ||||
| { | ||||
| 	hcl_t* hcl; | ||||
| 	hcl_bch_t* ptr; | ||||
| 	hcl_oow_t len; | ||||
| 	hcl_oow_t capa; | ||||
| }; | ||||
| typedef struct fmt_bch_buf_t fmt_bch_buf_t; | ||||
|  | ||||
|  | ||||
| static int fmt_put_bchars_to_bch_buf (hcl_fmtout_t* fmtout, const hcl_bch_t* ptr, hcl_oow_t len) | ||||
| { | ||||
| 	fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; | ||||
| 	hcl_oow_t n; | ||||
|  | ||||
| 	/* this function null-terminates the destination. so give the restored buffer size */ | ||||
| 	n = hcl_copy_bchars_to_bcstr(&b->ptr[b->len], b->capa - b->len + 1, ptr, len); | ||||
| 	b->len += n; | ||||
| 	if (n < len) | ||||
| 	{ | ||||
| 		hcl_seterrnum (b->hcl, HCL_EBUFFULL); | ||||
| 		return 0; /* stop. insufficient buffer */ | ||||
| 	} | ||||
|  | ||||
| 	return 1; /* success */ | ||||
| } | ||||
|  | ||||
|  | ||||
| static int fmt_put_uchars_to_bch_buf (hcl_fmtout_t* fmtout, const hcl_uch_t* ptr, hcl_oow_t len) | ||||
| { | ||||
| 	fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx; | ||||
| 	hcl_oow_t bcslen, ucslen; | ||||
| 	int n; | ||||
|  | ||||
| 	bcslen = b->capa - b->len; | ||||
| 	ucslen = len; | ||||
| 	n = hcl_conv_uchars_to_bchars_with_cmgr(ptr, &ucslen, &b->ptr[b->len], &bcslen, b->hcl->_cmgr); | ||||
| 	b->len += bcslen; | ||||
| 	if (n <= -1) | ||||
| 	{ | ||||
| 		if (n == -2) | ||||
| 		{ | ||||
| 			return 0; /* buffer full. stop */ | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			hcl_seterrnum (b->hcl, HCL_EECERR); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 1; /* success. carry on */ | ||||
| } | ||||
|  | ||||
| hcl_oow_t hcl_vfmttobcstr (hcl_t* hcl, hcl_bch_t* buf, hcl_oow_t bufsz, const hcl_bch_t* fmt, va_list ap) | ||||
| { | ||||
| 	hcl_fmtout_t fo; | ||||
| 	fmt_bch_buf_t fb; | ||||
|  | ||||
| 	if (bufsz <= 0) return 0; | ||||
|  | ||||
| 	HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo)); | ||||
| 	fo.mmgr = hcl->_mmgr; | ||||
| 	fo.putbchars = fmt_put_bchars_to_bch_buf; | ||||
| 	fo.putuchars = fmt_put_uchars_to_bch_buf; | ||||
| 	fo.ctx = &fb; | ||||
|  | ||||
| 	HCL_MEMSET (&fb, 0, HCL_SIZEOF(fb)); | ||||
| 	fb.hcl = hcl; | ||||
| 	fb.ptr = buf; | ||||
| 	fb.capa = bufsz - 1; | ||||
|  | ||||
| 	if (hcl_bfmt_outv(&fo, fmt, ap) <= -1) return -1; | ||||
|  | ||||
| 	buf[fb.len] = '\0'; | ||||
| 	return fb.len; | ||||
| } | ||||
|  | ||||
| hcl_oow_t hcl_fmttobcstr (hcl_t* hcl, hcl_bch_t* buf, hcl_oow_t bufsz, const hcl_bch_t* fmt, ...) | ||||
| { | ||||
| 	hcl_oow_t x; | ||||
| 	va_list ap; | ||||
|  | ||||
| 	va_start (ap, fmt); | ||||
| 	x = hcl_vfmttobcstr(hcl, buf, bufsz, fmt, ap); | ||||
| 	va_end (ap); | ||||
|  | ||||
| 	return x; | ||||
| } | ||||
|  | ||||
| @ -2221,6 +2221,53 @@ HCL_EXPORT hcl_ooi_t hcl_prufmtv ( | ||||
| #	define hcl_proofmt hcl_prbfmt | ||||
| #	define hcl_proofmtv hcl_prbfmtv | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* ========================================================================= | ||||
|  * STRING FORMATTING | ||||
|  * ========================================================================= */ | ||||
|  | ||||
| HCL_EXPORT hcl_oow_t hcl_vfmttoucstr ( | ||||
| 	hcl_t*           hcl, | ||||
| 	hcl_uch_t*       buf, | ||||
| 	hcl_oow_t        bufsz, | ||||
| 	const hcl_uch_t* fmt, | ||||
| 	va_list           ap | ||||
| ); | ||||
|  | ||||
| HCL_EXPORT hcl_oow_t hcl_fmttoucstr ( | ||||
| 	hcl_t*           hcl, | ||||
| 	hcl_uch_t*       buf, | ||||
| 	hcl_oow_t        bufsz, | ||||
| 	const hcl_uch_t* fmt, | ||||
| 	... | ||||
| ); | ||||
|  | ||||
| HCL_EXPORT hcl_oow_t hcl_vfmttobcstr ( | ||||
| 	hcl_t*           hcl, | ||||
| 	hcl_bch_t*       buf, | ||||
| 	hcl_oow_t        bufsz, | ||||
| 	const hcl_bch_t* fmt, | ||||
| 	va_list           ap | ||||
| ); | ||||
|  | ||||
| HCL_EXPORT hcl_oow_t hcl_fmttobcstr ( | ||||
| 	hcl_t*           hcl, | ||||
| 	hcl_bch_t*       buf, | ||||
| 	hcl_oow_t        bufsz, | ||||
| 	const hcl_bch_t* fmt, | ||||
| 	... | ||||
| ); | ||||
|  | ||||
| #if defined(HCL_OOCH_IS_UCH) | ||||
| #	define hcl_vfmttooocstr hcl_vfmttoucstr | ||||
| #	define hcl_fmttooocstr hcl_fmttoucstr | ||||
| #else | ||||
| #	define hcl_vfmttooocstr hcl_vfmttobcstr | ||||
| #	define hcl_fmttooocstr hcl_fmttobcstr | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* ========================================================================= | ||||
|  * OBJECT MANAGEMENT | ||||
|  * ========================================================================= */ | ||||
|  | ||||
| @ -2771,23 +2771,40 @@ static void cb_opt_set (hcl_t* hcl, hcl_option_t id, const void* value) | ||||
| #if defined(__OS2__) && defined(TCPV40HDRS) | ||||
| static int os2_socket_pair (int p[2]) | ||||
| { | ||||
| 	int x, y, z; | ||||
| 	int x = -1, y = -1, z; | ||||
| 	struct sockaddr_un sa; | ||||
| 	PTIB tib; | ||||
| 	PPIB pib; | ||||
| 	ULONG pid, tid, msec; | ||||
|  | ||||
|         DosGetInfoBlocks(&tib, &pib); | ||||
| 	DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT, &msec, HCL_SIZEOF(msec)); | ||||
|  | ||||
| 	x = socket(PF_OS2, SOCK_STREAM, 0); | ||||
| 	if (x <= -1) goto oops; | ||||
|  | ||||
| 	for (i = 0; i < 10000; i++) | ||||
| 	{ | ||||
| 		HCL_MEMSET (&sa, 0, HCL_SIZEOF(sa)); | ||||
| 		sa.sun_family = AF_OS2; | ||||
|  | ||||
| 		/* OS/2 mandates the socket name should begin with \socket\ */ | ||||
| 		sprintf (sa.sun_path, "\\socket\\hcl-%lu-%lu-%lu", (unsigned long int)pib->pib_ulpid, (unsigned long int)tib->tib_ultid, (unsigned long int)msec); | ||||
|  | ||||
| 		if (bind(x, &sa, HCL_SIZEOF(sa)) <= -1)  | ||||
| 		{ | ||||
| 			msec++; | ||||
| 			continue; | ||||
| 			goto oops; | ||||
| 		} | ||||
| 		if (listen(x, 1) <= -1) goto oops; | ||||
| 	} | ||||
|  | ||||
| 	y = socket(PF_OS2, SOCK_STREAM, 0); | ||||
| 	if (x == -1 || y == -1)  goto oops; | ||||
|  | ||||
| 	HCL_MEMSET (&sa, 0, HCL_SIZEOF(sa)); | ||||
| 	sa.sun_family = AF_OS2; | ||||
| 	hcl_copy_bcstr (sa.sun_path, HCL_SIZEOF(sa.sun_path), "\\socket\\XXXXX"); /* TODO: make this address unique*/ | ||||
|  | ||||
| 	if (bind(x, &sa, HCL_SIZEOF(sa)) == -1) goto oops; | ||||
| 	if (listen(x, 1) == -1) goto oops; | ||||
|  | ||||
| 	if (connect(y, &sa, HCL_SIZEOF(sa)) == -1) goto oops; | ||||
| 	if (y <= -1) goto oops; | ||||
| 	if (connect(y, &sa, HCL_SIZEOF(sa)) <= -1) goto oops; | ||||
| 	z = accept(x, HCL_NULL, HCL_NULL); | ||||
| 	if (z == -1) goto oops; | ||||
| 	if (z <= -1) goto oops; | ||||
|  | ||||
| 	soclose (x); | ||||
| 	p[0] = z; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user