added more code for primitive module loading
This commit is contained in:
		| @ -238,6 +238,8 @@ | |||||||
| 		## ffi call: #puts withSig: 'i|s' withArgs: #('hello world'). | 		## ffi call: #puts withSig: 'i|s' withArgs: #('hello world'). | ||||||
| 		ffi close." | 		ffi close." | ||||||
| 		self abc. | 		self abc. | ||||||
|  | 		self abc. | ||||||
|  | 		self abc. | ||||||
|  |  | ||||||
| 		FFI isNil dump. | 		FFI isNil dump. | ||||||
| 		FFI notNil dump. | 		FFI notNil dump. | ||||||
|  | |||||||
							
								
								
									
										200
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							
							
						
						
									
										200
									
								
								stix/lib/exec.c
									
									
									
									
									
								
							| @ -26,12 +26,9 @@ | |||||||
|  |  | ||||||
| #include "stix-prv.h" | #include "stix-prv.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| /* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */ | /* TODO: defined dcAllocMem and dcFreeMeme before builing the dynload and dyncall library */ | ||||||
| #include <dynload.h> /* TODO: remove this. make dlXXX calls to callbacks */ |  | ||||||
| #include <dyncall.h> /* TODO: remove this. make dyXXXX calls to callbacks */ | #include <dyncall.h> /* TODO: remove this. make dyXXXX calls to callbacks */ | ||||||
|  |  | ||||||
|  |  | ||||||
| /* TODO: context's stack overflow check in various part of this file */ | /* TODO: context's stack overflow check in various part of this file */ | ||||||
| /* TOOD: determine the right stack size */ | /* TOOD: determine the right stack size */ | ||||||
| #define CONTEXT_STACK_SIZE 96 | #define CONTEXT_STACK_SIZE 96 | ||||||
| @ -103,6 +100,7 @@ | |||||||
| #	define DBGOUT_EXEC_3(fmt,a1,a2,a3) | #	define DBGOUT_EXEC_3(fmt,a1,a2,a3) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth) | static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth) | ||||||
| { | { | ||||||
| 	stix_oop_context_t ctx; | 	stix_oop_context_t ctx; | ||||||
| @ -1029,27 +1027,19 @@ static int primitive_ffi_open (stix_t* stix, stix_ooi_t nargs) | |||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| { /////////////////////// | 	if (!stix->vmprim.mod_open) | ||||||
| /* TODO: grow buffer */ |  | ||||||
| 	stix_bch_t bcs[128]; |  | ||||||
| 	stix_size_t ucslen, bcslen; |  | ||||||
|  |  | ||||||
| 	bcslen = STIX_COUNTOF(bcs); |  | ||||||
| 	ucslen = STIX_OBJ_GET_SIZE(arg); |  | ||||||
| 	if (stix_ucstoutf8 (((stix_oop_char_t)arg)->slot, &ucslen, bcs, &bcslen) <= -1) |  | ||||||
| 	{ | 	{ | ||||||
| 		/* TODO: more info on error */ | 		/* TODO: more info on error */ | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bcs[bcslen] = '\0'; | /* TODO: check null-termination... */ | ||||||
| 	handle = dlLoadLibrary (bcs); | 	handle = stix->vmprim.mod_open (stix, ((stix_oop_char_t)arg)->slot); | ||||||
| 	if (!handle) | 	if (!handle) | ||||||
| 	{ | 	{ | ||||||
| 		/* TODO: more info on error */ | 		/* TODO: more info on error */ | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| } /////////////////////// |  | ||||||
|  |  | ||||||
| 	ACTIVE_STACK_POP (stix); | 	ACTIVE_STACK_POP (stix); | ||||||
| /* TODO: how to hold an address? as an integer????  or a byte array? */ | /* TODO: how to hold an address? as an integer????  or a byte array? */ | ||||||
| @ -1079,7 +1069,7 @@ static int primitive_ffi_close (stix_t* stix, stix_ooi_t nargs) | |||||||
| 	ACTIVE_STACK_POP (stix); | 	ACTIVE_STACK_POP (stix); | ||||||
|  |  | ||||||
| 	handle = STIX_OOP_TO_SMINT(arg); /* TODO: how to store void* ??? */ | 	handle = STIX_OOP_TO_SMINT(arg); /* TODO: how to store void* ??? */ | ||||||
| 	dlFreeLibrary (handle); | 	if (stix->vmprim.mod_close) stix->vmprim.mod_close (stix, handle); | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -1275,29 +1265,16 @@ printf ("wrong function name...\n"); | |||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| { /////////////////////// | 	if (!stix->vmprim.mod_getsym) | ||||||
| /* TODO: grow buffer */ |  | ||||||
| 	stix_bch_t bcs[128]; |  | ||||||
| 	stix_size_t ucslen, bcslen; |  | ||||||
|  |  | ||||||
| 	bcslen = STIX_COUNTOF(bcs); |  | ||||||
| 	ucslen = STIX_OBJ_GET_SIZE(fun); |  | ||||||
| 	if (stix_ucstoutf8 (((stix_oop_char_t)fun)->slot, &ucslen, bcs, &bcslen) <= -1) |  | ||||||
| 	{ | 	{ | ||||||
| 		/* TODO: more info on error */ |  | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bcs[bcslen] = '\0'; | 	sym = stix->vmprim.mod_getsym (stix, STIX_OOP_TO_SMINT(hnd), ((stix_oop_char_t)fun)->slot); | ||||||
| printf ("FINDING SYMBOL %s\n", bcs); |  | ||||||
| 	sym = dlFindSymbol (STIX_OOP_TO_SMINT(hnd), bcs); // TODO: decode hnd properly. |  | ||||||
| 	if (!sym) | 	if (!sym) | ||||||
| 	{ | 	{ | ||||||
| 		/* TODO: more info on error */ |  | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
| printf ("FOUND SYMBOL %p\n", sym); |  | ||||||
| } /////////////////////// |  | ||||||
|  |  | ||||||
| 	ACTIVE_STACK_POPS (stix, 2); | 	ACTIVE_STACK_POPS (stix, 2); | ||||||
| /* TODO: how to hold an address? as an integer????  or a byte array? */ | /* TODO: how to hold an address? as an integer????  or a byte array? */ | ||||||
| @ -1343,8 +1320,9 @@ static primitive_t primitives[] = | |||||||
|  |  | ||||||
| 	{   1,   primitive_ffi_open,             "ffiOpen"       }, | 	{   1,   primitive_ffi_open,             "ffiOpen"       }, | ||||||
| 	{   1,   primitive_ffi_close,            "ffiClose"      }, | 	{   1,   primitive_ffi_close,            "ffiClose"      }, | ||||||
| 	{   3,   primitive_ffi_call,             "ffiCall"       }, | 	{   2,   primitive_ffi_getsym,           "ffiGetSym"     }, | ||||||
| 	{   2,   primitive_ffi_getsym,           "ffiGetSym"     } | 	{   3,   primitive_ffi_call,             "ffiCall"       } | ||||||
|  | 	 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| int stix_getprimno (stix_t* stix, const stix_ucs_t* name) | int stix_getprimno (stix_t* stix, const stix_ucs_t* name) | ||||||
| @ -1363,67 +1341,99 @@ int stix_getprimno (stix_t* stix, const stix_ucs_t* name) | |||||||
| 	return -1; | 	return -1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static stix_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name) | typedef struct stix_prim_mod_t stix_prim_mod_t; | ||||||
|  |  | ||||||
|  | typedef int (*stix_prim_mod_load_t) ( | ||||||
|  | 	stix_t*          stix, | ||||||
|  | 	stix_prim_mod_t* mod | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | typedef void* (*stix_prim_mod_query_t) ( | ||||||
|  | 	stix_t*           stix, | ||||||
|  | 	stix_prim_mod_t*  mod, | ||||||
|  | 	const stix_uch_t* name | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | typedef void (*stix_prim_mod_unload_t) ( | ||||||
|  | 	stix_t*          stix, | ||||||
|  | 	stix_prim_mod_t* mod | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | struct stix_prim_mod_t | ||||||
|  | { | ||||||
|  | 	stix_prim_mod_load_t   load; | ||||||
|  | 	stix_prim_mod_unload_t unload; | ||||||
|  | 	stix_prim_mod_query_t  query; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | struct stix_prim_mod_data_t  | ||||||
|  | { | ||||||
|  | 	void* handle; | ||||||
|  | 	stix_prim_mod_t mod; | ||||||
|  | }; | ||||||
|  | typedef struct stix_prim_mod_data_t stix_prim_mod_data_t; | ||||||
|  |  | ||||||
|  | static stix_prim_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name, stix_oow_t len) | ||||||
| { | { | ||||||
| 	stix_rbt_pair_t* pair; | 	stix_rbt_pair_t* pair; | ||||||
| 	stix_mod_data_t* mdp; | 	stix_prim_mod_data_t* mdp; | ||||||
| 	stix_cstr_t ea; | 	const stix_uch_t* sep; | ||||||
|  | 	stix_oow_t mod_name_len; | ||||||
| 	int n; | 	int n; | ||||||
|  |  | ||||||
| 	STIX_ASSERT (nsegs == 2); | 	sep = stix_findchar (name, len, '_'); | ||||||
|  | 	STIX_ASSERT (sep != STIX_NULL); | ||||||
|  | 	mod_name_len = sep - name; | ||||||
|  |  | ||||||
| 	pair = stix_rbt_search (stix->modtab, segs[0].ptr, segs[0].len); | 	pair = stix_rbt_search (&stix->pmtable, name, mod_name_len); | ||||||
| 	if (pair) | 	if (pair) | ||||||
| 	{ | 	{ | ||||||
| 		mdp = (stix_mod_data_t*)STIX_RBT_VPTR(pair); | 		mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		stix_mod_data_t md; | 		stix_prim_mod_data_t md; | ||||||
| 		stix_mod_load_t load = STIX_NULL; | 		stix_prim_mod_load_t load = STIX_NULL; | ||||||
| 		stix_mod_spec_t spec; |  | ||||||
| 		stix_size_t buflen; |  | ||||||
| 		/*stix_char_t buf[64 + 15] = STIX_T("_stix_mod_");*/ |  | ||||||
|  |  | ||||||
| 		/* maximum module name length is 64. 15 is decomposed to 13 + 1 + 1. | 		/* maximum module name length is STIX_MOD_NAME_LEN_MAX.  | ||||||
| 		 * 13 for _stix_mod_t | 		 * 17 is decomposed to 15 + 1 + 1. | ||||||
| 		 * 1 for _ at the end when stix_mod_xxx_ is attempted. | 		 *   15 for _stix_prim_mod_. | ||||||
| 		 * 1 for the terminating '\0' | 		 *   1 for _ at the end when stix_prim_mod_xxx_ is attempted. | ||||||
|  | 		 *   1 for the terminating '\0'. | ||||||
| 		 */ | 		 */ | ||||||
| 		stix_char_t buf[64 + 15];  | 		stix_uch_t buf[STIX_MOD_NAME_LEN_MAX + 17];  | ||||||
|  |  | ||||||
| 		/* the terminating null isn't needed in buf here */ | 		/* the terminating null isn't needed in buf here */ | ||||||
| 		STIX_MEMCPY (buf, STIX_T("_stix_mod_"), STIX_SIZEOF(stix_char_t) * 13);  | 		stix_copychars2 (buf, "_stix_prim_mod_", 15);  | ||||||
| 		if (segs[0].len > STIX_COUNTOF(buf) - 15) |  | ||||||
|  | 		if (mod_name_len > STIX_COUNTOF(buf) - 17) | ||||||
| 		{ | 		{ | ||||||
| 			/* module name too long  */ | 			/* module name too long  */ | ||||||
| 			ea.ptr = segs[0].ptr; | 			stix->errnum = STIX_EINVAL; /* TODO: change the  error number to something more specific */ | ||||||
| 			ea.len = segs[0].len; |  | ||||||
| 			stix_seterror (stix, STIX_ESEGTL, &ea, STIX_NULL); |  | ||||||
| 			return STIX_NULL; | 			return STIX_NULL; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		stix_copychars (&buf[15], name, mod_name_len); | ||||||
|  | 		buf[15 + mod_name_len] = '\0'; | ||||||
|  |  | ||||||
| #if defined(STIX_ENABLE_STATIC_MODULE) | #if defined(STIX_ENABLE_STATIC_MODULE) | ||||||
| 		/* attempt to find a statically linked module */ | 		/* attempt to find a statically linked module */ | ||||||
|  |  | ||||||
| 		/* TODO: binary search ... */ | 		/* TODO: binary search ... */ | ||||||
| 		for (n = 0; n < STIX_COUNTOF(static_modtab); n++) | 		for (n = 0; n < STIX_COUNTOF(static_modtab); n++) | ||||||
| 		{ | 		{ | ||||||
| 			if (stix_strcmp (static_modtab[n].modname, segs[0].ptr) == 0)  | 			if (stix_compucstr (static_modtab[n].modname, name) == 0)  | ||||||
| 			{ | 			{ | ||||||
| 				load = static_modtab[n].modload; | 				load = static_modtab[n].modload; | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		/*if (n >= STIX_COUNTOF(static_modtab)) | 		if (n >= STIX_COUNTOF(static_modtab)) | ||||||
| 		{ | 		{ | ||||||
|  | 			stix->errnum = STIX_ENOENT; | ||||||
| 			ea.ptr = segs[0].ptr; |  | ||||||
| 			ea.len = segs[0].len; |  | ||||||
| 			stix_seterror (stix, STIX_ENOENT, &ea, STIX_NULL); |  | ||||||
| 			return STIX_NULL; | 			return STIX_NULL; | ||||||
| 		}*/ | 		} | ||||||
|  |  | ||||||
| 		if (load) | 		if (load) | ||||||
| 		{ | 		{ | ||||||
| @ -1434,10 +1444,10 @@ static stix_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name) | |||||||
|  |  | ||||||
| 			/* i copy-insert 'md' into the table before calling 'load'. | 			/* i copy-insert 'md' into the table before calling 'load'. | ||||||
| 			 * to pass the same address to load(), query(), etc */ | 			 * to pass the same address to load(), query(), etc */ | ||||||
| 			pair = stix_rbt_insert (stix->modtab, segs[0].ptr, segs[0].len, &md, STIX_SIZEOF(md)); | 			pair = stix_rbt_insert (stix->modtab, name, mod_name_len, &md, STIX_SIZEOF(md)); | ||||||
| 			if (pair == STIX_NULL) | 			if (pair == STIX_NULL) | ||||||
| 			{ | 			{ | ||||||
| 				stix_seterrnum (stix, STIX_ENOMEM, STIX_NULL); | 				stix->errnum = STIX_ENOMEM; | ||||||
| 				return STIX_NULL; | 				return STIX_NULL; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @ -1453,79 +1463,49 @@ static stix_mod_t* query_primitive_module (stix_t* stix, const stix_uch_t* name) | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 		/* attempt to find an external module */ | 		/* attempt to find an external module */ | ||||||
| 		STIX_MEMSET (&spec, 0, STIX_SIZEOF(spec)); |  | ||||||
|  |  | ||||||
| 		if (stix->opt.mod[0].len > 0) |  | ||||||
| 			spec.prefix = stix->opt.mod[0].ptr; |  | ||||||
| 		else spec.prefix = STIX_T(STIX_DEFAULT_MODPREFIX); |  | ||||||
|  |  | ||||||
| 		if (stix->opt.mod[1].len > 0) |  | ||||||
| 			spec.postfix = stix->opt.mod[1].ptr; |  | ||||||
| 		else spec.postfix = STIX_T(STIX_DEFAULT_MODPOSTFIX); |  | ||||||
| 		 |  | ||||||
| 		STIX_MEMSET (&md, 0, STIX_SIZEOF(md)); | 		STIX_MEMSET (&md, 0, STIX_SIZEOF(md)); | ||||||
| 		if (stix->prm.modopen && stix->prm.modsym && stix->prm.modclose) | 		if (stix->vmprim.mod_open && stix->vmprim.mod_getsym && stix->vmprim.mod_close) | ||||||
| 		{ | 		{ | ||||||
| 			spec.name = segs[0].ptr; | 			md.handle = stix->vmprim.mod_open (stix, &buf[15]); | ||||||
| 			md.handle = stix->prm.modopen (stix, &spec); |  | ||||||
| 		} | 		} | ||||||
| 		else md.handle = STIX_NULL; |  | ||||||
|  |  | ||||||
| 		if (md.handle == STIX_NULL)  | 		if (md.handle == STIX_NULL)  | ||||||
| 		{ | 		{ | ||||||
| 			ea.ptr = segs[0].ptr; | 			stix->errnum = STIX_ENOENT; /* TODO: be more descriptive about the error */ | ||||||
| 			ea.len = segs[0].len; |  | ||||||
| 			stix_seterror (stix, STIX_ENOENT, &ea, STIX_NULL); |  | ||||||
| 			return STIX_NULL; | 			return STIX_NULL; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		buflen = stix_strcpy (&buf[13], segs[0].ptr); | 		/* attempt to get stix_prim_mod_xxx */ | ||||||
| 		/* attempt stix_mod_xxx */ | 		load = stix->vmprim.mod_getsym (stix, md.handle, buf); | ||||||
| 		load = stix->prm.modsym (stix, md.handle, &buf[1]); |  | ||||||
| 		if (!load)  | 		if (!load)  | ||||||
| 		{ | 		{ | ||||||
| 			/* attempt _stix_mod_xxx */ | 			stix->errnum = STIX_ENOENT; /* TODO: be more descriptive about the error */ | ||||||
| 			load = stix->prm.modsym (stix, md.handle, &buf[0]); | 			stix->vmprim.mod_close (stix, md.handle); | ||||||
| 			if (!load) |  | ||||||
| 			{ |  | ||||||
| 				/* attempt stix_mod_xxx_ */ |  | ||||||
| 				buf[13 + buflen] = STIX_T('_'); |  | ||||||
| 				buf[13 + buflen + 1] = STIX_T('\0'); |  | ||||||
| 				load = stix->prm.modsym (stix, md.handle, &buf[1]); |  | ||||||
| 				if (!load) |  | ||||||
| 				{ |  | ||||||
| 					ea.ptr = &buf[1]; |  | ||||||
| 					ea.len = 12 + buflen; |  | ||||||
| 					stix_seterror (stix, STIX_ENOENT, &ea, STIX_NULL); |  | ||||||
|  |  | ||||||
| 					stix->prm.modclose (stix, md.handle); |  | ||||||
| 			return STIX_NULL; | 			return STIX_NULL; | ||||||
| 		} | 		} | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		/* i copy-insert 'md' into the table before calling 'load'. | 		/* i copy-insert 'md' into the table before calling 'load'. | ||||||
| 		 * to pass the same address to load(), query(), etc */ | 		 * to pass the same address to load(), query(), etc */ | ||||||
| 		pair = stix_rbt_insert (stix->modtab, segs[0].ptr, segs[0].len, &md, STIX_SIZEOF(md)); | 		pair = stix_rbt_insert (&stix->pmtable, name, mod_name_len, &md, STIX_SIZEOF(md)); | ||||||
| 		if (pair == STIX_NULL) | 		if (pair == STIX_NULL) | ||||||
| 		{ | 		{ | ||||||
| 			stix_seterrnum (stix, STIX_ENOMEM, STIX_NULL); | 			stix->errnum = STIX_ENOMEM; | ||||||
| 			stix->prm.modclose (stix, md.handle); | 			stix->vmprim.mod_close (stix, md.handle); | ||||||
| 			return STIX_NULL; | 			return STIX_NULL; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		mdp = (stix_mod_data_t*)STIX_RBT_VPTR(pair); | 		mdp = (stix_prim_mod_data_t*)STIX_RBT_VPTR(pair); | ||||||
| 		if (load (&mdp->mod, stix) <= -1) | 		if (load (stix, &mdp->mod) <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			stix_rbt_delete (stix->modtab, segs[0].ptr, segs[0].len); | 			stix_rbt_delete (&stix->pmtable, name, mod_name_len); | ||||||
| 			stix->prm.modclose (stix, mdp->handle); | 			stix->vmprim.mod_close (stix, mdp->handle); | ||||||
| 			return STIX_NULL; | 			return STIX_NULL; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| done: | done: | ||||||
| 	n = mdp->mod.query (&mdp->mod, stix, segs[1].ptr, sym); | 	if (mdp->mod.query (stix, &mdp->mod, sep + 1) == STIX_NULL) return STIX_NULL; | ||||||
| 	return (n <= -1)? STIX_NULL: &mdp->mod; | 	return &mdp->mod; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* ------------------------------------------------------------------------- */ | /* ------------------------------------------------------------------------- */ | ||||||
| @ -2161,9 +2141,11 @@ printf ("]\n"); | |||||||
| 						STIX_ASSERT (STIX_OBJ_GET_FLAGS_EXTRA(name)); | 						STIX_ASSERT (STIX_OBJ_GET_FLAGS_EXTRA(name)); | ||||||
| 						STIX_ASSERT (STIX_CLASSOF(stix,name) == stix->_symbol); | 						STIX_ASSERT (STIX_CLASSOF(stix,name) == stix->_symbol); | ||||||
|  |  | ||||||
| 						handler = query_primitive_module (stix, ((stix_oop_char_t)name)->slot); | 						handler = query_primitive_module (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name)); | ||||||
| 						if (handler) | 						if (handler) | ||||||
| 						{ | 						{ | ||||||
|  | 							int n; | ||||||
|  |  | ||||||
| 							stix_pushtmp (stix, (stix_oop_t*)&newmth); | 							stix_pushtmp (stix, (stix_oop_t*)&newmth); | ||||||
| 							n = handler (stix, b1); | 							n = handler (stix, b1); | ||||||
| 							stix_poptmp (stix); | 							stix_poptmp (stix); | ||||||
|  | |||||||
							
								
								
									
										107
									
								
								stix/lib/main.c
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								stix/lib/main.c
									
									
									
									
									
								
							| @ -29,8 +29,22 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <dlfcn.h> | ||||||
|  |  | ||||||
| #include <limits.h> | #include <limits.h> | ||||||
|  | #include <dlfcn.h> | ||||||
|  |  | ||||||
|  | #if defined(_WIN32) | ||||||
|  | #	define DEFAULT_MODPREFIX "stix-" | ||||||
|  | #elif defined(__OS2__) | ||||||
|  | #	define DEFAULT_MODPREFIX "st-" | ||||||
|  | #elif defined(__DOS__) | ||||||
|  | #	define DEFAULT_MODPREFIX "st-" | ||||||
|  | #else | ||||||
|  | #	define DEFAULT_MODPREFIX "libstix-" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct xtn_t xtn_t; | typedef struct xtn_t xtn_t; | ||||||
| struct xtn_t | struct xtn_t | ||||||
| { | { | ||||||
| @ -167,6 +181,63 @@ static stix_ssize_t input_handler (stix_t* stix, stix_io_cmd_t cmd, stix_io_arg_ | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void* mod_open (stix_t* stix, const stix_uch_t* name) | ||||||
|  | { | ||||||
|  | /* TODO: support various platforms */ | ||||||
|  | 	stix_bch_t buf[1024]; /* TODO: use a proper path buffer */ | ||||||
|  | 	stix_size_t ucslen, bcslen; | ||||||
|  | 	stix_size_t len; | ||||||
|  |  | ||||||
|  | 	len = stix_copybcstr (buf, STIX_COUNTOF(buf), DEFAULT_MODPREFIX); | ||||||
|  |  | ||||||
|  | /* TODO: proper error checking and overflow checking */ | ||||||
|  | 	ucslen = ~(stix_size_t)0; | ||||||
|  | 	bcslen = STIX_COUNTOF(buf) - len; | ||||||
|  | 	stix_ucstoutf8 (name, &ucslen, &buf[len], &bcslen); | ||||||
|  |  | ||||||
|  | printf ("MOD-OPENING %s\n", buf); | ||||||
|  | 	return dlopen (buf, RTLD_NOW); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void mod_close (stix_t* stix, void* handle) | ||||||
|  | { | ||||||
|  | 	dlclose (handle); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void* mod_getsym (stix_t* stix, void* handle, const stix_uch_t* name) | ||||||
|  | { | ||||||
|  | 	stix_bch_t buf[1024]; /* TODO: use a proper buffer. dynamically allocated if conversion result in too a large value */ | ||||||
|  | 	stix_size_t ucslen, bcslen; | ||||||
|  | 	void* sym; | ||||||
|  |  | ||||||
|  | 	buf[0] = '_'; | ||||||
|  |  | ||||||
|  | 	ucslen = ~(stix_size_t)0; | ||||||
|  | 	bcslen = STIX_COUNTOF(buf) - 2; | ||||||
|  | 	stix_ucstoutf8 (name, &ucslen, &buf[1], &bcslen); | ||||||
|  | printf ("MOD_GETSYM [%s]\n", &buf[1]); | ||||||
|  | 	sym = dlsym (handle, &buf[1]); | ||||||
|  | 	if (!sym) | ||||||
|  | 	{ | ||||||
|  | printf ("MOD_GETSYM [%s]\n", &buf[0]); | ||||||
|  | 		sym = dlsym (handle, &buf[0]); | ||||||
|  | 		if (!sym) | ||||||
|  | 		{ | ||||||
|  | 			buf[bcslen + 1] = '_'; | ||||||
|  | 			buf[bcslen + 2] = '\0'; | ||||||
|  | printf ("MOD_GETSYM [%s]\n", &buf[1]); | ||||||
|  | 			sym = dlsym (handle, &buf[1]); | ||||||
|  | 			if (!sym) | ||||||
|  | 			{ | ||||||
|  | printf ("MOD_GETSYM [%s]\n", &buf[0]); | ||||||
|  | 				sym = dlsym (handle, &buf[0]); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return sym; | ||||||
|  | } | ||||||
|  |  | ||||||
| static char* syntax_error_msg[] =  | static char* syntax_error_msg[] =  | ||||||
| { | { | ||||||
| 	"no error", | 	"no error", | ||||||
| @ -233,6 +304,7 @@ int main (int argc, char* argv[]) | |||||||
| 	xtn_t* xtn; | 	xtn_t* xtn; | ||||||
| 	stix_ucs_t objname; | 	stix_ucs_t objname; | ||||||
| 	stix_ucs_t mthname; | 	stix_ucs_t mthname; | ||||||
|  | 	stix_vmprim_t vmprim; | ||||||
| 	int i; | 	int i; | ||||||
|  |  | ||||||
| 	printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu\n",  | 	printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu\n",  | ||||||
| @ -241,17 +313,6 @@ int main (int argc, char* argv[]) | |||||||
| 		(unsigned long int)STIX_MAX_CLASSVARS, | 		(unsigned long int)STIX_MAX_CLASSVARS, | ||||||
| 		(unsigned long int)STIX_MAX_CLASSINSTVARS); | 		(unsigned long int)STIX_MAX_CLASSINSTVARS); | ||||||
|  |  | ||||||
| { |  | ||||||
| stix_oop_t k; |  | ||||||
| k = STIX_OOP_FROM_SMINT(-1); |  | ||||||
| printf ("%ld %ld %ld %lX\n", (long int)STIX_OOP_TO_SMINT(k), (long int)STIX_SMINT_MIN, (long int)STIX_SMINT_MAX, (long)LONG_MIN); |  | ||||||
|  |  | ||||||
| k = STIX_OOP_FROM_SMINT(STIX_SMINT_MAX); |  | ||||||
| printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k)); |  | ||||||
|  |  | ||||||
| k = STIX_OOP_FROM_SMINT(STIX_SMINT_MIN); |  | ||||||
| printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #if !defined(macintosh) | #if !defined(macintosh) | ||||||
| 	if (argc < 2) | 	if (argc < 2) | ||||||
| @ -261,18 +322,32 @@ printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k)); | |||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | 	/* | ||||||
| 	{ | 	{ | ||||||
|  | 	stix_oop_t k; | ||||||
| 	stix_oow_t x; | 	stix_oow_t x; | ||||||
|  |  | ||||||
| 	printf ("%u\n", STIX_BITS_MAX(unsigned int, 5)); | 	k = STIX_OOP_FROM_SMINT(-1); | ||||||
|  | 	printf ("%ld %ld %ld %lX\n", (long int)STIX_OOP_TO_SMINT(k), (long int)STIX_SMINT_MIN, (long int)STIX_SMINT_MAX, (long)LONG_MIN); | ||||||
|  |  | ||||||
|  | 	k = STIX_OOP_FROM_SMINT(STIX_SMINT_MAX); | ||||||
|  | 	printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k)); | ||||||
|  |  | ||||||
|  | 	k = STIX_OOP_FROM_SMINT(STIX_SMINT_MIN); | ||||||
|  | 	printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k)); | ||||||
|  |  | ||||||
|  | 	printf ("%u\n", STIX_BITS_MAX(unsigned int, 5)); | ||||||
| 	x = STIX_CLASS_SPEC_MAKE (10, 1, STIX_OBJ_TYPE_CHAR); | 	x = STIX_CLASS_SPEC_MAKE (10, 1, STIX_OBJ_TYPE_CHAR); | ||||||
| 	printf ("%lu %lu %lu %lu\n", (unsigned long int)x, (unsigned long int)STIX_OOP_FROM_SMINT(x), | 	printf ("%lu %lu %lu %lu\n", (unsigned long int)x, (unsigned long int)STIX_OOP_FROM_SMINT(x), | ||||||
| 		(unsigned long int)STIX_CLASS_SPEC_NAMED_INSTVAR(x), | 		(unsigned long int)STIX_CLASS_SPEC_NAMED_INSTVAR(x), | ||||||
| 		(unsigned long int)STIX_CLASS_SPEC_INDEXED_TYPE(x)); | 		(unsigned long int)STIX_CLASS_SPEC_INDEXED_TYPE(x)); | ||||||
| 	} | 	}*/ | ||||||
|  |  | ||||||
| 	stix = stix_open (&sys_mmgr, STIX_SIZEOF(xtn_t), 512000lu, STIX_NULL); | 	vmprim.mod_open = mod_open; | ||||||
|  | 	vmprim.mod_close = mod_close; | ||||||
|  | 	vmprim.mod_getsym = mod_getsym; | ||||||
|  |  | ||||||
|  | 	stix = stix_open (&sys_mmgr, STIX_SIZEOF(xtn_t), 512000lu, &vmprim, STIX_NULL); | ||||||
| 	if (!stix) | 	if (!stix) | ||||||
| 	{ | 	{ | ||||||
| 		printf ("cannot open stix\n"); | 		printf ("cannot open stix\n"); | ||||||
| @ -283,9 +358,9 @@ printf ("%ld\n", (long int)STIX_OOP_TO_SMINT(k)); | |||||||
| 		stix_oow_t tab_size; | 		stix_oow_t tab_size; | ||||||
|  |  | ||||||
| 		tab_size = 5000; | 		tab_size = 5000; | ||||||
| 		stix_setoption (stix, STIX_DFL_SYMTAB_SIZE, &tab_size); | 		stix_setoption (stix, STIX_SYMTAB_SIZE, &tab_size); | ||||||
| 		tab_size = 5000; | 		tab_size = 5000; | ||||||
| 		stix_setoption (stix, STIX_DFL_SYSDIC_SIZE, &tab_size); | 		stix_setoption (stix, STIX_SYSDIC_SIZE, &tab_size); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
| @ -60,6 +60,7 @@ | |||||||
| #define STIX_MEMSET(dst,src,size)  memset(dst,src,size) | #define STIX_MEMSET(dst,src,size)  memset(dst,src,size) | ||||||
| #define STIX_MEMCPY(dst,src,size)  memcpy(dst,src,size) | #define STIX_MEMCPY(dst,src,size)  memcpy(dst,src,size) | ||||||
| #define STIX_MEMMOVE(dst,src,size) memmove(dst,src,size) | #define STIX_MEMMOVE(dst,src,size) memmove(dst,src,size) | ||||||
|  | #define STIX_MEMCMP(dst,src,size)  memcmp(dst,src,size) | ||||||
| #define STIX_ASSERT(x)             assert(x) | #define STIX_ASSERT(x)             assert(x) | ||||||
|  |  | ||||||
| #define STIX_ALIGN(x,y) ((((x) + (y) - 1) / (y)) * (y)) | #define STIX_ALIGN(x,y) ((((x) + (y) - 1) / (y)) * (y)) | ||||||
| @ -862,7 +863,17 @@ int stix_equalchars ( | |||||||
|  |  | ||||||
| int stix_equalchars2 ( | int stix_equalchars2 ( | ||||||
| 	const stix_ucs_t* str1, | 	const stix_ucs_t* str1, | ||||||
| 	const char*       str2 | 	const stix_bch_t* str2 | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | int stix_compucstr ( | ||||||
|  | 	const stix_uch_t* str1, | ||||||
|  | 	const stix_uch_t* str2 | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | int stix_compbcstr ( | ||||||
|  | 	const stix_bch_t* str1, | ||||||
|  | 	const stix_bch_t* str2 | ||||||
| ); | ); | ||||||
|  |  | ||||||
| void stix_copychars ( | void stix_copychars ( | ||||||
| @ -871,12 +882,30 @@ void stix_copychars ( | |||||||
| 	stix_size_t       len | 	stix_size_t       len | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | void stix_copychars2 ( | ||||||
|  | 	stix_uch_t*       dst, | ||||||
|  | 	const stix_bch_t* src, | ||||||
|  | 	stix_size_t       len | ||||||
|  | ); | ||||||
|  |  | ||||||
| stix_uch_t* stix_findchar ( | stix_uch_t* stix_findchar ( | ||||||
| 	const stix_uch_t* ptr, | 	const stix_uch_t* ptr, | ||||||
| 	stix_size_t       len, | 	stix_size_t       len, | ||||||
| 	stix_uch_t        c | 	stix_uch_t        c | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | stix_size_t stix_copyucstr ( | ||||||
|  | 	stix_uch_t*       dst, | ||||||
|  | 	stix_size_t       len, | ||||||
|  | 	const stix_uch_t* src | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | stix_size_t stix_copybcstr ( | ||||||
|  | 	stix_bch_t*       dst, | ||||||
|  | 	stix_size_t       len, | ||||||
|  | 	const stix_bch_t* src | ||||||
|  | ); | ||||||
|  |  | ||||||
| /* ========================================================================= */ | /* ========================================================================= */ | ||||||
| /* gc.c                                                                     */ | /* gc.c                                                                     */ | ||||||
| /* ========================================================================= */ | /* ========================================================================= */ | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ | |||||||
| #include "stix-prv.h" | #include "stix-prv.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize, stix_errnum_t* errnum) | stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize, const stix_vmprim_t* vmprim, stix_errnum_t* errnum) | ||||||
| { | { | ||||||
| 	stix_t* stix; | 	stix_t* stix; | ||||||
|  |  | ||||||
| @ -37,7 +37,7 @@ stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize, | |||||||
| 	stix = STIX_MMGR_ALLOC (mmgr, STIX_SIZEOF(*stix) + xtnsize); | 	stix = STIX_MMGR_ALLOC (mmgr, STIX_SIZEOF(*stix) + xtnsize); | ||||||
| 	if (stix) | 	if (stix) | ||||||
| 	{ | 	{ | ||||||
| 		if (stix_init(stix, mmgr, heapsize) <= -1) | 		if (stix_init(stix, mmgr, heapsize, vmprim) <= -1) | ||||||
| 		{ | 		{ | ||||||
| 			if (errnum) *errnum = stix->errnum; | 			if (errnum) *errnum = stix->errnum; | ||||||
| 			STIX_MMGR_FREE (mmgr, stix); | 			STIX_MMGR_FREE (mmgr, stix); | ||||||
| @ -56,10 +56,11 @@ void stix_close (stix_t* stix) | |||||||
| 	STIX_MMGR_FREE (stix->mmgr, stix); | 	STIX_MMGR_FREE (stix->mmgr, stix); | ||||||
| } | } | ||||||
|  |  | ||||||
| int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_size_t heapsz) | int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_size_t heapsz, const stix_vmprim_t* vmprim) | ||||||
| { | { | ||||||
| 	STIX_MEMSET (stix, 0, STIX_SIZEOF(*stix)); | 	STIX_MEMSET (stix, 0, STIX_SIZEOF(*stix)); | ||||||
| 	stix->mmgr = mmgr; | 	stix->mmgr = mmgr; | ||||||
|  | 	stix->vmprim = *vmprim; | ||||||
|  |  | ||||||
| 	/*stix->permheap = stix_makeheap (stix, what is the best size???); | 	/*stix->permheap = stix_makeheap (stix, what is the best size???); | ||||||
| 	if (!stix->curheap) goto oops; */ | 	if (!stix->curheap) goto oops; */ | ||||||
| @ -68,6 +69,8 @@ int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_size_t heapsz) | |||||||
| 	stix->newheap = stix_makeheap (stix, heapsz); | 	stix->newheap = stix_makeheap (stix, heapsz); | ||||||
| 	if (!stix->newheap) goto oops; | 	if (!stix->newheap) goto oops; | ||||||
|  |  | ||||||
|  | 	if (stix_rbt_init (&stix->pmtable, mmgr, STIX_SIZEOF(stix_uch_t), 1) <= -1) goto oops; | ||||||
|  | 	stix_rbt_setstyle (&stix->pmtable, stix_getrbtstyle(STIX_RBT_STYLE_INLINE_COPIERS)); | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
| oops: | oops: | ||||||
| @ -86,11 +89,12 @@ void stix_fini (stix_t* stix) | |||||||
| 		if (cb->fini) cb->fini (stix); | 		if (cb->fini) cb->fini (stix); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	stix_rbt_fini (&stix->pmtable); | ||||||
|  |  | ||||||
| 	stix_killheap (stix, stix->newheap); | 	stix_killheap (stix, stix->newheap); | ||||||
| 	stix_killheap (stix, stix->curheap); | 	stix_killheap (stix, stix->curheap); | ||||||
| 	stix_killheap (stix, stix->permheap); | 	stix_killheap (stix, stix->permheap); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	/* deregister all callbacks */ | 	/* deregister all callbacks */ | ||||||
| 	while (stix->cblist) stix_deregcb (stix, stix->cblist); | 	while (stix->cblist) stix_deregcb (stix, stix->cblist); | ||||||
| } | } | ||||||
| @ -124,11 +128,13 @@ int stix_setoption (stix_t* stix, stix_option_t id, const void* value) | |||||||
| 			stix->option.trait = *(const int*)value; | 			stix->option.trait = *(const int*)value; | ||||||
| 			return 0; | 			return 0; | ||||||
|  |  | ||||||
| 		case STIX_DFL_SYMTAB_SIZE: | 		case STIX_SYMTAB_SIZE: | ||||||
| 			stix->option.dfl_symtab_size = *(stix_oow_t*)value; | 			stix->option.dfl_symtab_size = *(stix_oow_t*)value; | ||||||
|  | 			return 0; | ||||||
|  |  | ||||||
| 		case STIX_DFL_SYSDIC_SIZE: | 		case STIX_SYSDIC_SIZE: | ||||||
| 			stix->option.dfl_sysdic_size = *(stix_oow_t*)value; | 			stix->option.dfl_sysdic_size = *(stix_oow_t*)value; | ||||||
|  | 			return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stix->errnum = STIX_EINVAL; | 	stix->errnum = STIX_EINVAL; | ||||||
| @ -143,10 +149,10 @@ int stix_getoption (stix_t* stix, stix_option_t id, void* value) | |||||||
| 			*(int*)value = stix->option.trait; | 			*(int*)value = stix->option.trait; | ||||||
| 			return 0; | 			return 0; | ||||||
|  |  | ||||||
| 		case STIX_DFL_SYMTAB_SIZE: | 		case STIX_SYMTAB_SIZE: | ||||||
| 			*(stix_oow_t*)value = stix->option.dfl_symtab_size; | 			*(stix_oow_t*)value = stix->option.dfl_symtab_size; | ||||||
|  |  | ||||||
| 		case STIX_DFL_SYSDIC_SIZE: | 		case STIX_SYSDIC_SIZE: | ||||||
| 			*(stix_oow_t*)value = stix->option.dfl_sysdic_size; | 			*(stix_oow_t*)value = stix->option.dfl_sysdic_size; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @ -214,7 +220,7 @@ int stix_equalchars (const stix_uch_t* str1, const stix_uch_t* str2, stix_size_t | |||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| int stix_equalchars2 (const stix_ucs_t* str1, const char* str2) | int stix_equalchars2 (const stix_ucs_t* str1, const stix_bch_t* str2) | ||||||
| { | { | ||||||
| 	const stix_uch_t* ptr, * end; | 	const stix_uch_t* ptr, * end; | ||||||
|  |  | ||||||
| @ -229,12 +235,72 @@ int stix_equalchars2 (const stix_ucs_t* str1, const char* str2) | |||||||
| 	return ptr >= end && *str2 == '\0'; | 	return ptr >= end && *str2 == '\0'; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int stix_compucstr (const stix_uch_t* str1, const stix_uch_t* str2) | ||||||
|  | { | ||||||
|  | 	while (*str1 == *str2) | ||||||
|  | 	{ | ||||||
|  | 		if (*str1 == '\0') return 0; | ||||||
|  | 		str1++, str2++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return (*str1 > *str2)? 1: -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int stix_compbcstr (const stix_bch_t* str1, const stix_bch_t* str2) | ||||||
|  | { | ||||||
|  | 	while (*str1 == *str2) | ||||||
|  | 	{ | ||||||
|  | 		if (*str1 == '\0') return 0; | ||||||
|  | 		str1++, str2++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return (*str1 > *str2)? 1: -1; | ||||||
|  | } | ||||||
|  |  | ||||||
| void stix_copychars (stix_uch_t* dst, const stix_uch_t* src, stix_size_t len) | void stix_copychars (stix_uch_t* dst, const stix_uch_t* src, stix_size_t len) | ||||||
| { | { | ||||||
| 	stix_size_t i; | 	stix_size_t i; | ||||||
| 	for (i = 0; i < len; i++) dst[i] = src[i]; | 	for (i = 0; i < len; i++) dst[i] = src[i]; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void stix_copychars2 (stix_uch_t* dst, const stix_bch_t* src, stix_size_t len) | ||||||
|  | { | ||||||
|  | 	stix_size_t i; | ||||||
|  | 	for (i = 0; i < len; i++) dst[i] = src[i]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_size_t stix_copyucstr (stix_uch_t* dst, stix_size_t len, const stix_uch_t* src) | ||||||
|  | { | ||||||
|  | 	stix_uch_t* p, * p2; | ||||||
|  |  | ||||||
|  | 	p = dst; p2 = dst + len - 1; | ||||||
|  |  | ||||||
|  | 	while (p < p2) | ||||||
|  | 	{ | ||||||
|  | 		 if (*src == '\0') break; | ||||||
|  | 		 *p++ = *src++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (len > 0) *p = '\0'; | ||||||
|  | 	return p - dst; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_size_t stix_copybcstr (stix_bch_t* dst, stix_size_t len, const stix_bch_t* src) | ||||||
|  | { | ||||||
|  | 	stix_bch_t* p, * p2; | ||||||
|  |  | ||||||
|  | 	p = dst; p2 = dst + len - 1; | ||||||
|  |  | ||||||
|  | 	while (p < p2) | ||||||
|  | 	{ | ||||||
|  | 		 if (*src == '\0') break; | ||||||
|  | 		 *p++ = *src++; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (len > 0) *p = '\0'; | ||||||
|  | 	return p - dst; | ||||||
|  | } | ||||||
|  |  | ||||||
| stix_uch_t* stix_findchar (const stix_uch_t* ptr, stix_size_t len, stix_uch_t c) | stix_uch_t* stix_findchar (const stix_uch_t* ptr, stix_size_t len, stix_uch_t c) | ||||||
| { | { | ||||||
| 	const stix_uch_t* end; | 	const stix_uch_t* end; | ||||||
|  | |||||||
							
								
								
									
										297
									
								
								stix/lib/stix.h
									
									
									
									
									
								
							
							
						
						
									
										297
									
								
								stix/lib/stix.h
									
									
									
									
									
								
							| @ -27,252 +27,12 @@ | |||||||
| #ifndef _STIX_H_ | #ifndef _STIX_H_ | ||||||
| #define _STIX_H_ | #define _STIX_H_ | ||||||
|  |  | ||||||
|  | #include "stix-cmn.h" | ||||||
|  | #include "stix-rbt.h" | ||||||
|  |  | ||||||
| /* TODO: move this macro out to the build files.... */ | /* TODO: move this macro out to the build files.... */ | ||||||
| #define STIX_INCLUDE_COMPILER | #define STIX_INCLUDE_COMPILER | ||||||
|  |  | ||||||
| /* ========================================================================= |  | ||||||
|  * PRIMITIVE TYPE DEFINTIONS |  | ||||||
|  * ========================================================================= */ |  | ||||||
| /* TODO: define these types and macros using autoconf */ |  | ||||||
| typedef unsigned char      stix_uint8_t; |  | ||||||
| typedef signed char        stix_int8_t; |  | ||||||
|  |  | ||||||
| typedef unsigned short int stix_uint16_t; |  | ||||||
| typedef signed short int stix_int16_t; |  | ||||||
|  |  | ||||||
| #if defined(__MSDOS__) |  | ||||||
| 	typedef unsigned long int stix_uint32_t; |  | ||||||
| 	typedef signed long int stix_int32_t; |  | ||||||
| #else |  | ||||||
| 	typedef unsigned int stix_uint32_t; |  | ||||||
| 	typedef signed int stix_int32_t; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(_WIN64) |  | ||||||
| 	typedef unsigned __int64  stix_uintptr_t; |  | ||||||
| 	typedef signed __int64    stix_intptr_t; |  | ||||||
| 	typedef unsigned __int64  stix_size_t; |  | ||||||
| 	typedef signed __int64    stix_ssize_t; |  | ||||||
| #else |  | ||||||
| 	typedef unsigned long int stix_uintptr_t; |  | ||||||
| 	typedef signed long int   stix_intptr_t; |  | ||||||
| 	typedef unsigned long int stix_size_t; |  | ||||||
| 	typedef signed long int   stix_ssize_t; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| typedef stix_uint8_t  stix_byte_t; |  | ||||||
| typedef stix_uint16_t stix_uch_t; /* TODO ... wchar_t??? */ |  | ||||||
| typedef stix_int32_t  stix_uci_t; |  | ||||||
| typedef char          stix_bch_t; |  | ||||||
|  |  | ||||||
| struct stix_ucs_t |  | ||||||
| { |  | ||||||
| 	stix_uch_t* ptr; |  | ||||||
| 	stix_size_t len; |  | ||||||
| }; |  | ||||||
| typedef struct stix_ucs_t stix_ucs_t; |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* ========================================================================= |  | ||||||
|  * PRIMITIVE MACROS |  | ||||||
|  * ========================================================================= */ |  | ||||||
| #define STIX_UCI_EOF ((stix_uci_t)-1) |  | ||||||
| #define STIX_UCI_NL  ((stix_uci_t)'\n') |  | ||||||
|  |  | ||||||
| #define STIX_SIZEOF(x) (sizeof(x)) |  | ||||||
| #define STIX_COUNTOF(x) (sizeof(x) / sizeof(x[0])) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The STIX_OFFSETOF() macro returns the offset of a field from the beginning |  | ||||||
|  * of a structure. |  | ||||||
|  */ |  | ||||||
| #define STIX_OFFSETOF(type,member) ((stix_uintptr_t)&((type*)0)->member) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The STIX_ALIGNOF() macro returns the alignment size of a structure. |  | ||||||
|  * Note that this macro may not work reliably depending on the type given. |  | ||||||
|  */ |  | ||||||
| #define STIX_ALIGNOF(type) STIX_OFFSETOF(struct { stix_uint8_t d1; type d2; }, d2) |  | ||||||
|         /*(sizeof(struct { stix_uint8_t d1; type d2; }) - sizeof(type))*/ |  | ||||||
|  |  | ||||||
| #if defined(__cplusplus) |  | ||||||
| #	if (__cplusplus >= 201103L) /* C++11 */ |  | ||||||
| #		define STIX_NULL nullptr |  | ||||||
| #	else |  | ||||||
| #		define STIX_NULL (0) |  | ||||||
| #	endif |  | ||||||
| #else |  | ||||||
| #	define STIX_NULL ((void*)0) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| /* make a low bit mask that can mask off low n bits*/ |  | ||||||
| #define STIX_LBMASK(type,n) (~(~((type)0) << (n)))  |  | ||||||
|  |  | ||||||
| /* get 'length' bits starting from the bit at the 'offset' */ |  | ||||||
| #define STIX_GETBITS(type,value,offset,length) \ |  | ||||||
| 	((((type)(value)) >> (offset)) & STIX_LBMASK(type,length)) |  | ||||||
|  |  | ||||||
| #define STIX_SETBITS(type,value,offset,length,bits) \ |  | ||||||
| 	(value = (((type)(value)) | (((bits) & STIX_LBMASK(type,length)) << (offset)))) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /**  |  | ||||||
|  * The STIX_BITS_MAX() macros calculates the maximum value that the 'nbits' |  | ||||||
|  * bits of an unsigned integer of the given 'type' can hold. |  | ||||||
|  * \code |  | ||||||
|  * printf ("%u", STIX_BITS_MAX(unsigned int, 5)); |  | ||||||
|  * \endcode |  | ||||||
|  */ |  | ||||||
| /*#define STIX_BITS_MAX(type,nbits) ((((type)1) << (nbits)) - 1)*/ |  | ||||||
| #define STIX_BITS_MAX(type,nbits) ((~(type)0) >> (STIX_SIZEOF(type) * 8 - (nbits))) |  | ||||||
|  |  | ||||||
| /* ========================================================================= |  | ||||||
|  * POINTER MANIPULATION MACROS |  | ||||||
|  * ========================================================================= */ |  | ||||||
|  |  | ||||||
| #if defined(__MSDOS__) |  | ||||||
| #	define STIX_INCPTR(type,base,inc)  (((type __huge*)base) + (inc)) |  | ||||||
| #	define STIX_DECPTR(type,base,inc)  (((type __huge*)base) - (inc)) |  | ||||||
| #	define STIX_GTPTR(type,ptr1,ptr2)  (((type __huge*)ptr1) > ((type __huge*)ptr2)) |  | ||||||
| #	define STIX_GEPTR(type,ptr1,ptr2)  (((type __huge*)ptr1) >= ((type __huge*)ptr2)) |  | ||||||
| #	define STIX_LTPTR(type,ptr1,ptr2)  (((type __huge*)ptr1) < ((type __huge*)ptr2)) |  | ||||||
| #	define STIX_LEPTR(type,ptr1,ptr2)  (((type __huge*)ptr1) <= ((type __huge*)ptr2)) |  | ||||||
| #	define STIX_EQPTR(type,ptr1,ptr2)  (((type __huge*)ptr1) == ((type __huge*)ptr2)) |  | ||||||
| #	define STIX_SUBPTR(type,ptr1,ptr2) (((type __huge*)ptr1) - ((type __huge*)ptr2)) |  | ||||||
| #else |  | ||||||
| #	define STIX_INCPTR(type,base,inc)  (((type*)base) + (inc)) |  | ||||||
| #	define STIX_DECPTR(type,base,inc)  (((type*)base) - (inc)) |  | ||||||
| #	define STIX_GTPTR(type,ptr1,ptr2)  (((type*)ptr1) > ((type*)ptr2)) |  | ||||||
| #	define STIX_GEPTR(type,ptr1,ptr2)  (((type*)ptr1) >= ((type*)ptr2)) |  | ||||||
| #	define STIX_LTPTR(type,ptr1,ptr2)  (((type*)ptr1) < ((type*)ptr2)) |  | ||||||
| #	define STIX_LEPTR(type,ptr1,ptr2)  (((type*)ptr1) <= ((type*)ptr2)) |  | ||||||
| #	define STIX_EQPTR(type,ptr1,ptr2)  (((type*)ptr1) == ((type*)ptr2)) |  | ||||||
| #	define STIX_SUBPTR(type,ptr1,ptr2) (((type*)ptr1) - ((type*)ptr2)) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| /* ========================================================================= |  | ||||||
|  * MMGR |  | ||||||
|  * ========================================================================= */ |  | ||||||
| typedef struct stix_mmgr_t stix_mmgr_t; |  | ||||||
|  |  | ||||||
| /**  |  | ||||||
|  * allocate a memory chunk of the size \a n. |  | ||||||
|  * \return pointer to a memory chunk on success, #STIX_NULL on failure. |  | ||||||
|  */ |  | ||||||
| typedef void* (*stix_mmgr_alloc_t)   (stix_mmgr_t* mmgr, stix_size_t n); |  | ||||||
| /**  |  | ||||||
|  * resize a memory chunk pointed to by \a ptr to the size \a n. |  | ||||||
|  * \return pointer to a memory chunk on success, #STIX_NULL on failure. |  | ||||||
|  */ |  | ||||||
| typedef void* (*stix_mmgr_realloc_t) (stix_mmgr_t* mmgr, void* ptr, stix_size_t n); |  | ||||||
| /** |  | ||||||
|  * free a memory chunk pointed to by \a ptr. |  | ||||||
|  */ |  | ||||||
| typedef void  (*stix_mmgr_free_t)    (stix_mmgr_t* mmgr, void* ptr); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The stix_mmgr_t type defines the memory management interface. |  | ||||||
|  * As the type is merely a structure, it is just used as a single container |  | ||||||
|  * for memory management functions with a pointer to user-defined data.  |  | ||||||
|  * The user-defined data pointer \a ctx is passed to each memory management  |  | ||||||
|  * function whenever it is called. You can allocate, reallocate, and free  |  | ||||||
|  * a memory chunk. |  | ||||||
|  * |  | ||||||
|  * For example, a stix_xxx_open() function accepts a pointer of the stix_mmgr_t |  | ||||||
|  * type and the xxx object uses it to manage dynamic data within the object.  |  | ||||||
|  */ |  | ||||||
| struct stix_mmgr_t |  | ||||||
| { |  | ||||||
| 	stix_mmgr_alloc_t   alloc;   /**< allocation function */ |  | ||||||
| 	stix_mmgr_realloc_t realloc; /**< resizing function */ |  | ||||||
| 	stix_mmgr_free_t    free;    /**< disposal function */ |  | ||||||
| 	void*               ctx;     /**< user-defined data pointer */ |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The STIX_MMGR_ALLOC() macro allocates a memory block of the \a size bytes |  | ||||||
|  * using the \a mmgr memory manager. |  | ||||||
|  */ |  | ||||||
| #define STIX_MMGR_ALLOC(mmgr,size) ((mmgr)->alloc(mmgr,size)) |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The STIX_MMGR_REALLOC() macro resizes a memory block pointed to by \a ptr  |  | ||||||
|  * to the \a size bytes using the \a mmgr memory manager. |  | ||||||
|  */ |  | ||||||
| #define STIX_MMGR_REALLOC(mmgr,ptr,size) ((mmgr)->realloc(mmgr,ptr,size)) |  | ||||||
|  |  | ||||||
| /**  |  | ||||||
|  * The STIX_MMGR_FREE() macro deallocates the memory block pointed to by \a ptr. |  | ||||||
|  */ |  | ||||||
| #define STIX_MMGR_FREE(mmgr,ptr) ((mmgr)->free(mmgr,ptr)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* ========================================================================= |  | ||||||
|  * CMGR |  | ||||||
|  * =========================================================================*/ |  | ||||||
|  |  | ||||||
| typedef struct stix_cmgr_t stix_cmgr_t; |  | ||||||
|  |  | ||||||
| typedef stix_size_t (*stix_cmgr_bctouc_t) ( |  | ||||||
| 	const stix_bch_t*   mb,  |  | ||||||
| 	stix_size_t         size, |  | ||||||
| 	stix_uch_t*         wc |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| typedef stix_size_t (*stix_cmgr_uctobc_t) ( |  | ||||||
| 	stix_uch_t    wc, |  | ||||||
| 	stix_bch_t*   mb, |  | ||||||
| 	stix_size_t   size |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * The stix_cmgr_t type defines the character-level interface to  |  | ||||||
|  * multibyte/wide-character conversion. This interface doesn't  |  | ||||||
|  * provide any facility to store conversion state in a context |  | ||||||
|  * independent manner. This leads to the limitation that it can |  | ||||||
|  * handle a stateless multibyte encoding only. |  | ||||||
|  */ |  | ||||||
| struct stix_cmgr_t |  | ||||||
| { |  | ||||||
| 	stix_cmgr_bctouc_t bctouc; |  | ||||||
| 	stix_cmgr_uctobc_t uctobc; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /* ========================================================================= |  | ||||||
|  * MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER/LINKER |  | ||||||
|  * =========================================================================*/ |  | ||||||
|  |  | ||||||
| #if defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__)) |  | ||||||
| #	define STIX_IMPORT __declspec(dllimport) |  | ||||||
| #	define STIX_EXPORT __declspec(dllexport) |  | ||||||
| #	define STIX_PRIVATE  |  | ||||||
| #elif defined(__GNUC__) && (__GNUC__>=4) |  | ||||||
| #	define STIX_IMPORT __attribute__((visibility("default"))) |  | ||||||
| #	define STIX_EXPORT __attribute__((visibility("default"))) |  | ||||||
| #	define STIX_PRIVATE __attribute__((visibility("hidden"))) |  | ||||||
| /*#	define STIX_PRIVATE __attribute__((visibility("internal")))*/ |  | ||||||
| #else |  | ||||||
| #	define STIX_IMPORT |  | ||||||
| #	define STIX_EXPORT |  | ||||||
| #	define STIX_PRIVATE |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(__STDC_VERSION__) && (__STDC_VERSION__>=199901L) |  | ||||||
| #	define STIX_INLINE inline |  | ||||||
| #	define STIX_HAVE_INLINE |  | ||||||
| #elif defined(__GNUC__) && defined(__GNUC_GNU_INLINE__) |  | ||||||
| 		/* gcc disables inline when -std=c89 or -ansi is used.  |  | ||||||
| 		 * so use __inline__ supported by gcc regardless of the options */ |  | ||||||
| #	define STIX_INLINE /*extern*/ __inline__ |  | ||||||
| #	define STIX_HAVE_INLINE |  | ||||||
| #else |  | ||||||
| #	define STIX_INLINE  |  | ||||||
| #	undef STIX_HAVE_INLINE |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* ========================================================================== */ | /* ========================================================================== */ | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @ -301,8 +61,8 @@ typedef enum stix_errnum_t stix_errnum_t; | |||||||
| enum stix_option_t | enum stix_option_t | ||||||
| { | { | ||||||
| 	STIX_TRAIT, | 	STIX_TRAIT, | ||||||
| 	STIX_DFL_SYMTAB_SIZE, | 	STIX_SYMTAB_SIZE, /* default system table size */ | ||||||
| 	STIX_DFL_SYSDIC_SIZE | 	STIX_SYSDIC_SIZE  /* default system dictionary size */ | ||||||
| }; | }; | ||||||
| typedef enum stix_option_t stix_option_t; | typedef enum stix_option_t stix_option_t; | ||||||
|  |  | ||||||
| @ -741,33 +501,32 @@ struct stix_heap_t | |||||||
| typedef struct stix_t stix_t; | typedef struct stix_t stix_t; | ||||||
|  |  | ||||||
| /* ========================================================================= | /* ========================================================================= | ||||||
|  * MODULE MANIPULATION |  * VIRTUAL MACHINE PRIMITIVES | ||||||
|  * ========================================================================= */ |  * ========================================================================= */ | ||||||
| enum stix_mod_cmd_t | #define STIX_MOD_PREFIX_LEN_MAX  30 | ||||||
|  | #define STIX_MOD_POSTFIX_LEN_MAX 30 | ||||||
|  | #define STIX_MOD_NAME_LEN_MAX    60 | ||||||
|  |  | ||||||
|  | struct stix_mod_spec_t | ||||||
| { | { | ||||||
| 	STIX_MOD_OPEN, | 	const stix_uch_t prefix[STIX_MOD_PREFIX_LEN_MAX]; | ||||||
| 	STIX_MOD_CLOSE, | 	const stix_uch_t postfix[STIX_MOD_POSTFIX_LEN_MAX]; | ||||||
| 	STIX_MOD_READ | 	const stix_uch_t name[STIX_MOD_NAME_LEN_MAX]; | ||||||
| }; | }; | ||||||
| typedef enum stix_mod_cmd_t stix_mod_cmd_t; | typedef struct stix_mod_spec_t stix_mod_spec_t; | ||||||
|  |  | ||||||
| struct stix_mod_arg_t | typedef void* (*stix_mod_open_t) (stix_t* stix, const stix_uch_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_uch_t* name); | ||||||
|  |  | ||||||
|  | struct stix_vmprim_t | ||||||
| { | { | ||||||
| 	/* [INPUT] */ | 	stix_mod_open_t mod_open; | ||||||
| 	const stix_uch_t* prefix; | 	stix_mod_close_t mod_close; | ||||||
| 	const stix_uch_t* postfix; | 	stix_mod_getsym_t mod_getsym; | ||||||
| 	const stix_uch_t* name; |  | ||||||
|  |  | ||||||
| 	/* [OUTPUT] */ |  | ||||||
| 	void* handle; |  | ||||||
| }; | }; | ||||||
| typedef struct stix_mod_arg_t stix_mod_arg_t; |  | ||||||
|  |  | ||||||
| typedef int (*stix_mod_impl_t) ( | typedef struct stix_vmprim_t stix_vmprim_t; | ||||||
| 	stix_t*         stix, |  | ||||||
| 	stix_mod_cmd_t  cmd, |  | ||||||
| 	stix_mod_arg_t* arg |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| /* ========================================================================= | /* ========================================================================= | ||||||
|  * IO MANIPULATION |  * IO MANIPULATION | ||||||
| @ -806,10 +565,14 @@ struct stix_t | |||||||
| 		int trait; | 		int trait; | ||||||
| 		stix_oow_t dfl_symtab_size; | 		stix_oow_t dfl_symtab_size; | ||||||
| 		stix_oow_t dfl_sysdic_size; | 		stix_oow_t dfl_sysdic_size; | ||||||
|  | 		stix_ucs_t dfl_mod_prefix[STIX_MOD_PREFIX_LEN_MAX + 1]; | ||||||
|  | 		stix_ucs_t dfl_mod_postfix[STIX_MOD_POSTFIX_LEN_MAX + 1]; | ||||||
| 	} option; | 	} option; | ||||||
|  |  | ||||||
| 	stix_cb_t* cblist; | 	stix_vmprim_t vmprim; | ||||||
|  |  | ||||||
|  | 	stix_cb_t* cblist; | ||||||
|  | 	stix_rbt_t pmtable; /* primitive module table */ | ||||||
| 	/* ========================= */ | 	/* ========================= */ | ||||||
|  |  | ||||||
| 	stix_heap_t* permheap; /* TODO: put kernel objects to here */ | 	stix_heap_t* permheap; /* TODO: put kernel objects to here */ | ||||||
| @ -878,6 +641,7 @@ STIX_EXPORT stix_t* stix_open ( | |||||||
| 	stix_mmgr_t*         mmgr, | 	stix_mmgr_t*         mmgr, | ||||||
| 	stix_size_t          xtnsize, | 	stix_size_t          xtnsize, | ||||||
| 	stix_size_t          heapsize, | 	stix_size_t          heapsize, | ||||||
|  | 	const stix_vmprim_t* vmprim, | ||||||
| 	stix_errnum_t*       errnum | 	stix_errnum_t*       errnum | ||||||
| ); | ); | ||||||
|  |  | ||||||
| @ -888,7 +652,8 @@ STIX_EXPORT void stix_close ( | |||||||
| STIX_EXPORT int stix_init ( | STIX_EXPORT int stix_init ( | ||||||
| 	stix_t*              vm, | 	stix_t*              vm, | ||||||
| 	stix_mmgr_t*         mmgr, | 	stix_mmgr_t*         mmgr, | ||||||
| 	stix_size_t  heapsz | 	stix_size_t          heapsize, | ||||||
|  | 	const stix_vmprim_t* vmprim | ||||||
| ); | ); | ||||||
|  |  | ||||||
| STIX_EXPORT void stix_fini ( | STIX_EXPORT void stix_fini ( | ||||||
|  | |||||||
| @ -482,9 +482,7 @@ static stix_cmgr_t utf8_cmgr = | |||||||
| 	stix_uctoutf8 | 	stix_uctoutf8 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| int stix_utf8toucs ( | int stix_utf8toucs (const stix_bch_t* bcs, stix_size_t* bcslen, stix_uch_t* ucs, stix_size_t* ucslen) | ||||||
| 	const stix_bch_t* bcs, stix_size_t* bcslen, |  | ||||||
| 	stix_uch_t* ucs, stix_size_t* ucslen) |  | ||||||
| { | { | ||||||
| 	if (*bcslen == ~(stix_size_t)0) | 	if (*bcslen == ~(stix_size_t)0) | ||||||
| 	{ | 	{ | ||||||
| @ -498,9 +496,7 @@ int stix_utf8toucs ( | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| int stix_ucstoutf8 ( | int stix_ucstoutf8 (const stix_uch_t* ucs, stix_size_t *ucslen, stix_bch_t* bcs, stix_size_t* bcslen) | ||||||
| 	const stix_uch_t* ucs, stix_size_t *ucslen, |  | ||||||
| 	stix_bch_t* bcs, stix_size_t* bcslen) |  | ||||||
| { | { | ||||||
| 	if (*ucslen == ~(stix_size_t)0) | 	if (*ucslen == ~(stix_size_t)0) | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user