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:
parent
e8985e6dc5
commit
394a21b8d6
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user