renamed stix_prim_mod_t to stix_mod_t and made relevant changes
added stix_bcstoucs() and stix_ucstobcs() added stix_setcmgr() and stix_getcmgr()
This commit is contained in:
		| @ -1,18 +1,24 @@ | ||||
| #class(#word) Stdio(Object) | ||||
| ## #class(#byte) Stdio(Object) from 'stdio'. | ||||
|  | ||||
| #class(#byte) Stdio(Object) | ||||
| { | ||||
| 	#method(#class) _newInstSize | ||||
| 	{ | ||||
| 		<primitive: #stdio_newInstSize> | ||||
| 	} | ||||
|  | ||||
| 	#method(#class) new: size | ||||
| 	{ | ||||
| 		##self prohibited | ||||
| 		##raise exception. prohibited... | ||||
| 		^(super new: 1) | ||||
| 		^(super new: (self _newInstSize)) | ||||
| 	} | ||||
|  | ||||
| 	#method(#class) new | ||||
| 	{ | ||||
| 		##self prohibited | ||||
| 		##raise exception. prohibited... | ||||
| 		^(super new: 1) | ||||
| 		^(super new: (self _newInstSize)) | ||||
| 	} | ||||
|  | ||||
| 	#method(#class) open: name for: mode | ||||
| @ -29,14 +35,17 @@ | ||||
| 	{ | ||||
| 		<primitive: #stdio_close> | ||||
| 	} | ||||
| } | ||||
|  | ||||
| 	#method xxx | ||||
| #extend Stdio | ||||
| { | ||||
| 	#method xxxx | ||||
| 	{ | ||||
| 		self basicSize dump. | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #class(#word) Stdio2(Stdio) | ||||
| #class(#byte) Stdio2(Stdio) | ||||
| { | ||||
| 	#method(#class) new | ||||
| 	{ | ||||
|  | ||||
| @ -126,7 +126,7 @@ | ||||
|  | ||||
| 		##v1 := Stdio2 open: '/tmp/1.txt' for: 'w+'. | ||||
| 		v1 := Stdio2 new open: '/tmp/1.txt' for: 'w+'. | ||||
| 		v1 xxx. | ||||
| 		v1 xxxx. | ||||
| 		v1 close. | ||||
| 		nil isNil ifTrue: [ 'NIL NIL NIL' dump. ]. | ||||
| 		(Apex new) notNil ifTrue: [ 'APEX NIL NIL NIL' dump. ]. | ||||
|  | ||||
							
								
								
									
										119
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							| @ -2397,7 +2397,7 @@ static int prim_ffi_open (stix_t* stix, stix_ooi_t nargs) | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!stix->vmprim.mod_open) | ||||
| 	if (!stix->vmprim.dl_open) | ||||
| 	{ | ||||
| 		/* TODO: more info on error */ | ||||
| 		return 0; | ||||
| @ -2405,7 +2405,7 @@ static int prim_ffi_open (stix_t* stix, stix_ooi_t nargs) | ||||
|  | ||||
|  | ||||
| /* TODO: check null-termination... */ | ||||
| 	handle = stix->vmprim.mod_open (stix, ((stix_oop_char_t)arg)->slot); | ||||
| 	handle = stix->vmprim.dl_open (stix, ((stix_oop_char_t)arg)->slot); | ||||
| 	if (!handle) | ||||
| 	{ | ||||
| 		/* TODO: more info on error */ | ||||
| @ -2439,7 +2439,7 @@ static int prim_ffi_close (stix_t* stix, stix_ooi_t nargs) | ||||
| 	STIX_STACK_POP (stix); | ||||
|  | ||||
| 	handle = (void*)STIX_OOP_TO_SMOOI(arg); /* TODO: how to store void* ???. fix this not to loose accuracy */ | ||||
| 	if (stix->vmprim.mod_close) stix->vmprim.mod_close (stix, handle); | ||||
| 	if (stix->vmprim.dl_close) stix->vmprim.dl_close (stix, handle); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| @ -2538,7 +2538,7 @@ STIX_DEBUG2 (stix, "CALL MODE 222 ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSU | ||||
| 					stix_bch_t bcs[1024]; | ||||
|  | ||||
| 					ucslen = STIX_OBJ_GET_SIZE(arr->slot[i - 2]); | ||||
| 					stix_ucstoutf8 (((stix_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */ | ||||
| 					stix_oocstobcs (stix, ((stix_oop_char_t)arr->slot[i - 2])->slot, &ucslen, bcs, &bcslen); /* proper string conversion */ | ||||
|  | ||||
| 					bcs[bcslen] = '\0'; | ||||
| 					dcArgPointer (dc, bcs); | ||||
| @ -2596,7 +2596,7 @@ STIX_DEBUG2 (stix, "CALL ERROR %d %d\n", dcGetError (dc), DC_ERROR_UNSUPPORTED_M | ||||
| 				char* r = dcCallPointer (dc, f); | ||||
|  | ||||
| 				bcslen = strlen(r);  | ||||
| 				stix_utf8toucs (r, &bcslen, ucs, &ucslen); /* proper string conversion */ | ||||
| 				stix_bcstooocs (stix, r, &bcslen, ucs, &ucslen); /* proper string conversion */ | ||||
|  | ||||
| 				s = stix_makestring(stix, ucs, ucslen) | ||||
| 				if (!s)  | ||||
| @ -2646,12 +2646,12 @@ STIX_DEBUG0 (stix, "wrong function name...\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (!stix->vmprim.mod_getsym) | ||||
| 	if (!stix->vmprim.dl_getsym) | ||||
| 	{ | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	sym = stix->vmprim.mod_getsym (stix, (void*)STIX_OOP_TO_SMOOI(hnd), ((stix_oop_char_t)fun)->slot); | ||||
| 	sym = stix->vmprim.dl_getsym (stix, (void*)STIX_OOP_TO_SMOOI(hnd), ((stix_oop_char_t)fun)->slot); | ||||
| 	if (!sym) | ||||
| 	{ | ||||
| 		return 0; | ||||
| @ -2755,49 +2755,35 @@ int stix_getprimno (stix_t* stix, const stix_ooch_t* ptr, stix_oow_t len) | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_ooch_t* name, stix_oow_t len) | ||||
| #define MOD_PREFIX "stix_mod_" | ||||
| #define MOD_PREFIX_LEN 9 | ||||
|  | ||||
| static stix_mod_data_t* open_prim_module (stix_t* stix, const stix_ooch_t* name, stix_oow_t namelen) | ||||
| { | ||||
| 	stix_rbt_pair_t* pair; | ||||
| 	stix_prim_mod_data_t* mdp; | ||||
| 	const stix_ooch_t* sep; | ||||
| 	stix_oow_t mod_name_len; | ||||
| 	stix_prim_impl_t handler; | ||||
| 	int n; | ||||
|  | ||||
| 	sep = stix_findoochar (name, len, '_'); | ||||
| 	STIX_ASSERT (sep != STIX_NULL); | ||||
| 	mod_name_len = sep - name; | ||||
|  | ||||
| 	pair = stix_rbt_search (&stix->pmtable, name, mod_name_len); | ||||
| 	if (pair) | ||||
| 	{ | ||||
| 		mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		stix_prim_mod_data_t md; | ||||
| 		stix_prim_mod_load_t load = STIX_NULL; | ||||
| 	stix_mod_data_t* mdp; | ||||
| 	stix_mod_data_t md; | ||||
| 	stix_mod_load_t load = STIX_NULL; | ||||
|  | ||||
| 	/* maximum module name length is STIX_MOD_NAME_LEN_MAX.  | ||||
| 		 * 16 is decomposed to 14 + 1 + 1. | ||||
| 		 *   14 for stix_prim_mod_. | ||||
| 		 *   1 for _ at the end when stix_prim_mod_xxx_ is attempted. | ||||
| 	 *   MOD_PREFIX_LEN for MOD_PREFIX | ||||
| 	 *   1 for _ at the end when stix_mod_xxx_ is attempted. | ||||
| 	 *   1 for the terminating '\0'. | ||||
| 	 */ | ||||
| 		stix_ooch_t buf[STIX_MOD_NAME_LEN_MAX + 16];  | ||||
| 	stix_ooch_t buf[MOD_PREFIX_LEN + STIX_MOD_NAME_LEN_MAX + 1 + 1];  | ||||
|  | ||||
| 	/* the terminating null isn't needed in buf here */ | ||||
| 		stix_copybchtooochars (buf, "stix_prim_mod_", 14);  | ||||
| 	stix_copybchtooochars (buf, MOD_PREFIX, MOD_PREFIX_LEN);  | ||||
|  | ||||
| 		if (mod_name_len > STIX_COUNTOF(buf) - 16) | ||||
| 	if (namelen > STIX_COUNTOF(buf) - (MOD_PREFIX_LEN + 1 + 1)) | ||||
| 	{ | ||||
| 		/* module name too long  */ | ||||
| 		stix->errnum = STIX_EINVAL; /* TODO: change the  error number to something more specific */ | ||||
| 		return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 		stix_copyoochars (&buf[14], name, mod_name_len); | ||||
| 		buf[14 + mod_name_len] = '\0'; | ||||
| 	stix_copyoochars (&buf[MOD_PREFIX_LEN], name, namelen); | ||||
| 	buf[MOD_PREFIX_LEN + namelen] = '\0'; | ||||
|  | ||||
| #if defined(STIX_ENABLE_STATIC_MODULE) | ||||
| 	/* attempt to find a statically linked module */ | ||||
| @ -2807,7 +2793,7 @@ static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_ooch_t* name | ||||
| 	/* TODO: binary search ... */ | ||||
| 	for (n = 0; n < STIX_COUNTOF(static_modtab); n++) | ||||
| 	{ | ||||
| 			if (stix_compoocstr (static_modtab[n].modname, name) == 0)  | ||||
| 		if (stix_compoocstr (static_modtab[n].modname, name, name_len....) == 0)  | ||||
| 		{ | ||||
| 			load = static_modtab[n].modload; | ||||
| 			break; | ||||
| @ -2825,11 +2811,12 @@ static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_ooch_t* name | ||||
| 		/* found the module in the staic module table */ | ||||
|  | ||||
| 		STIX_MEMSET (&md, 0, STIX_SIZEOF(md)); | ||||
| 		stix_copyoochars (md.name, name, namelen); | ||||
| 		/* Note md.handle is STIX_NULL for a static module */ | ||||
|  | ||||
| 		/* i copy-insert 'md' into the table before calling 'load'. | ||||
| 		 * to pass the same address to load(), query(), etc */ | ||||
| 			pair = stix_rbt_insert (stix->modtab, name, mod_name_len, &md, STIX_SIZEOF(md)); | ||||
| 		pair = stix_rbt_insert (stix->modtab, name, namelen, &md, STIX_SIZEOF(md)); | ||||
| 		if (pair == STIX_NULL) | ||||
| 		{ | ||||
| 			stix->errnum = STIX_ESYSMEM; | ||||
| @ -2843,61 +2830,97 @@ static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_ooch_t* name | ||||
| 			return STIX_NULL; | ||||
| 		} | ||||
|  | ||||
| 			goto done; | ||||
| 		return mdp; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	/* attempt to find an external module */ | ||||
| 	STIX_MEMSET (&md, 0, STIX_SIZEOF(md)); | ||||
| 		if (stix->vmprim.mod_open && stix->vmprim.mod_getsym && stix->vmprim.mod_close) | ||||
| 	stix_copyoochars (md.name, name, namelen); | ||||
| 	if (stix->vmprim.dl_open && stix->vmprim.dl_getsym && stix->vmprim.dl_close) | ||||
| 	{ | ||||
| 			md.handle = stix->vmprim.mod_open (stix, &buf[14]); | ||||
| 		md.handle = stix->vmprim.dl_open (stix, &buf[MOD_PREFIX_LEN]); | ||||
| 	} | ||||
|  | ||||
| 	if (md.handle == STIX_NULL)  | ||||
| 	{ | ||||
| 		STIX_DEBUG2 (stix, "Cannot open a module [%.*S]\n", namelen, name); | ||||
| 		stix->errnum = STIX_ENOENT; /* TODO: be more descriptive about the error */ | ||||
| 		return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 		/* attempt to get stix_prim_mod_xxx */ | ||||
| 		load = stix->vmprim.mod_getsym (stix, md.handle, buf); | ||||
| 	/* attempt to get stix_mod_xxx */ | ||||
| 	load = stix->vmprim.dl_getsym (stix, md.handle, buf); | ||||
| 	if (!load)  | ||||
| 	{ | ||||
| 		STIX_DEBUG3 (stix, "Cannot get a module symbol [%S] in [%.*S]\n", buf, namelen, name); | ||||
| 		stix->errnum = STIX_ENOENT; /* TODO: be more descriptive about the error */ | ||||
| 			stix->vmprim.mod_close (stix, md.handle); | ||||
| 		stix->vmprim.dl_close (stix, md.handle); | ||||
| 		return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* i copy-insert 'md' into the table before calling 'load'. | ||||
| 	 * to pass the same address to load(), query(), etc */ | ||||
| 		pair = stix_rbt_insert (&stix->pmtable, (void*)name, mod_name_len, &md, STIX_SIZEOF(md)); | ||||
| 	pair = stix_rbt_insert (&stix->pmtable, (void*)name, namelen, &md, STIX_SIZEOF(md)); | ||||
| 	if (pair == STIX_NULL) | ||||
| 	{ | ||||
| 		STIX_DEBUG2 (stix, "Cannot register a module [%.*S]\n", namelen, name); | ||||
| 		stix->errnum = STIX_ESYSMEM; | ||||
| 			stix->vmprim.mod_close (stix, md.handle); | ||||
| 		stix->vmprim.dl_close (stix, md.handle); | ||||
| 		return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 		mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair); | ||||
| 	mdp = (stix_mod_data_t*)STIX_RBT_VPTR(pair); | ||||
| 	if (load (stix, &mdp->mod) <= -1) | ||||
| 	{ | ||||
| 		STIX_DEBUG3 (stix, "Module function [%S] returned failure in [%.*S]\n", buf, namelen, name); | ||||
| 		stix->errnum = STIX_ENOENT; /* TODO: proper error code and handling */ | ||||
| 			stix_rbt_delete (&stix->pmtable, name, mod_name_len); | ||||
| 			stix->vmprim.mod_close (stix, mdp->handle); | ||||
| 		stix_rbt_delete (&stix->pmtable, name, namelen); | ||||
| 		stix->vmprim.dl_close (stix, mdp->handle); | ||||
| 		return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 	STIX_DEBUG2 (stix, "Opened a module [%S] - %p\n", mdp->name, mdp->handle); | ||||
| 	/* the module loader must ensure to set a proper query handler */ | ||||
| 	STIX_ASSERT (mdp->mod.query != STIX_NULL); | ||||
|  | ||||
| 	return mdp; | ||||
| } | ||||
|  | ||||
| static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_ooch_t* name, stix_oow_t len) | ||||
| { | ||||
| 	stix_rbt_pair_t* pair; | ||||
| 	stix_mod_data_t* mdp; | ||||
| 	const stix_ooch_t* sep; | ||||
| 	stix_oow_t mod_name_len; | ||||
| 	stix_prim_impl_t handler; | ||||
| 	int n; | ||||
|  | ||||
| 	sep = stix_findoochar (name, len, '_'); | ||||
| 	STIX_ASSERT (sep != STIX_NULL); | ||||
| 	mod_name_len = sep - name; | ||||
|  | ||||
| 	pair = stix_rbt_search (&stix->pmtable, name, mod_name_len); | ||||
| 	if (pair) | ||||
| 	{ | ||||
| 		mdp = (stix_mod_data_t*)STIX_RBT_VPTR(pair); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		mdp = open_prim_module (stix, name, mod_name_len); | ||||
| 		if (!mdp) return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| done: | ||||
| 	if ((handler = mdp->mod.query (stix, &mdp->mod, sep + 1)) == STIX_NULL)  | ||||
| 	{ | ||||
| 		/* the primitive function is not found */ | ||||
| 		STIX_DEBUG3 (stix, "Cannot find a primitive function [%S] in a module [%.*S]\n", sep + 1, mod_name_len, name); | ||||
| 		stix->errnum = STIX_ENOENT; /* TODO: proper error code and handling */ | ||||
| 		return STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 	STIX_DEBUG4 (stix, "Found a primitive function [%S] in a module [%.*S] - %p\n", sep + 1, mod_name_len, name, handler); | ||||
| 	return handler; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -425,7 +425,7 @@ reswitch: | ||||
| 			/* get the length */ | ||||
| 			for (bslen = 0; bsp[bslen]; bslen++); | ||||
|  | ||||
| 			if (stix_utf8toucs (bsp, &bslen, STIX_NULL, &slen) <= -1) | ||||
| 			if (stix_bcstooocs (stix, bsp, &bslen, STIX_NULL, &slen) <= -1) | ||||
| 			{  | ||||
| 				/* conversion error */ | ||||
| 				stix->errnum = STIX_EECERR; | ||||
| @ -450,7 +450,7 @@ reswitch: | ||||
| 					conv_len = STIX_COUNTOF(conv_buf); | ||||
|  | ||||
| 					/* this must not fail since the dry-run above was successful */ | ||||
| 					stix_utf8toucs (&bsp[tot_len], &src_len, conv_buf, &conv_len); | ||||
| 					stix_bcstooocs (stix, &bsp[tot_len], &src_len, conv_buf, &conv_len); | ||||
| 					tot_len += src_len; | ||||
|  | ||||
| 					if (conv_len > n) conv_len = n; | ||||
|  | ||||
| @ -144,7 +144,7 @@ static STIX_INLINE stix_ooi_t open_input (stix_t* stix, stix_ioarg_t* arg) | ||||
| 		stix_oow_t bcslen = STIX_COUNTOF(bcs); | ||||
| 		stix_oow_t ucslen = ~(stix_oow_t)0; | ||||
|  | ||||
| 		if (stix_ucstoutf8 (arg->name, &ucslen, bcs, &bcslen) <= -1) | ||||
| 		if (stix_oocstobcs (stix, arg->name, &ucslen, bcs, &bcslen) <= -1) | ||||
| 		{ | ||||
| 			stix_seterrnum (stix, STIX_EECERR); | ||||
| 			return -1; | ||||
| @ -231,7 +231,8 @@ static STIX_INLINE stix_ooi_t read_input (stix_t* stix, stix_ioarg_t* arg) | ||||
|  | ||||
| 	bcslen = bb->len; | ||||
| 	ucslen = STIX_COUNTOF(arg->buf); | ||||
| 	x = stix_utf8toucs (bb->buf, &bcslen, arg->buf, &ucslen); | ||||
| 	x = stix_bcstooocs (stix, bb->buf, &bcslen, arg->buf, &ucslen); | ||||
| 	x = stix_bcstooocs (stix, bb->buf, &bcslen, arg->buf, &ucslen); | ||||
| 	if (x <= -1 && ucslen <= 0) | ||||
| 	{ | ||||
| 		stix_seterrnum (stix, STIX_EECERR); | ||||
| @ -264,7 +265,7 @@ static stix_ooi_t input_handler (stix_t* stix, stix_iocmd_t cmd, stix_ioarg_t* a | ||||
| } | ||||
| /* ========================================================================= */ | ||||
|  | ||||
| static void* mod_open (stix_t* stix, const stix_ooch_t* name) | ||||
| static void* dl_open (stix_t* stix, const stix_ooch_t* name) | ||||
| { | ||||
| #if defined(USE_LTDL) | ||||
| /* TODO: support various platforms */ | ||||
| @ -279,7 +280,7 @@ static void* mod_open (stix_t* stix, const stix_ooch_t* name) | ||||
|  * Attempting /home/hyung-hwan/xxx/lib/libstix-libc.so.6 followed by libc.so.6 is bad. | ||||
|  * Need to accept the type or flags? | ||||
|  * | ||||
|  * mod_open (stix, "xxxx", STIX_MOD_EXTERNAL); | ||||
|  * dl_open (stix, "xxxx", STIX_MOD_EXTERNAL); | ||||
|  * if external, don't use DEFAULT_MODPERFIX and MODPOSTFIX??? | ||||
|  */ | ||||
|  | ||||
| @ -288,7 +289,7 @@ static void* mod_open (stix_t* stix, const stix_ooch_t* name) | ||||
| /* TODO: proper error checking and overflow checking */ | ||||
| 	ucslen = ~(stix_oow_t)0; | ||||
| 	bcslen = STIX_COUNTOF(buf) - len; | ||||
| 	stix_ucstoutf8 (name, &ucslen, &buf[len], &bcslen); | ||||
| 	stix_oocstobcs (stix, name, &ucslen, &buf[len], &bcslen); | ||||
|  | ||||
| 	stix_copybcstr (&buf[bcslen + len], STIX_COUNTOF(buf) - bcslen - len, STIX_DEFAULT_MODPOSTFIX); | ||||
|  | ||||
| @ -312,7 +313,7 @@ static void* mod_open (stix_t* stix, const stix_ooch_t* name) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static void mod_close (stix_t* stix, void* handle) | ||||
| static void dl_close (stix_t* stix, void* handle) | ||||
| { | ||||
| 	STIX_DEBUG1 (stix, "Closed module handle %p\n", handle); | ||||
| #if defined(USE_LTDL) | ||||
| @ -328,7 +329,7 @@ static void mod_close (stix_t* stix, void* handle) | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static void* mod_getsym (stix_t* stix, void* handle, const stix_ooch_t* name) | ||||
| static void* dl_getsym (stix_t* stix, void* handle, const stix_ooch_t* name) | ||||
| { | ||||
| #if defined(USE_LTDL) | ||||
| 	stix_bch_t buf[1024]; /* TODO: use a proper buffer. dynamically allocated if conversion result in too a large value */ | ||||
| @ -340,7 +341,7 @@ static void* mod_getsym (stix_t* stix, void* handle, const stix_ooch_t* name) | ||||
|  | ||||
| 	ucslen = ~(stix_oow_t)0; | ||||
| 	bcslen = STIX_COUNTOF(buf) - 2; | ||||
| 	stix_ucstoutf8 (name, &ucslen, &buf[1], &bcslen); | ||||
| 	stix_oocstobcs (stix, name, &ucslen, &buf[1], &bcslen); /* TODO: error check */ | ||||
| 	symname = &buf[1]; | ||||
| 	sym = lt_dlsym (handle, symname); | ||||
| 	if (!sym) | ||||
| @ -435,7 +436,7 @@ static void log_write (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, st | ||||
| 		ucslen = len; | ||||
| 		bcslen = STIX_COUNTOF(buf); | ||||
|  | ||||
| 		n = stix_ucstoutf8 (&msg[msgidx], &ucslen, buf, &bcslen); | ||||
| 		n = stix_oocstobcs (stix, &msg[msgidx], &ucslen, buf, &bcslen); | ||||
| 		if (n == 0 || n == -2) | ||||
| 		{ | ||||
| 			/* n = 0:  | ||||
| @ -656,9 +657,9 @@ int main (int argc, char* argv[]) | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	vmprim.mod_open = mod_open; | ||||
| 	vmprim.mod_close = mod_close; | ||||
| 	vmprim.mod_getsym = mod_getsym; | ||||
| 	vmprim.dl_open = dl_open; | ||||
| 	vmprim.dl_close = dl_close; | ||||
| 	vmprim.dl_getsym = dl_getsym; | ||||
| 	vmprim.log_write = log_write; | ||||
|  | ||||
|  | ||||
| @ -728,7 +729,7 @@ int main (int argc, char* argv[]) | ||||
| 				{ | ||||
| 					bcslen = STIX_COUNTOF(bcs); | ||||
| 					ucslen = ~(stix_oow_t)0; | ||||
| 					if (stix_ucstoutf8 (synerr.loc.file, &ucslen, bcs, &bcslen) >= 0) | ||||
| 					if (stix_oocstobcs (stix, synerr.loc.file, &ucslen, bcs, &bcslen) >= 0) | ||||
| 					{ | ||||
| 						printf ("%.*s ", (int)bcslen, bcs); | ||||
| 					} | ||||
| @ -747,7 +748,7 @@ int main (int argc, char* argv[]) | ||||
| 					bcslen = STIX_COUNTOF(bcs); | ||||
| 					ucslen = synerr.tgt.len; | ||||
|  | ||||
| 					if (stix_ucstoutf8 (synerr.tgt.ptr, &ucslen, bcs, &bcslen) >= 0) | ||||
| 					if (stix_oocstobcs (stix, synerr.tgt.ptr, &ucslen, bcs, &bcslen) >= 0) | ||||
| 					{ | ||||
| 						printf (" [%.*s]", (int)bcslen, bcs); | ||||
| 					} | ||||
|  | ||||
| @ -147,21 +147,8 @@ STIX_EXPORT stix_oow_t stix_countbcstr ( | ||||
| 	const stix_bch_t* str | ||||
| ); | ||||
|  | ||||
|  | ||||
|  | ||||
| /* ========================================================================= */ | ||||
| /* utf8.c                                                                    */ | ||||
| /* ========================================================================= */ | ||||
| STIX_EXPORT stix_oow_t stix_uctoutf8 ( | ||||
| 	stix_uch_t    uc, | ||||
| 	stix_bch_t*   utf8, | ||||
| 	stix_oow_t    size | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT stix_oow_t stix_utf8touc ( | ||||
| 	const stix_bch_t* utf8, | ||||
| 	stix_oow_t        size, | ||||
| 	stix_uch_t*       uc | ||||
| STIX_EXPORT stix_cmgr_t* stix_getutf8cmgr ( | ||||
| 	void | ||||
| ); | ||||
|  | ||||
| /** | ||||
| @ -235,6 +222,22 @@ STIX_EXPORT int stix_utf8toucs ( | ||||
| 	stix_oow_t*         ucslen | ||||
| ); | ||||
|  | ||||
|  | ||||
| /* ========================================================================= */ | ||||
| /* utf8.c                                                                    */ | ||||
| /* ========================================================================= */ | ||||
| STIX_EXPORT stix_oow_t stix_uctoutf8 ( | ||||
| 	stix_uch_t    uc, | ||||
| 	stix_bch_t*   utf8, | ||||
| 	stix_oow_t    size | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT stix_oow_t stix_utf8touc ( | ||||
| 	const stix_bch_t* utf8, | ||||
| 	stix_oow_t        size, | ||||
| 	stix_uch_t*       uc | ||||
| ); | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| @ -26,7 +26,6 @@ | ||||
|  | ||||
| #include "stix-prv.h" | ||||
|  | ||||
|  | ||||
| stix_t* stix_open (stix_mmgr_t* mmgr, stix_oow_t xtnsize, stix_oow_t heapsize, const stix_vmprim_t* vmprim, stix_errnum_t* errnum) | ||||
| { | ||||
| 	stix_t* stix; | ||||
| @ -87,6 +86,7 @@ int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_oow_t heapsz, const stix_vm | ||||
| { | ||||
| 	STIX_MEMSET (stix, 0, STIX_SIZEOF(*stix)); | ||||
| 	stix->mmgr = mmgr; | ||||
| 	stix->cmgr = stix_getutf8cmgr (); | ||||
| 	stix->vmprim = *vmprim; | ||||
|  | ||||
| 	stix->option.log_mask = ~0u; | ||||
| @ -123,11 +123,16 @@ oops: | ||||
| static stix_rbt_walk_t unload_primitive_module (stix_rbt_t* rbt, stix_rbt_pair_t* pair, void* ctx) | ||||
| { | ||||
| 	stix_t* stix = (stix_t*)ctx; | ||||
| 	stix_prim_mod_data_t* md; | ||||
| 	stix_mod_data_t* md; | ||||
|  | ||||
| 	md = STIX_RBT_VPTR(pair); | ||||
| 	if (md->mod.unload) md->mod.unload (stix, &md->mod); | ||||
| 	if (md->handle) stix->vmprim.mod_close (stix, md->handle); | ||||
| 	if (md->handle)  | ||||
| 	{ | ||||
| 		stix->vmprim.dl_close (stix, md->handle); | ||||
| 		STIX_DEBUG2 (stix, "Closed a module [%S] - %p\n", md->name, md->handle); | ||||
| 		md->handle = STIX_NULL; | ||||
| 	} | ||||
|  | ||||
| 	return STIX_RBT_WALK_FORWARD; | ||||
| } | ||||
| @ -190,6 +195,16 @@ stix_mmgr_t* stix_getmmgr (stix_t* stix) | ||||
| 	return stix->mmgr; | ||||
| } | ||||
|  | ||||
| stix_cmgr_t* stix_getcmgr (stix_t* stix) | ||||
| { | ||||
| 	return stix->cmgr; | ||||
| } | ||||
|  | ||||
| void stix_setcmgr (stix_t* stix, stix_cmgr_t* cmgr) | ||||
| { | ||||
| 	stix->cmgr = cmgr; | ||||
| } | ||||
|  | ||||
| void* stix_getxtn (stix_t* stix) | ||||
| { | ||||
| 	return (void*)(stix + 1); | ||||
|  | ||||
| @ -681,19 +681,17 @@ typedef struct stix_t stix_t; | ||||
| /* ========================================================================= | ||||
|  * VIRTUAL MACHINE PRIMITIVES | ||||
|  * ========================================================================= */ | ||||
| #define STIX_MOD_NAME_LEN_MAX 120 | ||||
|  | ||||
| typedef void* (*stix_mod_open_t) (stix_t* stix, const stix_ooch_t* name); | ||||
| typedef void (*stix_mod_close_t) (stix_t* stix, void* handle); | ||||
| typedef void* (*stix_mod_getsym_t) (stix_t* stix, void* handle, const stix_ooch_t* name); | ||||
| typedef void* (*stix_vmprim_opendl_t) (stix_t* stix, const stix_ooch_t* name); | ||||
| typedef void (*stix_vmprim_closedl_t) (stix_t* stix, void* handle); | ||||
| typedef void* (*stix_vmprim_getdlsym_t) (stix_t* stix, void* handle, const stix_ooch_t* name); | ||||
|  | ||||
| typedef void (*stix_log_write_t) (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, stix_oow_t len); | ||||
|  | ||||
| struct stix_vmprim_t | ||||
| { | ||||
| 	stix_mod_open_t mod_open; | ||||
| 	stix_mod_close_t mod_close; | ||||
| 	stix_mod_getsym_t mod_getsym; | ||||
| 	stix_vmprim_opendl_t dl_open; | ||||
| 	stix_vmprim_closedl_t dl_close; | ||||
| 	stix_vmprim_getdlsym_t dl_getsym; | ||||
| 	stix_log_write_t log_write; | ||||
| }; | ||||
|  | ||||
| @ -725,39 +723,42 @@ struct stix_cb_t | ||||
| /* ========================================================================= | ||||
|  * PRIMITIVE MODULE MANIPULATION | ||||
|  * ========================================================================= */ | ||||
| #define STIX_MOD_NAME_LEN_MAX 120 | ||||
|  | ||||
| typedef int (*stix_prim_impl_t) (stix_t* stix, stix_ooi_t nargs); | ||||
|  | ||||
| typedef struct stix_prim_mod_t stix_prim_mod_t; | ||||
| typedef struct stix_mod_t stix_mod_t; | ||||
|  | ||||
| typedef int (*stix_prim_mod_load_t) ( | ||||
| typedef int (*stix_mod_load_t) ( | ||||
| 	stix_t*     stix, | ||||
| 	stix_prim_mod_t* mod | ||||
| 	stix_mod_t* mod | ||||
| ); | ||||
|  | ||||
| typedef stix_prim_impl_t (*stix_prim_mod_query_t) ( | ||||
| typedef stix_prim_impl_t (*stix_mod_query_t) ( | ||||
| 	stix_t*           stix, | ||||
| 	stix_prim_mod_t*  mod, | ||||
| 	stix_mod_t*       mod, | ||||
| 	const stix_uch_t* name | ||||
| ); | ||||
|  | ||||
| typedef void (*stix_prim_mod_unload_t) ( | ||||
| typedef void (*stix_mod_unload_t) ( | ||||
| 	stix_t*     stix, | ||||
| 	stix_prim_mod_t* mod | ||||
| 	stix_mod_t* mod | ||||
| ); | ||||
|  | ||||
| struct stix_prim_mod_t | ||||
| struct stix_mod_t | ||||
| { | ||||
| 	stix_prim_mod_unload_t unload; | ||||
| 	stix_prim_mod_query_t  query; | ||||
| 	stix_mod_unload_t unload; | ||||
| 	stix_mod_query_t  query; | ||||
| 	void*             ctx; | ||||
| }; | ||||
|  | ||||
| struct stix_prim_mod_data_t  | ||||
| struct stix_mod_data_t  | ||||
| { | ||||
| 	stix_ooch_t name[STIX_MOD_NAME_LEN_MAX + 1]; | ||||
| 	void*       handle; | ||||
| 	stix_prim_mod_t mod; | ||||
| 	stix_mod_t  mod; | ||||
| }; | ||||
| typedef struct stix_prim_mod_data_t stix_prim_mod_data_t; | ||||
| typedef struct stix_mod_data_t stix_mod_data_t; | ||||
|  | ||||
| /* ========================================================================= | ||||
|  * STIX VM | ||||
| @ -769,6 +770,7 @@ typedef struct stix_compiler_t stix_compiler_t; | ||||
| struct stix_t | ||||
| { | ||||
| 	stix_mmgr_t*  mmgr; | ||||
| 	stix_cmgr_t*  cmgr; | ||||
| 	stix_errnum_t errnum; | ||||
|  | ||||
| 	struct | ||||
| @ -982,18 +984,18 @@ STIX_EXPORT stix_t* stix_open ( | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT void stix_close ( | ||||
| 	stix_t* vm | ||||
| 	stix_t* stix | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT int stix_init ( | ||||
| 	stix_t*              vm, | ||||
| 	stix_t*              stix, | ||||
| 	stix_mmgr_t*         mmgr, | ||||
| 	stix_oow_t           heapsize, | ||||
| 	const stix_vmprim_t* vmprim | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT void stix_fini ( | ||||
| 	stix_t* vm | ||||
| 	stix_t* stix | ||||
| ); | ||||
|  | ||||
|  | ||||
| @ -1001,6 +1003,15 @@ STIX_EXPORT stix_mmgr_t* stix_getmmgr ( | ||||
| 	stix_t* stix | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT stix_cmgr_t* stix_getcmgr ( | ||||
| 	stix_t* stix | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT void stix_setcmgr ( | ||||
| 	stix_t*      stix, | ||||
| 	stix_cmgr_t* cmgr | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT void* stix_getxtn ( | ||||
| 	stix_t* stix | ||||
| ); | ||||
| @ -1153,6 +1164,31 @@ STIX_EXPORT void stix_freemem ( | ||||
| ); | ||||
|  | ||||
|  | ||||
| #if defined(STIX_OOCH_IS_UCH) | ||||
| #	define stix_oocstobcs(stix,oocs,oocslen,bcs,bcslen) stix_ucstobcs(stix,oocs,oocslen,bcs,bcslen) | ||||
| #	define stix_bcstooocs(stix,bcs,bcslen,oocs,oocslen) stix_bcstoucs(stix,bcs,bcslen,oocs,oocslen) | ||||
| #else | ||||
| #error TODO | ||||
| #	define stix_oocstobcs(stix,oocs,oocslen,bcs,bcslen) stix_ucstobcs(stix,oocs,oocslen,bcs,bcslen) | ||||
| #	define stix_bcstooocs(stix,bcs,bcslen,oocs,oocslen) stix_bcstoucs(stix,bcs,bcslen,oocs,oocslen) | ||||
| #endif | ||||
|  | ||||
| STIX_EXPORT int stix_bcstoucs ( | ||||
| 	stix_t*           stix, | ||||
| 	const stix_bch_t* bcs, | ||||
| 	stix_oow_t*       bcslen, | ||||
| 	stix_uch_t*       ucs, | ||||
| 	stix_oow_t*       ucslen | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT int stix_ucstobcs ( | ||||
| 	stix_t*           stix, | ||||
| 	const stix_uch_t* ucs, | ||||
| 	stix_oow_t*       ucslen, | ||||
| 	stix_bch_t*       bcs, | ||||
| 	stix_oow_t*       bcslen | ||||
| ); | ||||
|  | ||||
| STIX_EXPORT stix_ooi_t stix_logbfmt ( | ||||
| 	stix_t*           stix, | ||||
| 	stix_oow_t        mask, | ||||
|  | ||||
							
								
								
									
										341
									
								
								stix/lib/utf8.c
									
									
									
									
									
								
							
							
						
						
									
										341
									
								
								stix/lib/utf8.c
									
									
									
									
									
								
							| @ -26,8 +26,6 @@ | ||||
|  | ||||
| #include "stix-prv.h" | ||||
|  | ||||
| #define STIX_BCLEN_MAX 6 | ||||
|  | ||||
| /* | ||||
|  * from RFC 2279 UTF-8, a transformation format of ISO 10646 | ||||
|  * | ||||
| @ -179,342 +177,3 @@ stix_oow_t stix_utf8touc (const stix_bch_t* utf8, stix_oow_t size, stix_uch_t* u | ||||
| 	return 0; /* error - invalid sequence */ | ||||
| } | ||||
|  | ||||
| /* ----------------------------------------------------------------------- */ | ||||
|  | ||||
| static STIX_INLINE int bcsn_to_ucsn_with_cmgr ( | ||||
| 	const stix_bch_t* bcs, stix_oow_t* bcslen, | ||||
| 	stix_uch_t* ucs, stix_oow_t* ucslen, stix_cmgr_t* cmgr, int all) | ||||
| { | ||||
| 	const stix_bch_t* p; | ||||
| 	int ret = 0; | ||||
| 	stix_oow_t mlen; | ||||
|  | ||||
| 	if (ucs) | ||||
| 	{ | ||||
| 		/* destination buffer is specified.  | ||||
| 		 * copy the conversion result to the buffer */ | ||||
|  | ||||
| 		stix_uch_t* q, * qend; | ||||
|  | ||||
| 		p = bcs; | ||||
| 		q = ucs; | ||||
| 		qend = ucs + *ucslen; | ||||
| 		mlen = *bcslen; | ||||
|  | ||||
| 		while (mlen > 0) | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			if (q >= qend) | ||||
| 			{ | ||||
| 				/* buffer too small */ | ||||
| 				ret = -2; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			n = cmgr->bctouc (p, mlen, q); | ||||
| 			if (n == 0) | ||||
| 			{ | ||||
| 				/* invalid sequence */ | ||||
| 				if (all) | ||||
| 				{ | ||||
| 					n = 1; | ||||
| 					*q = '?'; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (n > mlen) | ||||
| 			{ | ||||
| 				/* incomplete sequence */ | ||||
| 				if (all) | ||||
| 				{ | ||||
| 					n = 1; | ||||
| 					*q = '?'; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -3; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			q++; | ||||
| 			p += n; | ||||
| 			mlen -= n; | ||||
| 		} | ||||
|  | ||||
| 		*ucslen = q - ucs; | ||||
| 		*bcslen = p - bcs; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* no destination buffer is specified. perform conversion | ||||
| 		 * but don't copy the result. the caller can call this function | ||||
| 		 * without a buffer to find the required buffer size, allocate | ||||
| 		 * a buffer with the size and call this function again with  | ||||
| 		 * the buffer. */ | ||||
|  | ||||
| 		stix_uch_t w; | ||||
| 		stix_oow_t wlen = 0; | ||||
|  | ||||
| 		p = bcs; | ||||
| 		mlen = *bcslen; | ||||
|  | ||||
| 		while (mlen > 0) | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			n = cmgr->bctouc (p, mlen, &w); | ||||
| 			if (n == 0) | ||||
| 			{ | ||||
| 				/* invalid sequence */ | ||||
| 				if (all) n = 1; | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (n > mlen) | ||||
| 			{ | ||||
| 				/* incomplete sequence */ | ||||
| 				if (all) n = 1; | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -3; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			p += n; | ||||
| 			mlen -= n; | ||||
| 			wlen += 1; | ||||
| 		} | ||||
|  | ||||
| 		*ucslen = wlen; | ||||
| 		*bcslen = p - bcs; | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static STIX_INLINE int bcs_to_ucs_with_cmgr ( | ||||
| 	const stix_bch_t* bcs, stix_oow_t* bcslen, | ||||
| 	stix_uch_t* ucs, stix_oow_t* ucslen, stix_cmgr_t* cmgr, int all) | ||||
| { | ||||
| 	const stix_bch_t* bp; | ||||
| 	stix_oow_t mlen, wlen; | ||||
| 	int n; | ||||
|  | ||||
| 	for (bp = bcs; *bp != '\0'; bp++) /* nothing */ ; | ||||
|  | ||||
| 	mlen = bp - bcs; wlen = *ucslen; | ||||
| 	n = bcsn_to_ucsn_with_cmgr (bcs, &mlen, ucs, &wlen, cmgr, all); | ||||
| 	if (ucs) | ||||
| 	{ | ||||
| 		/* null-terminate the target buffer if it has room for it. */ | ||||
| 		if (wlen < *ucslen) ucs[wlen] = '\0'; | ||||
| 		else n = -2; /* buffer too small */ | ||||
| 	} | ||||
| 	*bcslen = mlen; *ucslen = wlen; | ||||
|  | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| static STIX_INLINE int ucsn_to_bcsn_with_cmgr ( | ||||
| 	const stix_uch_t* ucs, stix_oow_t* ucslen, | ||||
| 	stix_bch_t* bcs, stix_oow_t* bcslen, stix_cmgr_t* cmgr) | ||||
| { | ||||
| 	const stix_uch_t* p = ucs; | ||||
| 	const stix_uch_t* end = ucs + *ucslen; | ||||
| 	int ret = 0;  | ||||
|  | ||||
| 	if (bcs) | ||||
| 	{ | ||||
| 		stix_oow_t rem = *bcslen; | ||||
|  | ||||
| 		while (p < end)  | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			if (rem <= 0) | ||||
| 			{ | ||||
| 				ret = -2; /* buffer too small */ | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			n = cmgr->uctobc (*p, bcs, rem); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
| 			if (n > rem)  | ||||
| 			{ | ||||
| 				ret = -2; /* buffer too small */ | ||||
| 				break; | ||||
| 			} | ||||
| 			bcs += n; rem -= n; p++; | ||||
| 		} | ||||
|  | ||||
| 		*bcslen -= rem;  | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		stix_bch_t bcsbuf[STIX_BCLEN_MAX]; | ||||
| 		stix_oow_t mlen = 0; | ||||
|  | ||||
| 		while (p < end) | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			n = cmgr->uctobc (*p, bcsbuf, STIX_COUNTOF(bcsbuf)); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
|  | ||||
| 			/* it assumes that bcsbuf is large enough to hold a character */ | ||||
| 			STIX_ASSERT (n <= STIX_COUNTOF(bcsbuf)); | ||||
|  | ||||
| 			p++; mlen += n; | ||||
| 		} | ||||
|  | ||||
| 		/* this length excludes the terminating null character.  | ||||
| 		 * this function doesn't even null-terminate the result. */ | ||||
| 		*bcslen = mlen; | ||||
| 	} | ||||
|  | ||||
| 	*ucslen = p - ucs; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int ucs_to_bcs_with_cmgr ( | ||||
| 	const stix_uch_t* ucs, stix_oow_t* ucslen, | ||||
| 	stix_bch_t* bcs, stix_oow_t* bcslen, stix_cmgr_t* cmgr) | ||||
| { | ||||
| 	const stix_uch_t* p = ucs; | ||||
| 	int ret = 0; | ||||
|  | ||||
| 	if (bcs) | ||||
| 	{ | ||||
| 		stix_oow_t rem = *bcslen; | ||||
|  | ||||
| 		while (*p != '\0') | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			if (rem <= 0) | ||||
| 			{ | ||||
| 				ret = -2; | ||||
| 				break; | ||||
| 			} | ||||
| 			 | ||||
| 			n = cmgr->uctobc (*p, bcs, rem); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
| 			if (n > rem)  | ||||
| 			{ | ||||
| 				ret = -2; | ||||
| 				break; /* buffer too small */ | ||||
| 			} | ||||
|  | ||||
| 			bcs += n; rem -= n; p++; | ||||
| 		} | ||||
|  | ||||
| 		/* update bcslen to the length of the bcs string converted excluding | ||||
| 		 * terminating null */ | ||||
| 		*bcslen -= rem;  | ||||
|  | ||||
| 		/* null-terminate the multibyte sequence if it has sufficient space */ | ||||
| 		if (rem > 0) *bcs = '\0'; | ||||
| 		else  | ||||
| 		{ | ||||
| 			/* if ret is -2 and cs[cslen] == '\0',  | ||||
| 			 * this means that the bcs buffer was lacking one | ||||
| 			 * slot for the terminating null */ | ||||
| 			ret = -2; /* buffer too small */ | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		stix_bch_t bcsbuf[STIX_BCLEN_MAX]; | ||||
| 		stix_oow_t mlen = 0; | ||||
|  | ||||
| 		while (*p != '\0') | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			n = cmgr->uctobc (*p, bcsbuf, STIX_COUNTOF(bcsbuf)); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
|  | ||||
| 			/* it assumes that bcs is large enough to hold a character */ | ||||
| 			STIX_ASSERT (n <= STIX_COUNTOF(bcs)); | ||||
|  | ||||
| 			p++; mlen += n; | ||||
| 		} | ||||
|  | ||||
| 		/* this length holds the number of resulting multi-byte characters  | ||||
| 		 * excluding the terminating null character */ | ||||
| 		*bcslen = mlen; | ||||
| 	} | ||||
|  | ||||
| 	*ucslen = p - ucs;  /* the number of wide characters handled. */ | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static stix_cmgr_t utf8_cmgr = | ||||
| { | ||||
| 	stix_utf8touc, | ||||
| 	stix_uctoutf8 | ||||
| }; | ||||
|  | ||||
| int stix_utf8toucs (const stix_bch_t* bcs, stix_oow_t* bcslen, stix_uch_t* ucs, stix_oow_t* ucslen) | ||||
| { | ||||
| 	if (*bcslen == ~(stix_oow_t)0) | ||||
| 	{ | ||||
| 		/* the source is null-terminated. */ | ||||
| 		return bcs_to_ucs_with_cmgr (bcs, bcslen, ucs, ucslen, &utf8_cmgr, 0); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* the source is length bound */ | ||||
| 		return bcsn_to_ucsn_with_cmgr (bcs, bcslen, ucs, ucslen, &utf8_cmgr, 0); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int stix_ucstoutf8 (const stix_uch_t* ucs, stix_oow_t* ucslen, stix_bch_t* bcs, stix_oow_t* bcslen) | ||||
| { | ||||
| 	if (*ucslen == ~(stix_oow_t)0) | ||||
| 	{ | ||||
| 		/* null-terminated */ | ||||
| 		return ucs_to_bcs_with_cmgr (ucs, ucslen, bcs, bcslen, &utf8_cmgr); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* length bound */ | ||||
| 		return ucsn_to_bcsn_with_cmgr (ucs, ucslen, bcs, bcslen, &utf8_cmgr); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
| stix_oow_t stix_ucslen (const stix_uch_t* ucs) | ||||
| { | ||||
| 	const stix_uch_t* ptr = ucs; | ||||
| 	while (*ptr) ptr++; | ||||
| 	return ptr - ucs; | ||||
| } | ||||
| */ | ||||
|  | ||||
							
								
								
									
										370
									
								
								stix/lib/utl.c
									
									
									
									
									
								
							
							
						
						
									
										370
									
								
								stix/lib/utl.c
									
									
									
									
									
								
							| @ -24,7 +24,9 @@ | ||||
|     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "stix-utl.h" | ||||
| #include "stix-prv.h" | ||||
|  | ||||
| #define STIX_BCLEN_MAX 6 | ||||
|  | ||||
| stix_oow_t stix_hashbytes (const stix_oob_t* ptr, stix_oow_t len) | ||||
| { | ||||
| @ -187,3 +189,369 @@ stix_bch_t* stix_findbchar (const stix_bch_t* ptr, stix_oow_t len, stix_bch_t c) | ||||
|  | ||||
| 	return STIX_NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* ----------------------------------------------------------------------- */ | ||||
|  | ||||
| static STIX_INLINE int bcsn_to_ucsn_with_cmgr ( | ||||
| 	const stix_bch_t* bcs, stix_oow_t* bcslen, | ||||
| 	stix_uch_t* ucs, stix_oow_t* ucslen, stix_cmgr_t* cmgr, int all) | ||||
| { | ||||
| 	const stix_bch_t* p; | ||||
| 	int ret = 0; | ||||
| 	stix_oow_t mlen; | ||||
|  | ||||
| 	if (ucs) | ||||
| 	{ | ||||
| 		/* destination buffer is specified.  | ||||
| 		 * copy the conversion result to the buffer */ | ||||
|  | ||||
| 		stix_uch_t* q, * qend; | ||||
|  | ||||
| 		p = bcs; | ||||
| 		q = ucs; | ||||
| 		qend = ucs + *ucslen; | ||||
| 		mlen = *bcslen; | ||||
|  | ||||
| 		while (mlen > 0) | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			if (q >= qend) | ||||
| 			{ | ||||
| 				/* buffer too small */ | ||||
| 				ret = -2; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			n = cmgr->bctouc (p, mlen, q); | ||||
| 			if (n == 0) | ||||
| 			{ | ||||
| 				/* invalid sequence */ | ||||
| 				if (all) | ||||
| 				{ | ||||
| 					n = 1; | ||||
| 					*q = '?'; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (n > mlen) | ||||
| 			{ | ||||
| 				/* incomplete sequence */ | ||||
| 				if (all) | ||||
| 				{ | ||||
| 					n = 1; | ||||
| 					*q = '?'; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -3; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			q++; | ||||
| 			p += n; | ||||
| 			mlen -= n; | ||||
| 		} | ||||
|  | ||||
| 		*ucslen = q - ucs; | ||||
| 		*bcslen = p - bcs; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* no destination buffer is specified. perform conversion | ||||
| 		 * but don't copy the result. the caller can call this function | ||||
| 		 * without a buffer to find the required buffer size, allocate | ||||
| 		 * a buffer with the size and call this function again with  | ||||
| 		 * the buffer. */ | ||||
|  | ||||
| 		stix_uch_t w; | ||||
| 		stix_oow_t wlen = 0; | ||||
|  | ||||
| 		p = bcs; | ||||
| 		mlen = *bcslen; | ||||
|  | ||||
| 		while (mlen > 0) | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			n = cmgr->bctouc (p, mlen, &w); | ||||
| 			if (n == 0) | ||||
| 			{ | ||||
| 				/* invalid sequence */ | ||||
| 				if (all) n = 1; | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -1; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			if (n > mlen) | ||||
| 			{ | ||||
| 				/* incomplete sequence */ | ||||
| 				if (all) n = 1; | ||||
| 				else | ||||
| 				{ | ||||
| 					ret = -3; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			p += n; | ||||
| 			mlen -= n; | ||||
| 			wlen += 1; | ||||
| 		} | ||||
|  | ||||
| 		*ucslen = wlen; | ||||
| 		*bcslen = p - bcs; | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static STIX_INLINE int bcs_to_ucs_with_cmgr ( | ||||
| 	const stix_bch_t* bcs, stix_oow_t* bcslen, | ||||
| 	stix_uch_t* ucs, stix_oow_t* ucslen, stix_cmgr_t* cmgr, int all) | ||||
| { | ||||
| 	const stix_bch_t* bp; | ||||
| 	stix_oow_t mlen, wlen; | ||||
| 	int n; | ||||
|  | ||||
| 	for (bp = bcs; *bp != '\0'; bp++) /* nothing */ ; | ||||
|  | ||||
| 	mlen = bp - bcs; wlen = *ucslen; | ||||
| 	n = bcsn_to_ucsn_with_cmgr (bcs, &mlen, ucs, &wlen, cmgr, all); | ||||
| 	if (ucs) | ||||
| 	{ | ||||
| 		/* null-terminate the target buffer if it has room for it. */ | ||||
| 		if (wlen < *ucslen) ucs[wlen] = '\0'; | ||||
| 		else n = -2; /* buffer too small */ | ||||
| 	} | ||||
| 	*bcslen = mlen; *ucslen = wlen; | ||||
|  | ||||
| 	return n; | ||||
| } | ||||
|  | ||||
| static STIX_INLINE int ucsn_to_bcsn_with_cmgr ( | ||||
| 	const stix_uch_t* ucs, stix_oow_t* ucslen, | ||||
| 	stix_bch_t* bcs, stix_oow_t* bcslen, stix_cmgr_t* cmgr) | ||||
| { | ||||
| 	const stix_uch_t* p = ucs; | ||||
| 	const stix_uch_t* end = ucs + *ucslen; | ||||
| 	int ret = 0;  | ||||
|  | ||||
| 	if (bcs) | ||||
| 	{ | ||||
| 		stix_oow_t rem = *bcslen; | ||||
|  | ||||
| 		while (p < end)  | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			if (rem <= 0) | ||||
| 			{ | ||||
| 				ret = -2; /* buffer too small */ | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			n = cmgr->uctobc (*p, bcs, rem); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
| 			if (n > rem)  | ||||
| 			{ | ||||
| 				ret = -2; /* buffer too small */ | ||||
| 				break; | ||||
| 			} | ||||
| 			bcs += n; rem -= n; p++; | ||||
| 		} | ||||
|  | ||||
| 		*bcslen -= rem;  | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		stix_bch_t bcsbuf[STIX_BCLEN_MAX]; | ||||
| 		stix_oow_t mlen = 0; | ||||
|  | ||||
| 		while (p < end) | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			n = cmgr->uctobc (*p, bcsbuf, STIX_COUNTOF(bcsbuf)); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
|  | ||||
| 			/* it assumes that bcsbuf is large enough to hold a character */ | ||||
| 			STIX_ASSERT (n <= STIX_COUNTOF(bcsbuf)); | ||||
|  | ||||
| 			p++; mlen += n; | ||||
| 		} | ||||
|  | ||||
| 		/* this length excludes the terminating null character.  | ||||
| 		 * this function doesn't even null-terminate the result. */ | ||||
| 		*bcslen = mlen; | ||||
| 	} | ||||
|  | ||||
| 	*ucslen = p - ucs; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int ucs_to_bcs_with_cmgr ( | ||||
| 	const stix_uch_t* ucs, stix_oow_t* ucslen, | ||||
| 	stix_bch_t* bcs, stix_oow_t* bcslen, stix_cmgr_t* cmgr) | ||||
| { | ||||
| 	const stix_uch_t* p = ucs; | ||||
| 	int ret = 0; | ||||
|  | ||||
| 	if (bcs) | ||||
| 	{ | ||||
| 		stix_oow_t rem = *bcslen; | ||||
|  | ||||
| 		while (*p != '\0') | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			if (rem <= 0) | ||||
| 			{ | ||||
| 				ret = -2; | ||||
| 				break; | ||||
| 			} | ||||
| 			 | ||||
| 			n = cmgr->uctobc (*p, bcs, rem); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
| 			if (n > rem)  | ||||
| 			{ | ||||
| 				ret = -2; | ||||
| 				break; /* buffer too small */ | ||||
| 			} | ||||
|  | ||||
| 			bcs += n; rem -= n; p++; | ||||
| 		} | ||||
|  | ||||
| 		/* update bcslen to the length of the bcs string converted excluding | ||||
| 		 * terminating null */ | ||||
| 		*bcslen -= rem;  | ||||
|  | ||||
| 		/* null-terminate the multibyte sequence if it has sufficient space */ | ||||
| 		if (rem > 0) *bcs = '\0'; | ||||
| 		else  | ||||
| 		{ | ||||
| 			/* if ret is -2 and cs[cslen] == '\0',  | ||||
| 			 * this means that the bcs buffer was lacking one | ||||
| 			 * slot for the terminating null */ | ||||
| 			ret = -2; /* buffer too small */ | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		stix_bch_t bcsbuf[STIX_BCLEN_MAX]; | ||||
| 		stix_oow_t mlen = 0; | ||||
|  | ||||
| 		while (*p != '\0') | ||||
| 		{ | ||||
| 			stix_oow_t n; | ||||
|  | ||||
| 			n = cmgr->uctobc (*p, bcsbuf, STIX_COUNTOF(bcsbuf)); | ||||
| 			if (n == 0)  | ||||
| 			{ | ||||
| 				ret = -1; | ||||
| 				break; /* illegal character */ | ||||
| 			} | ||||
|  | ||||
| 			/* it assumes that bcs is large enough to hold a character */ | ||||
| 			STIX_ASSERT (n <= STIX_COUNTOF(bcs)); | ||||
|  | ||||
| 			p++; mlen += n; | ||||
| 		} | ||||
|  | ||||
| 		/* this length holds the number of resulting multi-byte characters  | ||||
| 		 * excluding the terminating null character */ | ||||
| 		*bcslen = mlen; | ||||
| 	} | ||||
|  | ||||
| 	*ucslen = p - ucs;  /* the number of wide characters handled. */ | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static stix_cmgr_t utf8_cmgr = | ||||
| { | ||||
| 	stix_utf8touc, | ||||
| 	stix_uctoutf8 | ||||
| }; | ||||
|  | ||||
| stix_cmgr_t* stix_getutf8cmgr (void) | ||||
| { | ||||
| 	return &utf8_cmgr; | ||||
| } | ||||
|  | ||||
| int stix_utf8toucs (const stix_bch_t* bcs, stix_oow_t* bcslen, stix_uch_t* ucs, stix_oow_t* ucslen) | ||||
| { | ||||
| 	if (*bcslen == ~(stix_oow_t)0) | ||||
| 	{ | ||||
| 		/* the source is null-terminated. */ | ||||
| 		return bcs_to_ucs_with_cmgr (bcs, bcslen, ucs, ucslen, &utf8_cmgr, 0); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* the source is length bound */ | ||||
| 		return bcsn_to_ucsn_with_cmgr (bcs, bcslen, ucs, ucslen, &utf8_cmgr, 0); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int stix_ucstoutf8 (const stix_uch_t* ucs, stix_oow_t* ucslen, stix_bch_t* bcs, stix_oow_t* bcslen) | ||||
| { | ||||
| 	if (*ucslen == ~(stix_oow_t)0) | ||||
| 	{ | ||||
| 		/* null-terminated */ | ||||
| 		return ucs_to_bcs_with_cmgr (ucs, ucslen, bcs, bcslen, &utf8_cmgr); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* length bound */ | ||||
| 		return ucsn_to_bcsn_with_cmgr (ucs, ucslen, bcs, bcslen, &utf8_cmgr); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int stix_bcstoucs (stix_t* stix, const stix_bch_t* bcs, stix_oow_t* bcslen, stix_uch_t* ucs, stix_oow_t* ucslen) | ||||
| { | ||||
| 	if (*bcslen == ~(stix_oow_t)0) | ||||
| 	{ | ||||
| 		/* the source is null-terminated. */ | ||||
| 		return bcs_to_ucs_with_cmgr (bcs, bcslen, ucs, ucslen, stix->cmgr, 0); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* the source is length bound */ | ||||
| 		return bcsn_to_ucsn_with_cmgr (bcs, bcslen, ucs, ucslen, stix->cmgr, 0); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int stix_ucstobcs (stix_t* stix, const stix_uch_t* ucs, stix_oow_t* ucslen, stix_bch_t* bcs, stix_oow_t* bcslen) | ||||
| { | ||||
| 	if (*ucslen == ~(stix_oow_t)0) | ||||
| 	{ | ||||
| 		/* null-terminated */ | ||||
| 		return ucs_to_bcs_with_cmgr (ucs, ucslen, bcs, bcslen, stix->cmgr); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/* length bound */ | ||||
| 		return ucsn_to_bcsn_with_cmgr (ucs, ucslen, bcs, bcslen, stix->cmgr); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -166,7 +166,7 @@ static int prim_write (stix_t* stix, stix_ooi_t nargs) | ||||
| 	{ | ||||
| 		ucslen = ucsrem; | ||||
| 		bcslen = STIX_COUNTOF(bcs); | ||||
| 		if ((n = stix_ucstoutf8 (&oomsg->slot[ucspos], &ucslen, bcs, &bcslen)) <= -1) | ||||
| 		if ((n = stix_oocstobcs (stix, &oomsg->slot[ucspos], &ucslen, bcs, &bcslen)) <= -1) | ||||
| 		{ | ||||
| 			if (n != -2 || ucslen <= 0)  | ||||
| 			{ | ||||
| @ -267,7 +267,7 @@ static fnctab_t fnctab[] = | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| static stix_prim_impl_t query (stix_t* stix, stix_prim_mod_t* mod, const stix_ooch_t* name) | ||||
| static stix_prim_impl_t query (stix_t* stix, stix_mod_t* mod, const stix_ooch_t* name) | ||||
| { | ||||
| 	int left, right, mid, n; | ||||
|  | ||||
| @ -291,13 +291,13 @@ static stix_prim_impl_t query (stix_t* stix, stix_prim_mod_t* mod, const stix_oo | ||||
| } | ||||
|  | ||||
|  | ||||
| static void unload (stix_t* stix, stix_prim_mod_t* mod) | ||||
| static void unload (stix_t* stix, stix_mod_t* mod) | ||||
| { | ||||
| 	/* TODO: close all open handle?? */ | ||||
| } | ||||
|  | ||||
|  | ||||
| int stix_prim_mod_console (stix_t* stix, stix_prim_mod_t* mod) | ||||
| int stix_mod_console (stix_t* stix, stix_mod_t* mod) | ||||
| { | ||||
| 	mod->query = query; | ||||
| 	mod->unload = unload;  | ||||
|  | ||||
| @ -59,7 +59,7 @@ static fnctab_t fnctab[] = | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| static stix_prim_impl_t query (stix_t* stix, stix_prim_mod_t* mod, const stix_ooch_t* name) | ||||
| static stix_prim_impl_t query (stix_t* stix, stix_mod_t* mod, const stix_ooch_t* name) | ||||
| { | ||||
| 	int left, right, mid, n; | ||||
|  | ||||
| @ -88,12 +88,12 @@ static stix_prim_impl_t query (stix_t* stix, stix_prim_mod_t* mod, const stix_oo | ||||
| } | ||||
|  | ||||
|  | ||||
| static void unload (stix_t* stix, stix_prim_mod_t* mod) | ||||
| static void unload (stix_t* stix, stix_mod_t* mod) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| int stix_prim_mod_sound (stix_t* stix, stix_prim_mod_t* mod) | ||||
| int stix_mod_sound (stix_t* stix, stix_mod_t* mod) | ||||
| { | ||||
| 	mod->query = query; | ||||
| 	mod->unload = unload; | ||||
|  | ||||
| @ -31,12 +31,18 @@ | ||||
| #include <stdio.h> | ||||
| #include <limits.h> | ||||
|  | ||||
| typedef struct stdio_t stdio_t; | ||||
| struct stdio_t | ||||
| { | ||||
| 	STIX_OBJ_HEADER; | ||||
| 	FILE* fp; | ||||
| }; | ||||
|  | ||||
| static int prim_open (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| 	stix_oop_word_t rcv; | ||||
| 	stix_oop_char_t name; | ||||
| 	stix_oop_char_t mode; | ||||
| 	FILE* fp; | ||||
| 	stdio_t* rcv; | ||||
|  | ||||
| #if defined(STIX_OOCH_IS_UCH) | ||||
| 	stix_oow_t ucslen, bcslen; | ||||
| @ -44,7 +50,7 @@ static int prim_open (stix_t* stix, stix_ooi_t nargs) | ||||
| 	stix_bch_t modebuf[32]; /* TODO: dynamic-sized conversion?? */ | ||||
| #endif | ||||
|  | ||||
| 	rcv = (stix_oop_word_t)STIX_STACK_GETRCV(stix, nargs); | ||||
| 	rcv = (stdio_t*)STIX_STACK_GETRCV(stix, nargs); | ||||
| 	name = (stix_oop_char_t)STIX_STACK_GETARG(stix, nargs, 0); | ||||
| 	mode = (stix_oop_char_t)STIX_STACK_GETARG(stix, nargs, 1); | ||||
|  | ||||
| @ -52,45 +58,46 @@ static int prim_open (stix_t* stix, stix_ooi_t nargs) | ||||
| /* TODO: error check on string conversion */ | ||||
| 	ucslen = STIX_OBJ_GET_SIZE(name); | ||||
| 	bcslen = STIX_COUNTOF(namebuf) - 1; | ||||
| 	stix_ucstoutf8 (name->slot, &ucslen, namebuf, &bcslen); | ||||
| 	stix_oocstobcs (stix, name->slot, &ucslen, namebuf, &bcslen); /* TODO: error check */ | ||||
| 	namebuf[bcslen] = '\0'; | ||||
|  | ||||
| 	ucslen = STIX_OBJ_GET_SIZE(mode); | ||||
| 	bcslen = STIX_COUNTOF(modebuf) - 1; | ||||
| 	stix_ucstoutf8 (mode->slot, &ucslen, modebuf, &bcslen); | ||||
| 	stix_oocstobcs (stix, mode->slot, &ucslen, modebuf, &bcslen); /* TODO: error check */ | ||||
| 	modebuf[bcslen] = '\0'; | ||||
|  | ||||
| STIX_DEBUG2 (stix, "opening %s for %s\n", namebuf, modebuf); | ||||
| 	fp = fopen (namebuf, modebuf); | ||||
| 	rcv->fp = fopen (namebuf, modebuf); | ||||
| #else | ||||
| 	fp = fopen (name->slot, mode->slot); | ||||
| 	rcv->fp = fopen (name->slot, mode->slot); | ||||
| #endif | ||||
| 	if (!fp)  | ||||
| 	if (!rcv->fp)  | ||||
| 	{ | ||||
| STIX_DEBUG2 (stix, "cannot open %s for %s\n", namebuf, modebuf); | ||||
| 		return -1;  /* TODO: return success with an object instead... */ | ||||
| 	} | ||||
|  | ||||
| 	rcv->slot[0] = (stix_oow_t)fp; | ||||
| STIX_DEBUG3 (stix, "opened %s for %s - %p\n", namebuf, modebuf, rcv->fp); | ||||
| 	STIX_STACK_SETRETTORCV (stix, nargs); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int prim_close (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| 	stix_oop_word_t rcv; | ||||
| 	stdio_t* rcv; | ||||
|  | ||||
| 	rcv = (stix_oop_word_t)STIX_STACK_GETRCV(stix, nargs); | ||||
| 	if (rcv->slot[0]) | ||||
| 	rcv = (stdio_t*)STIX_STACK_GETRCV(stix, nargs); | ||||
| 	if (rcv->fp) | ||||
| 	{ | ||||
| 		fclose ((FILE*)rcv->slot[0]); | ||||
| 		rcv->slot[0] = 0; | ||||
| STIX_DEBUG1 (stix, "closing %p\n", rcv->fp); | ||||
| 		fclose (rcv->fp); | ||||
| 		rcv->fp = NULL; | ||||
| 	} | ||||
|  | ||||
| 	STIX_STACK_SETRETTORCV (stix, nargs); | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int prim_write (stix_t* stix, stix_ooi_t nargs) | ||||
| static int prim_puts (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| 	/* return how many bytes have been written.. */ | ||||
|  | ||||
| @ -98,6 +105,12 @@ static int prim_write (stix_t* stix, stix_ooi_t nargs) | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int prim_newinstsize (stix_t* stix, stix_ooi_t nargs) | ||||
| { | ||||
| 	stix_ooi_t newinstsize = STIX_SIZEOF(stdio_t) - STIX_SIZEOF(stix_obj_t); | ||||
| 	STIX_STACK_SETRET (stix, nargs, STIX_SMOOI_TO_OOP(newinstsize));  | ||||
| 	return 1; | ||||
| } | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| typedef struct fnctab_t fnctab_t; | ||||
| @ -110,13 +123,14 @@ struct fnctab_t | ||||
| static fnctab_t fnctab[] = | ||||
| { | ||||
| 	{ "close",       prim_close         }, | ||||
| 	{ "newInstSize", prim_newinstsize   }, | ||||
| 	{ "open",        prim_open          }, | ||||
| 	{ "write",      prim_write     } | ||||
| 	{ "puts",        prim_puts          } | ||||
| }; | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| static stix_prim_impl_t query (stix_t* stix, stix_prim_mod_t* mod, const stix_ooch_t* name) | ||||
| static stix_prim_impl_t query (stix_t* stix, stix_mod_t* mod, const stix_ooch_t* name) | ||||
| { | ||||
| 	int left, right, mid, n; | ||||
|  | ||||
| @ -150,13 +164,12 @@ static int sanity_check (stix_t* stix) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void unload (stix_t* stix, stix_prim_mod_t* mod) | ||||
| static void unload (stix_t* stix, stix_mod_t* mod) | ||||
| { | ||||
| 	/* TODO: close all open handle?? */ | ||||
| } | ||||
|  | ||||
|  | ||||
| int stix_prim_mod_stdio (stix_t* stix, stix_prim_mod_t* mod) | ||||
| int stix_mod_stdio (stix_t* stix, stix_mod_t* mod) | ||||
| { | ||||
| 	mod->query = query; | ||||
| 	mod->unload = unload;  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user