simplified some functions

This commit is contained in:
hyung-hwan 2012-11-06 04:30:35 +00:00
parent dfc5fdfdea
commit a3ee069804
7 changed files with 106 additions and 123 deletions

View File

@ -672,7 +672,8 @@ static int comparg (int argc, qse_char_t* argv[], struct arg_t* arg)
gvmv.str.ptr = ++eq;
gvmv.str.len = qse_strlen(eq);
if (qse_htb_upsert (gvm, opt.arg, qse_strlen(opt.arg), &gvmv, 1) == QSE_NULL)
/* +1 for null-termination of the key in the table */
if (qse_htb_upsert (gvm, opt.arg, qse_strlen(opt.arg) + 1, &gvmv, 1) == QSE_NULL)
{
print_error (QSE_T("out of memory\n"));
goto oops;
@ -880,12 +881,11 @@ qse_htb_walk_t add_global (qse_htb_t* map, qse_htb_pair_t* pair, void* arg)
qse_awk_t* awk = (qse_awk_t*)arg;
struct gvmv_t* gvmv = (struct gvmv_t*)QSE_HTB_VPTR(pair);
gvmv->idx = qse_awk_addgbl (awk, QSE_HTB_KPTL(pair));
if (gvmv->idx <= -1)
{
return QSE_HTB_WALK_STOP;
}
/* the key was inserted to the table with a null at the end
* and the key length was even incremetned for that.
* so i can pass the pointer without other adjustments. */
gvmv->idx = qse_awk_addgbl (awk, QSE_HTB_KPTR(pair));
if (gvmv->idx <= -1) return QSE_HTB_WALK_STOP;
return QSE_HTB_WALK_FORWARD;
}

View File

@ -735,6 +735,7 @@ typedef struct qse_awk_rio_t qse_awk_rio_t;
/* ------------------------------------------------------------------------ */
typedef struct qse_awk_fnc_t qse_awk_fnc_t;
typedef struct qse_awk_fnc_spec_t qse_awk_fnc_spec_t;
typedef struct qse_awk_fnc_info_t qse_awk_fnc_info_t;
@ -1614,7 +1615,7 @@ QSE_EXPORT void qse_awk_pushecb (
*/
QSE_EXPORT int qse_awk_addgbl (
qse_awk_t* awk, /**< awk */
const qse_cstr_t* name /**< variable name */
const qse_char_t* name /**< variable name */
);
/**
@ -1623,25 +1624,25 @@ QSE_EXPORT int qse_awk_addgbl (
*/
QSE_EXPORT int qse_awk_delgbl (
qse_awk_t* awk, /**< awk */
const qse_cstr_t* name /**< variable name */
const qse_char_t* name /**< variable name */
);
/**
* The qse_awk_findgbl function returns the numeric ID of an intrinsic global
* The qse_awk_findgbl() function returns the numeric ID of an intrinsic global
* variable.
* @return number >= 0 on success, -1 on failure
*/
QSE_EXPORT int qse_awk_findgbl (
qse_awk_t* awk, /**< awk */
const qse_cstr_t* name /**< variable name */
const qse_char_t* name /**< variable name */
);
/**
* The qse_awk_addfnc() function adds an intrinsic function.
*/
QSE_EXPORT void* qse_awk_addfnc (
QSE_EXPORT qse_awk_fnc_t* qse_awk_addfnc (
qse_awk_t* awk,
const qse_cstr_t* name,
const qse_char_t* name,
const qse_awk_fnc_spec_t* spec
);
@ -1651,7 +1652,7 @@ QSE_EXPORT void* qse_awk_addfnc (
*/
QSE_EXPORT int qse_awk_delfnc (
qse_awk_t* awk, /**< awk */
const qse_cstr_t* name /**< function name */
const qse_char_t* name /**< function name */
);
/**

View File

@ -1492,11 +1492,7 @@ void Awk::clearArguments ()
int Awk::addGlobal (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_addgbl (awk, &nx);
int n = qse_awk_addgbl (awk, name);
if (n <= -1) retrieveError ();
return n;
}
@ -1504,10 +1500,7 @@ int Awk::addGlobal (const char_t* name)
int Awk::deleteGlobal (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_delgbl (awk, &nx);
int n = qse_awk_delgbl (awk, name);
if (n <= -1) retrieveError ();
return n;
}
@ -1515,10 +1508,7 @@ int Awk::deleteGlobal (const char_t* name)
int Awk::findGlobal (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_findgbl (awk, &nx);
int n = qse_awk_findgbl (awk, name);
if (n <= -1) retrieveError ();
return n;
}
@ -1565,10 +1555,6 @@ int Awk::addFunction (
*tmp = handler;
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
fnc_spec_t spec;
QSE_MEMSET (&spec, 0, QSE_SIZEOF(spec));
@ -1580,8 +1566,8 @@ int Awk::addFunction (
spec.impl = functionHandler;
spec.trait = validOpts;
void* p = qse_awk_addfnc (awk, &nx, &spec);
if (p == QSE_NULL)
qse_awk_fnc_t* fnc = qse_awk_addfnc (awk, name, &spec);
if (fnc == QSE_NULL)
{
qse_awk_freemem (awk, tmp);
retrieveError ();
@ -1589,10 +1575,10 @@ int Awk::addFunction (
}
pair_t* pair = qse_htb_upsert (
functionMap, (char_t*)nx.ptr, nx.len, tmp, 0);
functionMap, (char_t*)name, qse_strlen(name), tmp, 0);
if (pair == QSE_NULL)
{
qse_awk_delfnc (awk, &nx);
qse_awk_delfnc (awk, name);
qse_awk_freemem (awk, tmp);
setError (QSE_AWK_ENOMEM);
return -1;
@ -1605,12 +1591,8 @@ int Awk::deleteFunction (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_delfnc (awk, &nx);
if (n == 0) qse_htb_delete (functionMap, nx.ptr, nx.len);
int n = qse_awk_delfnc (awk, name);
if (n == 0) qse_htb_delete (functionMap, name, qse_strlen(name));
else retrieveError ();
return n;

View File

@ -59,7 +59,7 @@ static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
* parameters are passed by reference regarless of the remaining
* chracters.
*/
static qse_awk_fnc_t sys_fnc[] =
static qse_awk_fnc_t sysfnctab[] =
{
/* io functions */
{ {QSE_T("close"), 5}, 0, { {1, 2, QSE_NULL}, fnc_close, QSE_AWK_RIO }, QSE_NULL},
@ -87,18 +87,20 @@ static qse_awk_fnc_t sys_fnc[] =
{ {QSE_T("log10"), 5}, 0, { {1, 1, QSE_NULL}, fnc_log10, 0 }, QSE_NULL},
{ {QSE_T("exp"), 3}, 0, { {1, 1, QSE_NULL}, fnc_exp, 0 }, QSE_NULL},
{ {QSE_T("sqrt"), 4}, 0, { {1, 1, QSE_NULL}, fnc_sqrt, 0 }, QSE_NULL},
{ {QSE_T("int"), 3}, 0, { {1, 1, QSE_NULL}, fnc_int, 0 }, QSE_NULL},
{ {QSE_NULL, 0}, 0, { {0, 0, QSE_NULL}, QSE_NULL, 0 }, QSE_NULL}
{ {QSE_T("int"), 3}, 0, { {1, 1, QSE_NULL}, fnc_int, 0 }, QSE_NULL}
};
void* qse_awk_addfnc (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_fnc_spec_t* spec)
qse_awk_fnc_t* qse_awk_addfnc (qse_awk_t* awk, const qse_char_t* name, const qse_awk_fnc_spec_t* spec)
{
qse_awk_fnc_t* fnc;
qse_size_t fnc_size;
qse_size_t spec_len;
qse_size_t speclen;
qse_cstr_t ncs;
if (name->len <= 0)
ncs.ptr = name;
ncs.len = qse_strlen (name);
if (ncs.len <= 0)
{
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
return QSE_NULL;
@ -108,42 +110,34 @@ void* qse_awk_addfnc (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_fnc_
* such a function registered won't take effect because
* the word is treated as a keyword */
if (qse_awk_getfnc (awk, name) != QSE_NULL)
if (qse_awk_findfnc (awk, &ncs) != QSE_NULL)
{
qse_cstr_t errarg;
errarg.ptr = name->ptr;
errarg.len = name->len;
qse_awk_seterrnum (awk, QSE_AWK_EEXIST, &errarg);
qse_awk_seterrnum (awk, QSE_AWK_EEXIST, &ncs);
return QSE_NULL;
}
spec_len = spec->arg.spec? qse_strlen(spec->arg.spec): 0;
speclen = spec->arg.spec? qse_strlen(spec->arg.spec): 0;
fnc_size =
QSE_SIZEOF(qse_awk_fnc_t) +
(name->len+1) * QSE_SIZEOF(qse_char_t) +
(spec_len+1) * QSE_SIZEOF(qse_char_t);
fnc_size = QSE_SIZEOF(*fnc) + (ncs.len + 1 + speclen + 1) * QSE_SIZEOF(qse_char_t);
fnc = (qse_awk_fnc_t*) qse_awk_callocmem (awk, fnc_size);
if (fnc)
{
qse_char_t* tmp;
tmp = (qse_char_t*)(fnc + 1);
fnc->name.len = qse_strxncpy (tmp, name->len+1, name->ptr, name->len);
fnc->name.len = qse_strcpy (tmp, ncs.ptr);
fnc->name.ptr = tmp;
fnc->spec = *spec;
if (spec->arg.spec)
{
tmp = fnc->name.ptr + fnc->name.len + 1;
qse_strxcpy (tmp, spec_len + 1, spec->arg.spec);
qse_strcpy (tmp, spec->arg.spec);
fnc->spec.arg.spec = tmp;
}
if (qse_htb_insert (awk->fnc.user,
(qse_char_t*)name->ptr, name->len, fnc, 0) == QSE_NULL)
(qse_char_t*)ncs.ptr, ncs.len, fnc, 0) == QSE_NULL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
QSE_AWK_FREE (awk, fnc); fnc = QSE_NULL;
@ -153,16 +147,16 @@ void* qse_awk_addfnc (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_fnc_
return fnc;
}
int qse_awk_delfnc (qse_awk_t* awk, const qse_cstr_t* name)
int qse_awk_delfnc (qse_awk_t* awk, const qse_char_t* name)
{
if (qse_htb_delete (awk->fnc.user, name->ptr, name->len) <= -1)
qse_cstr_t ncs;
ncs.ptr = name;
ncs.len = qse_strlen (name);
if (qse_htb_delete (awk->fnc.user, ncs.ptr, ncs.len) <= -1)
{
qse_cstr_t errarg;
errarg.ptr = name->ptr;
errarg.len = name->len;
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &errarg);
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &ncs);
return -1;
}
@ -174,34 +168,34 @@ void qse_awk_clrfnc (qse_awk_t* awk)
qse_htb_clear (awk->fnc.user);
}
qse_awk_fnc_t* qse_awk_getfnc (qse_awk_t* awk, const qse_cstr_t* name)
qse_awk_fnc_t* qse_awk_findfnc (qse_awk_t* awk, const qse_cstr_t* name)
{
qse_awk_fnc_t* fnc;
qse_htb_pair_t* pair;
int i;
/* search the system function table
* though some optimization like binary search can
* speed up the search, i don't do that since this
* function is called durting parse-time only.
* TODO: binary search.
*/
for (fnc = sys_fnc; fnc->name.ptr != QSE_NULL; fnc++)
for (i = 0; i < QSE_COUNTOF(sysfnctab); i++)
{
if (fnc->spec.trait != 0 &&
(awk->opt.trait & fnc->spec.trait) != fnc->spec.trait) continue;
if ((awk->opt.trait & sysfnctab[i].spec.trait) != sysfnctab[i].spec.trait) continue;
if (qse_strxncmp (
fnc->name.ptr, fnc->name.len,
name->ptr, name->len) == 0) return fnc;
sysfnctab[i].name.ptr, sysfnctab[i].name.len,
name->ptr, name->len) == 0) return &sysfnctab[i];
}
pair = qse_htb_search (awk->fnc.user, name->ptr, name->len);
if (pair == QSE_NULL) return QSE_NULL;
if (pair)
{
qse_awk_fnc_t* fnc;
fnc = (qse_awk_fnc_t*)QSE_HTB_VPTR(pair);
if ((awk->opt.trait & fnc->spec.trait) == fnc->spec.trait) return fnc;
}
fnc = (qse_awk_fnc_t*)QSE_HTB_VPTR(pair);
if (fnc->spec.trait != 0 && (awk->opt.trait & fnc->spec.trait) == 0) return QSE_NULL;
return fnc;
return QSE_NULL;
}
static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
@ -275,7 +269,7 @@ static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
}
}
if (opt != QSE_NULL)
if (opt)
{
if (optlen != 1 ||
(opt[0] != QSE_T('r') && opt[0] != QSE_T('w')))

View File

@ -21,7 +21,6 @@
#ifndef _QSE_LIB_AWK_FNC_H_
#define _QSE_LIB_AWK_FNC_H_
typedef struct qse_awk_fnc_t qse_awk_fnc_t;
struct qse_awk_fnc_t
{
struct
@ -41,7 +40,7 @@ struct qse_awk_fnc_t
extern "C" {
#endif
qse_awk_fnc_t* qse_awk_getfnc (qse_awk_t* awk, const qse_cstr_t* name);
qse_awk_fnc_t* qse_awk_findfnc (qse_awk_t* awk, const qse_cstr_t* name);
#ifdef __cplusplus
}

View File

@ -1081,7 +1081,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
/* note that i'm assigning to rederr in the 'if' conditions below.
* i'm not checking equality */
/* check if it is a builtin function */
if ((qse_awk_getfnc (awk, &name) != QSE_NULL && (rederr = QSE_AWK_EFNCRED)) ||
if ((qse_awk_findfnc (awk, &name) != QSE_NULL && (rederr = QSE_AWK_EFNCRED)) ||
/* check if it has already been defined as a function */
(qse_htb_search (awk->tree.funs, name.ptr, name.len) != QSE_NULL && (rederr = QSE_AWK_EFUNRED)) ||
/* check if it conflicts with a named variable */
@ -1089,7 +1089,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
/* check if it coincides to be a global variable name */
(((g = find_global (awk, &name)) != QSE_LDA_NIL) && (rederr = QSE_AWK_EGBLRED)))
{
SETERR_ARG_LOC (awk, rederr, name.ptr, name.len, &awk->tok.loc);
qse_awk_seterror (awk, rederr, &name, &awk->tok.loc);
return QSE_NULL;
}
@ -1695,7 +1695,7 @@ static int add_global (
}
/* check if it conflicts with a builtin function name */
if (qse_awk_getfnc (awk, name) != QSE_NULL)
if (qse_awk_findfnc (awk, name) != QSE_NULL)
{
SETERR_ARG_LOC (awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
return -1;
@ -1765,11 +1765,14 @@ static int add_global (
return (int)ngbls;
}
int qse_awk_addgbl (qse_awk_t* awk, const qse_cstr_t* name)
int qse_awk_addgbl (qse_awk_t* awk, const qse_char_t* name)
{
int n;
qse_cstr_t ncs;
if (name->len <= 0)
ncs.ptr = name;
ncs.len = qse_strlen(name);;
if (ncs.len <= 0)
{
SETERR_COD (awk, QSE_AWK_EINVAL);
return -1;
@ -1782,7 +1785,7 @@ int qse_awk_addgbl (qse_awk_t* awk, const qse_cstr_t* name)
return -1;
}
n = add_global (awk, name, QSE_NULL, 0);
n = add_global (awk, &ncs, QSE_NULL, 0);
/* update the count of the static globals.
* the total global count has been updated inside add_global. */
@ -1794,22 +1797,26 @@ int qse_awk_addgbl (qse_awk_t* awk, const qse_cstr_t* name)
#define QSE_AWK_NUM_STATIC_GBLS \
(QSE_AWK_MAX_GBL_ID-QSE_AWK_MIN_GBL_ID+1)
int qse_awk_delgbl (qse_awk_t* awk, const qse_cstr_t* name)
int qse_awk_delgbl (qse_awk_t* awk, const qse_char_t* name)
{
qse_size_t n;
qse_cstr_t ncs;
ncs.ptr = name;
ncs.len = qse_strlen (name);
if (awk->tree.ngbls > awk->tree.ngbls_base)
{
/* this function is not allow after qse_awk_parse is called */
SETERR_COD (awk, QSE_AWK_ENOPER);
qse_awk_seterrnum (awk, QSE_AWK_ENOPER, QSE_NULL);
return -1;
}
n = qse_lda_search (awk->parse.gbls,
QSE_AWK_NUM_STATIC_GBLS, name->ptr, name->len);
QSE_AWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
if (n == QSE_LDA_NIL)
{
SETERR_ARG (awk, QSE_AWK_ENOENT, name->ptr, name->len);
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &ncs);
return -1;
}
@ -1828,15 +1835,19 @@ int qse_awk_delgbl (qse_awk_t* awk, const qse_cstr_t* name)
return 0;
}
int qse_awk_findgbl (qse_awk_t* awk, const qse_cstr_t* name)
int qse_awk_findgbl (qse_awk_t* awk, const qse_char_t* name)
{
qse_size_t n;
qse_cstr_t ncs;
ncs.ptr = name;
ncs.len = qse_strlen (name);
n = qse_lda_search (awk->parse.gbls,
QSE_AWK_NUM_STATIC_GBLS, name->ptr, name->len);
QSE_AWK_NUM_STATIC_GBLS, ncs.ptr, ncs.len);
if (n == QSE_LDA_NIL)
{
SETERR_ARG (awk, QSE_AWK_ENOENT, name->ptr, name->len);
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &ncs);
return -1;
}
@ -1923,7 +1934,7 @@ static qse_awk_t* collect_locals (
/* check if it conflicts with a builtin function name
* function f() { local length; } */
if (qse_awk_getfnc (awk, &lcl) != QSE_NULL)
if (qse_awk_findfnc (awk, &lcl) != QSE_NULL)
{
SETERR_ARG_LOC (
awk, QSE_AWK_EFNCRED,
@ -4128,7 +4139,7 @@ static QSE_INLINE int isfunname (qse_awk_t* awk, const qse_xstr_t* name)
static QSE_INLINE int isfnname (qse_awk_t* awk, const qse_xstr_t* name)
{
if (qse_awk_getfnc (awk, name) != QSE_NULL)
if (qse_awk_findfnc (awk, name) != QSE_NULL)
{
/* implicit function */
return FNTYPE_FNC;
@ -4764,7 +4775,7 @@ static qse_awk_nde_t* parse_primary_ident_noseg (
qse_awk_nde_t* nde = QSE_NULL;
/* check if name is an intrinsic function name */
fnc = qse_awk_getfnc (awk, name);
fnc = qse_awk_findfnc (awk, name);
if (fnc)
{
if (MATCH(awk,TOK_LPAREN))
@ -5020,7 +5031,12 @@ static qse_awk_nde_t* parse_primary_ident (
full.len = capa;
nde = parse_primary_ident_segs (awk, xloc, &full, name, nsegs);
if (!nde) QSE_MMGR_FREE (awk->mmgr, full.ptr);
if (!nde || nde->type != QSE_AWK_NDE_FNC)
{
/* the FNC node takes the full name but other
* nodes don't. so i need to free it. i know it's ugly. */
QSE_MMGR_FREE (awk->mmgr, full.ptr);
}
}
else
{

View File

@ -2484,23 +2484,15 @@ qse_cmgr_t* qse_awk_rtx_getcmgrstd (
return QSE_NULL;
}
static int QSE_INLINE add_global (qse_awk_t* awk, const qse_char_t* ptr, qse_size_t len)
{
qse_cstr_t nx;
nx.ptr = ptr;
nx.len = len;
return qse_awk_addgbl (awk, &nx);
}
static int add_globals (qse_awk_t* awk)
{
xtn_t* xtn;
xtn = (xtn_t*) QSE_XTN (awk);
xtn->gbl_argc = add_global (awk, QSE_T("ARGC"), 4);
xtn->gbl_argv = add_global (awk, QSE_T("ARGV"), 4);
xtn->gbl_environ = add_global (awk, QSE_T("ENVIRON"), 7);
xtn->gbl_argc = qse_awk_addgbl (awk, QSE_T("ARGC"));
xtn->gbl_argv = qse_awk_addgbl (awk, QSE_T("ARGV"));
xtn->gbl_environ = qse_awk_addgbl (awk, QSE_T("ENVIRON"));
return (xtn->gbl_argc <= -1 ||
xtn->gbl_argv <= -1 ||
@ -2509,18 +2501,17 @@ static int add_globals (qse_awk_t* awk)
struct fnctab_t
{
qse_cstr_t name;
const qse_char_t* name;
qse_awk_fnc_spec_t spec;
int valid;
};
static struct fnctab_t fnctab[] =
{
{ {QSE_T("rand"), 4}, { {0, 0, QSE_NULL}, fnc_rand, 0 } },
{ {QSE_T("srand"), 5}, { {0, 1, QSE_NULL}, fnc_srand, 0 } },
{ {QSE_T("system"), 6}, { {1, 1, QSE_NULL}, fnc_system , 0 } },
{ {QSE_T("setioattr"), 9}, { {3, 3, QSE_NULL}, fnc_setioattr, QSE_AWK_RIO } },
{ {QSE_T("getioattr"), 9}, { {2, 2, QSE_NULL}, fnc_getioattr, QSE_AWK_RIO } }
{ QSE_T("rand"), { {0, 0, QSE_NULL}, fnc_rand, 0 } },
{ QSE_T("srand"), { {0, 1, QSE_NULL}, fnc_srand, 0 } },
{ QSE_T("system"), { {1, 1, QSE_NULL}, fnc_system , 0 } },
{ QSE_T("setioattr"), { {3, 3, QSE_NULL}, fnc_setioattr, QSE_AWK_RIO } },
{ QSE_T("getioattr"), { {2, 2, QSE_NULL}, fnc_getioattr, QSE_AWK_RIO } }
};
static int add_functions (qse_awk_t* awk)
@ -2529,7 +2520,7 @@ static int add_functions (qse_awk_t* awk)
for (i = 0; i < QSE_COUNTOF(fnctab); i++)
{
if (qse_awk_addfnc (awk, &fnctab[i].name, &fnctab[i].spec) == QSE_NULL) return -1;
if (qse_awk_addfnc (awk, fnctab[i].name, &fnctab[i].spec) == QSE_NULL) return -1;
}
return 0;