| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |     Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |     modification, are permitted provided that the following conditions | 
					
						
							|  |  |  |     are met: | 
					
						
							|  |  |  |     1. Redistributions of source code must retain the above copyright | 
					
						
							|  |  |  |        notice, this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |     2. Redistributions in binary form must reproduce the above copyright | 
					
						
							|  |  |  |        notice, this list of conditions and the following disclaimer in the | 
					
						
							|  |  |  |        documentation and/or other materials provided with the distribution. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | 
					
						
							|  |  |  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
					
						
							|  |  |  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
					
						
							|  |  |  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
					
						
							|  |  |  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
					
						
							|  |  |  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
					
						
							|  |  |  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
					
						
							|  |  |  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
					
						
							|  |  |  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "sed-prv.h"
 | 
					
						
							|  |  |  | #include "hawk-prv.h"
 | 
					
						
							|  |  |  | #include "hawk-std.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct xtn_in_t xtn_in_t; | 
					
						
							|  |  |  | struct xtn_in_t | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t* ptr; | 
					
						
							|  |  |  | 	hawk_sed_iostd_t* cur; | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	hawk_oow_t        mempos; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct xtn_out_t xtn_out_t; | 
					
						
							|  |  |  | struct xtn_out_t | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t* ptr; | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		hawk_becs_t* be; | 
					
						
							|  |  |  | 		hawk_uecs_t* ue; | 
					
						
							|  |  |  | 	} memstr; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct xtn_t xtn_t; | 
					
						
							|  |  |  | struct xtn_t | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xtn_in_t in; | 
					
						
							|  |  |  | 		hawk_ooch_t last; | 
					
						
							|  |  |  | 		int newline_squeezed; | 
					
						
							|  |  |  | 	} s; | 
					
						
							|  |  |  | 	struct | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		xtn_in_t  in; | 
					
						
							|  |  |  | 		xtn_out_t out; | 
					
						
							|  |  |  | 	} e; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hawk_link_t* sio_names; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(HAWK_HAVE_INLINE)
 | 
					
						
							|  |  |  | static HAWK_INLINE xtn_t* GET_XTN(hawk_sed_t* sed) { return (xtn_t*)((hawk_uint8_t*)hawk_sed_getxtn(sed) - HAWK_SIZEOF(xtn_t)); } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #define GET_XTN(sed) ((xtn_t*)((hawk_uint8_t*)hawk_sed_getxtn(sed) - HAWK_SIZEOF(xtn_t)))
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int int_to_str (hawk_oow_t val, hawk_ooch_t* buf, hawk_oow_t buflen) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_oow_t t; | 
					
						
							|  |  |  | 	hawk_oow_t rlen = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t = val; | 
					
						
							|  |  |  | 	if (t == 0) rlen++; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* non-zero values */ | 
					
						
							|  |  |  | 		if (t < 0) { t = -t; rlen++; } | 
					
						
							|  |  |  | 		while (t > 0) { rlen++; t /= 10; } | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (rlen >= buflen) return -1; /* buffer too small */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buf[rlen] = HAWK_T('\0'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t = val; | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (t == 0) buf[0] = HAWK_T('0'); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (t < 0) t = -t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* fill in the buffer with digits */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 		while (t > 0) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			buf[--rlen] = (hawk_ooch_t)(t % 10) + HAWK_T('0'); | 
					
						
							|  |  |  | 			t /= 10; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* insert the negative sign if necessary */ | 
					
						
							|  |  |  | 		if (val < 0) buf[--rlen] = HAWK_T('-'); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_sed_t* hawk_sed_openstd (hawk_oow_t xtnsize, hawk_errnum_t* errnum) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return hawk_sed_openstdwithmmgr (hawk_get_sys_mmgr(), xtnsize, hawk_get_cmgr_by_id(HAWK_CMGR_UTF8), errnum); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | hawk_sed_t* hawk_sed_openstdwithmmgr (hawk_mmgr_t* mmgr, hawk_oow_t xtnsize, hawk_cmgr_t* cmgr, hawk_errnum_t* errnum) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_t* sed; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!mmgr) mmgr = hawk_get_sys_mmgr(); | 
					
						
							|  |  |  | 	if (!cmgr) cmgr = hawk_get_cmgr_by_id(HAWK_CMGR_UTF8); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sed = hawk_sed_open(mmgr, HAWK_SIZEOF(xtn_t) + xtnsize, cmgr, errnum); | 
					
						
							|  |  |  | 	if (!sed) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sed->_instsize += HAWK_SIZEOF(xtn_t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return sed; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int verify_iostd_in (hawk_sed_t* sed, hawk_sed_iostd_t in[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_oow_t i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (in[0].type == HAWK_SED_IOSTD_NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 		/* if 'in' is specified, it must contains at least one
 | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		 * valid entry */ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_EINVAL, "no input handler provided"); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; in[i].type != HAWK_SED_IOSTD_NULL; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (in[i].type != HAWK_SED_IOSTD_FILE && | 
					
						
							|  |  |  | 		    in[i].type != HAWK_SED_IOSTD_FILEB && | 
					
						
							|  |  |  | 		    in[i].type != HAWK_SED_IOSTD_FILEU && | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		    in[i].type != HAWK_SED_IOSTD_OOCS && | 
					
						
							|  |  |  | 		    in[i].type != HAWK_SED_IOSTD_BCS && | 
					
						
							|  |  |  | 		    in[i].type != HAWK_SED_IOSTD_UCS && | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		    in[i].type != HAWK_SED_IOSTD_SIO) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_EINVAL, "unsupported input type provided - handler %d type %d", i, in[i].type); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_sio_t* open_sio_file (hawk_sed_t* sed, const hawk_ooch_t* file, int flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sio_t* sio; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sio = hawk_sio_open(hawk_sed_getgem(sed), 0, file, flags); | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (sio == HAWK_NULL) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed); | 
					
						
							|  |  |  | 		hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to open %js - %js", file, bem); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return sio; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_oocs_t sio_std_names[] = | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	{ (hawk_ooch_t*)HAWK_T("stdin"),   5 }, | 
					
						
							|  |  |  | 	{ (hawk_ooch_t*)HAWK_T("stdout"),  6 }, | 
					
						
							|  |  |  | 	{ (hawk_ooch_t*)HAWK_T("stderr"),  6 } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooch_t* add_sio_name_with_uchars (hawk_sed_t* sed, const hawk_uch_t* ptr, hawk_oow_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 	hawk_link_t* link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* TODO: duplication check? */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 	link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_uch_t) * (len + 1)); | 
					
						
							|  |  |  | 	if (!link) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hawk_copy_uchars_to_ucstr_unlimited ((hawk_uch_t*)(link + 1), ptr, len); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	hawk_oow_t bcslen, ucslen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ucslen = len; | 
					
						
							|  |  |  | 	if (hawk_gem_convutobchars(hawk_sed_getgem(sed), ptr, &ucslen, HAWK_NULL, &bcslen) <= -1) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_bch_t) * (bcslen + 1)); | 
					
						
							|  |  |  | 	if (!link) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ucslen = len; | 
					
						
							|  |  |  | 	bcslen = bcslen + 1; | 
					
						
							|  |  |  | 	hawk_gem_convutobchars (hawk_sed_getgem(sed), ptr, &ucslen, (hawk_bch_t*)(link + 1), &bcslen); | 
					
						
							|  |  |  | 	((hawk_bch_t*)(link + 1))[bcslen] = '\0'; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->link = xtn->sio_names; | 
					
						
							|  |  |  | 	xtn->sio_names = link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (hawk_ooch_t*)(link + 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooch_t* add_sio_name_with_bchars (hawk_sed_t* sed, const hawk_bch_t* ptr, hawk_oow_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 	hawk_link_t* link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* TODO: duplication check? */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 	hawk_oow_t bcslen, ucslen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bcslen = len; | 
					
						
							|  |  |  | 	if (hawk_gem_convbtouchars(hawk_sed_getgem(sed), ptr, &bcslen, HAWK_NULL, &ucslen, 0) <= -1) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_uch_t) * (ucslen + 1)); | 
					
						
							|  |  |  | 	if (!link) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bcslen = len; | 
					
						
							|  |  |  | 	ucslen = ucslen + 1; | 
					
						
							|  |  |  | 	hawk_gem_convbtouchars (hawk_sed_getgem(sed), ptr, &bcslen, (hawk_uch_t*)(link + 1), &ucslen, 0); | 
					
						
							|  |  |  | 	((hawk_uch_t*)(link + 1))[ucslen] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	link = (hawk_link_t*)hawk_sed_callocmem(sed, HAWK_SIZEOF(*link) + HAWK_SIZEOF(hawk_bch_t) * (len + 1)); | 
					
						
							|  |  |  | 	if (!link) return HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	hawk_copy_bchars_to_bcstr_unlimited ((hawk_bch_t*)(link + 1), ptr, len); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	link->link = xtn->sio_names; | 
					
						
							|  |  |  | 	xtn->sio_names = link; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (hawk_ooch_t*)(link + 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void clear_sio_names (hawk_sed_t* sed) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 	hawk_link_t* cur; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (xtn->sio_names) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		cur = xtn->sio_names; | 
					
						
							|  |  |  | 		xtn->sio_names = cur->link; | 
					
						
							|  |  |  | 		hawk_sed_freemem (sed, cur); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_sio_t* open_sio_std (hawk_sed_t* sed, hawk_sio_std_t std, int flags) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sio_t* sio; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sio = hawk_sio_openstd(hawk_sed_getgem(sed), 0, std, flags); | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (sio == HAWK_NULL) | 
					
						
							| 
									
										
										
										
											2022-06-09 13:53:01 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed); | 
					
						
							|  |  |  | 		hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to open %js - %js", &sio_std_names[std], bem); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	return sio; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | static void set_eiofil_for_iostd (hawk_sed_t* sed, hawk_sed_iostd_t* io) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-06-09 13:53:01 +00:00
										 |  |  | 	const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	HAWK_ASSERT (io->type == HAWK_SED_IOSTD_FILE || io->type == HAWK_SED_IOSTD_FILEB || io->type == HAWK_SED_IOSTD_FILEU); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (io->u.file.path) /* file, fileb, fileu are union members. checking file.path regardless of io->type must be safe */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		switch (io->type) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_FILEB: | 
					
						
							| 
									
										
										
										
											2022-06-09 13:53:01 +00:00
										 |  |  | 				hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "I/O error with file '%hs' - %js", io->u.fileb.path, bem); | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_FILEU: | 
					
						
							| 
									
										
										
										
											2022-06-09 13:53:01 +00:00
										 |  |  | 				hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "I/O error with file '%ls' - %js", io->u.fileu.path, bem); | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				HAWK_ASSERT (!"should never happen - unknown file I/O type"); | 
					
						
							|  |  |  | 				hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINVAL); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-06-09 13:53:01 +00:00
										 |  |  | 		hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "I/O error with file '%js' - %js", &sio_std_names[HAWK_SIO_STDIN], bem); | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | static void close_main_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_sed_iostd_t* io) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (io->type) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILEB: | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILEU: | 
					
						
							|  |  |  | 			hawk_sio_close (arg->handle); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_BCS: | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_UCS: | 
					
						
							|  |  |  | 			/* for input, there is nothing to do here.
 | 
					
						
							|  |  |  | 			 * for output, closing xtn->e.out.memstr is required. but put it to hawk_awk_execstd(). | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			 */ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_SIO: | 
					
						
							|  |  |  | 			/* nothing to do */ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			/* do nothing */ | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int open_input_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_sed_iostd_t* io, xtn_in_t* base) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HAWK_ASSERT (io != HAWK_NULL); | 
					
						
							|  |  |  | 	switch (io->type) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileb.path == &io->u.file.path); | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileb.cmgr == &io->u.file.cmgr); | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILEB: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			hawk_sio_t* sio; | 
					
						
							|  |  |  | 			hawk_ooch_t* path; | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (io->u.fileb.path == HAWK_NULL || | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			    (io->u.fileb.path[0] == '-' && io->u.fileb.path[1] == '\0')) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				sio = open_sio_std(sed, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				path = add_sio_name_with_bchars(sed, io->u.fileb.path, hawk_count_bcstr(io->u.fileb.path)); | 
					
						
							|  |  |  | 				if (path == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 				sio = open_sio_file(sed, path, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (io->u.fileb.cmgr) hawk_sio_setcmgr (sio, io->u.fileb.cmgr); | 
					
						
							|  |  |  | 			arg->handle = sio; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileu.path == &io->u.file.path); | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileu.cmgr == &io->u.file.cmgr); | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILEU: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			hawk_sio_t* sio; | 
					
						
							|  |  |  | 			hawk_ooch_t* path; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			if (io->u.fileu.path == HAWK_NULL || | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			    (io->u.fileu.path[0] == '-' && io->u.fileu.path[1] == '\0')) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				sio = open_sio_std(sed, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				path = add_sio_name_with_uchars(sed, io->u.fileu.path, hawk_count_ucstr(io->u.fileu.path)); | 
					
						
							|  |  |  | 				if (path == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 				sio = open_sio_file(sed, path, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (io->u.fileu.cmgr) hawk_sio_setcmgr (sio, io->u.fileu.cmgr); | 
					
						
							|  |  |  | 			arg->handle = sio; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_BCS: | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_UCS: | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			/* don't store anything to arg->handle */ | 
					
						
							|  |  |  | 			base->mempos = 0; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_SIO: | 
					
						
							|  |  |  | 			arg->handle = io->u.sio; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			HAWK_ASSERT (!"should never happen - io-type must be one of SIO,FILE,FILEB,FILEU,STR"); | 
					
						
							|  |  |  | 			hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (base == &xtn->s.in) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* reset script location */ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		switch (io->type) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 				if (io->u.fileb.path) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					hawk_sed_setcompid (sed, io->u.file.path); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 				compid_stdin: | 
					
						
							|  |  |  | 					hawk_sed_setcompid (sed, sio_std_names[HAWK_SIO_STDIN].ptr); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_FILEB: | 
					
						
							|  |  |  | 				if (!io->u.fileb.path) goto compid_stdin; | 
					
						
							|  |  |  | 				hawk_sed_setcompidwithbcstr (sed, io->u.fileb.path); | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			case HAWK_SED_IOSTD_FILEU: | 
					
						
							|  |  |  | 				if (!io->u.fileu.path) goto compid_stdin; | 
					
						
							|  |  |  | 				hawk_sed_setcompid (sed, sio_std_names[HAWK_SIO_STDIN].ptr); | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				hawk_ooch_t buf[64]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* format an identifier to be something like M#1, S#5 */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 				buf[0] = (io->type == HAWK_SED_IOSTD_OOCS || | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 						io->type == HAWK_SED_IOSTD_BCS || | 
					
						
							|  |  |  | 						io->type == HAWK_SED_IOSTD_UCS)? HAWK_T('M'): HAWK_T('S'); | 
					
						
							|  |  |  | 				buf[1] = HAWK_T('#'); | 
					
						
							|  |  |  | 				int_to_str (io - xtn->s.in.ptr, &buf[2], HAWK_COUNTOF(buf) - 2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 				/* don't care about failure int_to_str() though it's not
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 				 * likely to happen */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 				hawk_sed_setcompid (sed, buf); | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 		sed->src.loc.line = 1; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		sed->src.loc.colm = 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int open_output_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_sed_iostd_t* io) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HAWK_ASSERT (io != HAWK_NULL); | 
					
						
							|  |  |  | 	switch (io->type) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 	#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileb.path == &io->u.file.path); | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileb.cmgr == &io->u.file.cmgr); | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILEB: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			hawk_sio_t* sio; | 
					
						
							|  |  |  | 			hawk_ooch_t* path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (io->u.fileb.path == HAWK_NULL || | 
					
						
							|  |  |  | 			    (io->u.fileb.path[0] == HAWK_T('-') && io->u.fileb.path[1] == HAWK_T('\0'))) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				sio = open_sio_std( | 
					
						
							|  |  |  | 					sed, HAWK_SIO_STDOUT, | 
					
						
							|  |  |  | 					HAWK_SIO_WRITE | | 
					
						
							|  |  |  | 					HAWK_SIO_CREATE | | 
					
						
							|  |  |  | 					HAWK_SIO_TRUNCATE | | 
					
						
							|  |  |  | 					HAWK_SIO_IGNOREECERR | | 
					
						
							|  |  |  | 					HAWK_SIO_LINEBREAK | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				path = add_sio_name_with_bchars(sed, io->u.fileb.path, hawk_count_bcstr(io->u.fileb.path)); | 
					
						
							|  |  |  | 				if (path == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 				sio = open_sio_file( | 
					
						
							|  |  |  | 					sed, path, | 
					
						
							|  |  |  | 					HAWK_SIO_WRITE | | 
					
						
							|  |  |  | 					HAWK_SIO_CREATE | | 
					
						
							|  |  |  | 					HAWK_SIO_TRUNCATE | | 
					
						
							|  |  |  | 					HAWK_SIO_IGNOREECERR | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 			if (io->u.fileb.cmgr) hawk_sio_setcmgr (sio, io->u.fileb.cmgr); | 
					
						
							|  |  |  | 			arg->handle = sio; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILE: | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileu.path == &io->u.file.path); | 
					
						
							|  |  |  | 			HAWK_ASSERT (&io->u.fileu.cmgr == &io->u.file.cmgr); | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_FILEU: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			hawk_sio_t* sio; | 
					
						
							|  |  |  | 			hawk_ooch_t* path; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (io->u.fileu.path == HAWK_NULL || | 
					
						
							|  |  |  | 			    (io->u.fileu.path[0] == HAWK_T('-') && io->u.fileu.path[1] == HAWK_T('\0'))) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				sio = open_sio_std( | 
					
						
							|  |  |  | 					sed, HAWK_SIO_STDOUT, | 
					
						
							|  |  |  | 					HAWK_SIO_WRITE | | 
					
						
							|  |  |  | 					HAWK_SIO_CREATE | | 
					
						
							|  |  |  | 					HAWK_SIO_TRUNCATE | | 
					
						
							|  |  |  | 					HAWK_SIO_IGNOREECERR | | 
					
						
							|  |  |  | 					HAWK_SIO_LINEBREAK | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				path = add_sio_name_with_uchars(sed, io->u.fileu.path, hawk_count_ucstr(io->u.fileu.path)); | 
					
						
							|  |  |  | 				if (path == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 				sio = open_sio_file( | 
					
						
							|  |  |  | 					sed, path, | 
					
						
							|  |  |  | 					HAWK_SIO_WRITE | | 
					
						
							|  |  |  | 					HAWK_SIO_CREATE | | 
					
						
							|  |  |  | 					HAWK_SIO_TRUNCATE | | 
					
						
							|  |  |  | 					HAWK_SIO_IGNOREECERR | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 			if (io->u.fileu.cmgr) hawk_sio_setcmgr (sio, io->u.fileu.cmgr); | 
					
						
							|  |  |  | 			arg->handle = sio; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_BCS: | 
					
						
							|  |  |  | 			xtn->e.out.memstr.be = hawk_becs_open(hawk_sed_getgem(sed), 0, 512); | 
					
						
							|  |  |  | 			if (xtn->e.out.memstr.be == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 	#endif
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_UCS: | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			/* don't store anything to arg->handle */ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			xtn->e.out.memstr.ue = hawk_uecs_open(hawk_sed_getgem(sed), 0, 512); | 
					
						
							|  |  |  | 			if (xtn->e.out.memstr.ue == HAWK_NULL) return -1; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IOSTD_SIO: | 
					
						
							|  |  |  | 			arg->handle = io->u.sio; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			HAWK_ASSERT (!"should never happen - io-type must be one of SIO,FILE,FILEB,FILEU,STR"); | 
					
						
							|  |  |  | 			hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | static hawk_ooi_t read_input_stream (hawk_sed_t* sed, hawk_sed_io_arg_t* arg, hawk_ooch_t* buf, hawk_oow_t len, xtn_in_t* base) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 	hawk_sed_iostd_t* io, * next; | 
					
						
							|  |  |  | 	void* old, * new; | 
					
						
							|  |  |  | 	hawk_ooi_t n = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (len > HAWK_TYPE_MAX(hawk_ooi_t)) len = HAWK_TYPE_MAX(hawk_ooi_t); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	do | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		io = base->cur; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 		if (base == &xtn->s.in && xtn->s.newline_squeezed) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			xtn->s.newline_squeezed = 0; | 
					
						
							|  |  |  | 			goto open_next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		HAWK_ASSERT (io != HAWK_NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		if (io->type == HAWK_SED_IOSTD_OOCS) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		iostd_oocs: | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			n = 0; | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			while (base->mempos < io->u.oocs.len && n < len) | 
					
						
							|  |  |  | 				buf[n++] = io->u.oocs.ptr[base->mempos++]; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		else if (io->type == HAWK_SED_IOSTD_BCS) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 			goto iostd_oocs; | 
					
						
							|  |  |  | 		#else
 | 
					
						
							|  |  |  | 			int m; | 
					
						
							|  |  |  | 			hawk_oow_t mbslen, wcslen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			mbslen = io->u.bcs.len - base->mempos; | 
					
						
							|  |  |  | 			wcslen = len; | 
					
						
							|  |  |  | 			if ((m = hawk_conv_bchars_to_uchars_with_cmgr(&io->u.bcs.ptr[base->mempos], &mbslen, buf, &wcslen, hawk_sed_getcmgr(sed), 0)) <= -1 && m != -2) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EECERR); | 
					
						
							|  |  |  | 				n = -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				base->mempos += mbslen; | 
					
						
							|  |  |  | 				n = wcslen; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (io->type == HAWK_SED_IOSTD_UCS) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 		#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 			goto iostd_oocs; | 
					
						
							|  |  |  | 		#else
 | 
					
						
							|  |  |  | 			int m; | 
					
						
							|  |  |  | 			hawk_oow_t mbslen, wcslen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			wcslen = io->u.ucs.len - base->mempos; | 
					
						
							|  |  |  | 			mbslen = len; | 
					
						
							|  |  |  | 			if ((m = hawk_conv_uchars_to_bchars_with_cmgr(&io->u.ucs.ptr[base->mempos], &wcslen, buf, &mbslen, hawk_sed_getcmgr(sed))) <= -1 && m != -2) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EECERR); | 
					
						
							|  |  |  | 				n = -1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				base->mempos += mbslen; | 
					
						
							|  |  |  | 				n = mbslen; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 		else | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			n = hawk_sio_getoochars(arg->handle, buf, len); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			if (n <= -1) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 				set_eiofil_for_iostd (sed, io); | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 		if (n != 0) | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			if (base == &xtn->s.in) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 				xtn->s.last = buf[n - 1]; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		/* ============================================= */ | 
					
						
							|  |  |  | 		/* == end of file on the current input stream == */ | 
					
						
							|  |  |  | 		/* ============================================= */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (base == &xtn->s.in && xtn->s.last != HAWK_T('\n')) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			/* TODO: different line termination convension */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			buf[0] = HAWK_T('\n'); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			n = 1; | 
					
						
							|  |  |  | 			xtn->s.newline_squeezed = 1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	open_next: | 
					
						
							|  |  |  | 		next = base->cur + 1; | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 		if (next->type == HAWK_SED_IOSTD_NULL) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			/* no next stream available - return 0 */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		old = arg->handle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* try to open the next input stream */ | 
					
						
							|  |  |  | 		if (open_input_stream(sed, arg, next, base) <= -1) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			/* failed to open the next input stream */ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 			set_eiofil_for_iostd (sed, next); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			n = -1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* successfuly opened the next input stream */ | 
					
						
							|  |  |  | 		new = arg->handle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		arg->handle = old; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* close the previous stream */ | 
					
						
							|  |  |  | 		close_main_stream (sed, arg, io); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		arg->handle = new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		base->cur++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	while (1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t s_in (hawk_sed_t* sed, hawk_sed_io_cmd_t cmd, hawk_sed_io_arg_t* arg, hawk_ooch_t* buf, hawk_oow_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		case HAWK_SED_IO_OPEN: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (open_input_stream(sed, arg, xtn->s.in.cur, &xtn->s.in) <= -1) return -1; | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IO_CLOSE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			close_main_stream (sed, arg, xtn->s.in.cur); | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IO_READ: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			return read_input_stream(sed, arg, buf, len, &xtn->s.in); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			HAWK_ASSERT (!"should never happen - cmd must be one of OPEN,CLOSE,READ"); | 
					
						
							|  |  |  | 			hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t x_in (hawk_sed_t* sed, hawk_sed_io_cmd_t cmd, hawk_sed_io_arg_t* arg, hawk_ooch_t* buf, hawk_oow_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sio_t* sio; | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		case HAWK_SED_IO_OPEN: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (arg->path == HAWK_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 				/* main data stream */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 				if (xtn->e.in.ptr == HAWK_NULL) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 					/* HAWK_NULL passed into hawk_sed_exec() for input. open stdin */ | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					sio = open_sio_std(sed, HAWK_SIO_STDIN, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); | 
					
						
							|  |  |  | 					if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 					arg->handle = sio; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 					/* use the input stream handlers passed to hawk_sed_exec() */ | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					if (open_input_stream(sed, arg, xtn->e.in.cur, &xtn->e.in) <= -1) return -1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 				/* sub-stream */ | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 				sio = open_sio_file(sed, arg->path, HAWK_SIO_READ | HAWK_SIO_IGNOREECERR); | 
					
						
							|  |  |  | 				if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 				arg->handle = sio; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IO_CLOSE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (arg->path == HAWK_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* main data stream */ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 				if (xtn->e.in.ptr == HAWK_NULL) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					hawk_sio_close (arg->handle); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					close_main_stream (sed, arg, xtn->e.in.cur); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				hawk_sio_close (arg->handle); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IO_READ: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (arg->path == HAWK_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* main data stream */ | 
					
						
							|  |  |  | 				if (xtn->e.in.ptr == HAWK_NULL) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					hawk_ooi_t n; | 
					
						
							|  |  |  | 					n = hawk_sio_getoochars(arg->handle, buf, len); | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 					if (n <= -1) | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 					{ | 
					
						
							|  |  |  | 						const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed); | 
					
						
							|  |  |  | 						hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to read '%js' - %js", &sio_std_names[HAWK_SIO_STDIN], bem); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					return n; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					return read_input_stream(sed, arg, buf, len, &xtn->e.in); | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				hawk_ooi_t n; | 
					
						
							|  |  |  | 				n = hawk_sio_getoochars(arg->handle, buf, len); | 
					
						
							|  |  |  | 				if (n <= -1) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 					const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed); | 
					
						
							|  |  |  | 					hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to read '%js' - %js", arg->path, bem); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				return n; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			HAWK_ASSERT (!"should never happen - cmd must be one of OPEN,CLOSE,READ"); | 
					
						
							|  |  |  | 			hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static hawk_ooi_t x_out ( | 
					
						
							|  |  |  | 	hawk_sed_t* sed, hawk_sed_io_cmd_t cmd, hawk_sed_io_arg_t* arg, | 
					
						
							|  |  |  | 	hawk_ooch_t* dat, hawk_oow_t len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 	hawk_sio_t* sio; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch (cmd) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		case HAWK_SED_IO_OPEN: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (arg->path == HAWK_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* main data stream */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 				if (xtn->e.out.ptr == HAWK_NULL) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					/* HAWK_NULL passed into hawk_sed_execstd() for output */ | 
					
						
							|  |  |  | 					sio = open_sio_std( | 
					
						
							|  |  |  | 						sed, HAWK_SIO_STDOUT, | 
					
						
							|  |  |  | 						HAWK_SIO_WRITE | | 
					
						
							|  |  |  | 						HAWK_SIO_CREATE | | 
					
						
							|  |  |  | 						HAWK_SIO_TRUNCATE | | 
					
						
							|  |  |  | 						HAWK_SIO_IGNOREECERR | | 
					
						
							|  |  |  | 						HAWK_SIO_LINEBREAK | 
					
						
							|  |  |  | 					); | 
					
						
							|  |  |  | 					if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 					arg->handle = sio; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					if (open_output_stream(sed, arg, xtn->e.out.ptr) <= -1) return -1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				sio = open_sio_file( | 
					
						
							|  |  |  | 					sed, arg->path, | 
					
						
							|  |  |  | 					HAWK_SIO_WRITE | | 
					
						
							|  |  |  | 					HAWK_SIO_CREATE | | 
					
						
							|  |  |  | 					HAWK_SIO_TRUNCATE | | 
					
						
							|  |  |  | 					HAWK_SIO_IGNOREECERR | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 				if (sio == HAWK_NULL) return -1; | 
					
						
							|  |  |  | 				arg->handle = sio; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IO_CLOSE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (arg->path == HAWK_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 				if (xtn->e.out.ptr == HAWK_NULL) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					hawk_sio_close (arg->handle); | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 					close_main_stream (sed, arg, xtn->e.out.ptr); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				hawk_sio_close (arg->handle); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case HAWK_SED_IO_WRITE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			if (arg->path == HAWK_NULL) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* main data stream */ | 
					
						
							|  |  |  | 				if (xtn->e.out.ptr == HAWK_NULL) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					hawk_ooi_t n; | 
					
						
							|  |  |  | 					n = hawk_sio_putoochars(arg->handle, dat, len); | 
					
						
							|  |  |  | 					if (n <= -1) hawk_sed_seterror (sed, HAWK_NULL, HAWK_SED_EIOFIL, &sio_std_names[HAWK_SIO_STDOUT]); | 
					
						
							|  |  |  | 					return n; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					hawk_sed_iostd_t* io = xtn->e.out.ptr; | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 					switch (io->type) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 					#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 						case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 					#endif
 | 
					
						
							|  |  |  | 						case HAWK_SED_IOSTD_BCS: | 
					
						
							|  |  |  | 							if (len > HAWK_TYPE_MAX(hawk_ooi_t)) len = HAWK_TYPE_MAX(hawk_ooi_t); | 
					
						
							|  |  |  | 					#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 							if (hawk_becs_ncat(xtn->e.out.memstr.be, dat, len) == (hawk_oow_t)-1) return -1; | 
					
						
							|  |  |  | 					#else
 | 
					
						
							|  |  |  | 							if (hawk_becs_ncatuchars(xtn->e.out.memstr.be, dat, len, HAWK_NULL) == (hawk_oow_t)-1) return -1; | 
					
						
							|  |  |  | 					#endif
 | 
					
						
							|  |  |  | 							return len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 						case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 					#endif
 | 
					
						
							|  |  |  | 						case HAWK_SED_IOSTD_UCS: | 
					
						
							|  |  |  | 							if (len > HAWK_TYPE_MAX(hawk_ooi_t)) len = HAWK_TYPE_MAX(hawk_ooi_t); | 
					
						
							|  |  |  | 					#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 							if (hawk_uecs_ncat(xtn->e.out.memstr.ue, dat, len) == (hawk_oow_t)-1) return -1; | 
					
						
							|  |  |  | 					#else
 | 
					
						
							|  |  |  | 							if (hawk_uecs_ncatbchars(xtn->e.out.memstr.ue, dat, len, HAWK_NULL, 1) == (hawk_oow_t)-1) return -1; | 
					
						
							|  |  |  | 					#endif
 | 
					
						
							|  |  |  | 							return len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						default: | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 						{ | 
					
						
							|  |  |  | 							hawk_ooi_t n; | 
					
						
							|  |  |  | 							n = hawk_sio_putoochars(arg->handle, dat, len); | 
					
						
							|  |  |  | 							if (n <= -1) set_eiofil_for_iostd (sed, io); | 
					
						
							|  |  |  | 							return n; | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				hawk_ooi_t n; | 
					
						
							|  |  |  | 				n = hawk_sio_putoochars(arg->handle, dat, len); | 
					
						
							|  |  |  | 				if (n <= -1) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2022-04-05 14:26:21 +00:00
										 |  |  | 					const hawk_ooch_t* bem = hawk_sed_backuperrmsg(sed); | 
					
						
							|  |  |  | 					hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_SED_EIOFIL, "unable to write '%js' - %js", arg->path, bem); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				return n; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		default: | 
					
						
							|  |  |  | 			HAWK_ASSERT (!"should never happen - cmd must be one of OPEN,CLOSE,WRITE"); | 
					
						
							|  |  |  | 			hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINTERN); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sed_compstd (hawk_sed_t* sed, hawk_sed_iostd_t in[], hawk_oow_t* count) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 	int ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (in == HAWK_NULL) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		/* it requires a valid array unlike hawk_sed_execstd(). */ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		hawk_sed_seterrbfmt (sed, HAWK_NULL, HAWK_EINVAL, "no input handler provided"); | 
					
						
							|  |  |  | 		if (count) *count = 0; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2024-05-02 22:47:30 +09:00
										 |  |  | 	if (verify_iostd_in(sed, in) <= -1) | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		if (count) *count = 0; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HAWK_MEMSET (&xtn->s, 0, HAWK_SIZEOF(xtn->s)); | 
					
						
							|  |  |  | 	xtn->s.in.ptr = in; | 
					
						
							|  |  |  | 	xtn->s.in.cur = in; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ret = hawk_sed_comp(sed, s_in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (count) *count = xtn->s.in.cur - xtn->s.in.ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clear_sio_names (sed); | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sed_execstd (hawk_sed_t* sed, hawk_sed_iostd_t in[], hawk_sed_iostd_t* out) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 	xtn_t* xtn = GET_XTN(sed); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (in && verify_iostd_in(sed, in) <= -1) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (out) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (out->type != HAWK_SED_IOSTD_FILE && | 
					
						
							|  |  |  | 		    out->type != HAWK_SED_IOSTD_FILEB && | 
					
						
							|  |  |  | 		    out->type != HAWK_SED_IOSTD_FILEU && | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		    out->type != HAWK_SED_IOSTD_OOCS && | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		    out->type != HAWK_SED_IOSTD_SIO) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			hawk_sed_seterrnum (sed, HAWK_NULL, HAWK_EINVAL); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	HAWK_MEMSET (&xtn->e, 0, HAWK_SIZEOF(xtn->e)); | 
					
						
							|  |  |  | 	xtn->e.in.ptr = in; | 
					
						
							|  |  |  | 	xtn->e.in.cur = in; | 
					
						
							|  |  |  | 	xtn->e.out.ptr = out; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	n = hawk_sed_exec(sed, x_in, x_out); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	if (out && out->type == HAWK_SED_IOSTD_OOCS) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		switch (out->type) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 		#if defined(HAWK_OOCH_IS_BCH)
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_BCS: | 
					
						
							|  |  |  | 				if (n >= 0) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					HAWK_ASSERT (xtn->e.out.memstr.be != HAWK_NULL); | 
					
						
							|  |  |  | 					hawk_becs_yield (xtn->e.out.memstr.be, &out->u.bcs, 0); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (xtn->e.out.memstr.be) hawk_becs_close (xtn->e.out.memstr.be); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		#if defined(HAWK_OOCH_IS_UCH)
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_OOCS: | 
					
						
							|  |  |  | 		#endif
 | 
					
						
							|  |  |  | 			case HAWK_SED_IOSTD_UCS: | 
					
						
							|  |  |  | 				if (n >= 0) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					HAWK_ASSERT (xtn->e.out.memstr.ue != HAWK_NULL); | 
					
						
							|  |  |  | 					hawk_uecs_yield (xtn->e.out.memstr.ue, &out->u.ucs, 0); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (xtn->e.out.memstr.ue) hawk_uecs_close (xtn->e.out.memstr.ue); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				/* don't handle other types */ | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clear_sio_names (sed); | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sed_compstdfile (hawk_sed_t* sed, const hawk_ooch_t* file, hawk_cmgr_t* cmgr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t in[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	in[0].type = HAWK_SED_IOSTD_FILE; | 
					
						
							|  |  |  | 	in[0].u.file.path = file; | 
					
						
							|  |  |  | 	in[0].u.file.cmgr = cmgr; | 
					
						
							|  |  |  | 	in[1].type = HAWK_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return hawk_sed_compstd(sed, in, HAWK_NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sed_compstdfileb (hawk_sed_t* sed, const hawk_bch_t* file, hawk_cmgr_t* cmgr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t in[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	in[0].type = HAWK_SED_IOSTD_FILEB; | 
					
						
							|  |  |  | 	in[0].u.fileb.path = file; | 
					
						
							|  |  |  | 	in[0].u.fileb.cmgr = cmgr; | 
					
						
							|  |  |  | 	in[1].type = HAWK_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return hawk_sed_compstd(sed, in, HAWK_NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sed_compstdfileu (hawk_sed_t* sed, const hawk_uch_t* file, hawk_cmgr_t* cmgr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t in[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	in[0].type = HAWK_SED_IOSTD_FILEU; | 
					
						
							|  |  |  | 	in[0].u.fileu.path = file; | 
					
						
							|  |  |  | 	in[0].u.fileu.cmgr = cmgr; | 
					
						
							|  |  |  | 	in[1].type = HAWK_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return hawk_sed_compstd(sed, in, HAWK_NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | int hawk_sed_compstdoocstr (hawk_sed_t* sed, const hawk_ooch_t* script) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t in[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	in[0].type = HAWK_SED_IOSTD_OOCS; | 
					
						
							|  |  |  | 	in[0].u.oocs.ptr = (hawk_ooch_t*)script; | 
					
						
							|  |  |  | 	in[0].u.oocs.len = hawk_count_oocstr(script); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	in[1].type = HAWK_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	return hawk_sed_compstd(sed, in, HAWK_NULL); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | int hawk_sed_compstdoocs (hawk_sed_t* sed, const hawk_oocs_t* script) | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t in[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	in[0].type = HAWK_SED_IOSTD_OOCS; | 
					
						
							|  |  |  | 	in[0].u.oocs = *script; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	in[1].type = HAWK_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	return hawk_sed_compstd(sed, in, HAWK_NULL); | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sed_execstdfile (hawk_sed_t* sed, const hawk_ooch_t* infile, const hawk_ooch_t* outfile, hawk_cmgr_t* cmgr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t in[2]; | 
					
						
							|  |  |  | 	hawk_sed_iostd_t out; | 
					
						
							|  |  |  | 	hawk_sed_iostd_t* pin = HAWK_NULL, * pout = HAWK_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (infile) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		in[0].type = HAWK_SED_IOSTD_FILE; | 
					
						
							|  |  |  | 		in[0].u.file.path = infile; | 
					
						
							|  |  |  | 		in[0].u.file.cmgr = cmgr; | 
					
						
							|  |  |  | 		in[1].type = HAWK_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 		pin = in; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (outfile) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		out.type = HAWK_SED_IOSTD_FILE; | 
					
						
							|  |  |  | 		out.u.file.path = outfile; | 
					
						
							|  |  |  | 		out.u.file.cmgr = cmgr; | 
					
						
							|  |  |  | 		pout = &out; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return hawk_sed_execstd(sed, pin, pout); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int hawk_sed_execstdxstr (hawk_sed_t* sed, const hawk_oocs_t* instr, hawk_oocs_t* outstr, hawk_cmgr_t* cmgr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	hawk_sed_iostd_t in[2]; | 
					
						
							|  |  |  | 	hawk_sed_iostd_t out; | 
					
						
							|  |  |  | 	int n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	in[0].type = HAWK_SED_IOSTD_OOCS; | 
					
						
							|  |  |  | 	in[0].u.oocs = *instr; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 	in[1].type = HAWK_SED_IOSTD_NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	out.type = HAWK_SED_IOSTD_OOCS; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	n = hawk_sed_execstd(sed, in, &out); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 10:46:00 +00:00
										 |  |  | 	if (n >= 0) *outstr = out.u.oocs; | 
					
						
							| 
									
										
										
										
											2022-03-31 17:14:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return n; | 
					
						
							|  |  |  | } |