added qse_awk_fnc_spec_t.

renamed qse_awk_mod_info_t to qse_awk_mod_spec_t
This commit is contained in:
hyung-hwan 2012-11-03 17:44:23 +00:00
parent 7557b22cb8
commit 3f99d7ac3d
17 changed files with 355 additions and 325 deletions

View File

@ -880,7 +880,7 @@ 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_KPTR(pair), QSE_HTB_KLEN(pair));
gvmv->idx = qse_awk_addgbl (awk, QSE_HTB_KPTL(pair));
if (gvmv->idx <= -1)
{
return QSE_HTB_WALK_STOP;

View File

@ -82,9 +82,11 @@ public:
typedef qse_awk_sio_cmd_t sio_cmd_t;
typedef qse_awk_fnc_spec_t fnc_spec_t;
typedef qse_awk_fnc_info_t fnc_info_t;
typedef qse_awk_mod_info_t mod_info_t;
typedef qse_awk_mod_spec_t mod_spec_t;
class Run;
friend class Run;
@ -1226,7 +1228,7 @@ protected:
virtual flt_t exp (flt_t x) = 0;
virtual flt_t sqrt (flt_t x) = 0;
virtual void* modopen (const mod_info_t* info) = 0;
virtual void* modopen (const mod_spec_t* spec) = 0;
virtual void modclose (void* handle) = 0;
virtual void* modsym (void* handle, const char_t* name) = 0;
@ -1265,7 +1267,7 @@ protected:
static flt_t exp (awk_t* awk, flt_t x);
static flt_t sqrt (awk_t* awk, flt_t x);
static void* modopen (awk_t* awk, const mod_info_t* info);
static void* modopen (awk_t* awk, const mod_spec_t* spec);
static void modclose (awk_t* awk, void* handle);
static void* modsym (awk_t* awk, void* handle, const char_t* name);

View File

@ -200,7 +200,7 @@ protected:
flt_t exp (flt_t x);
flt_t sqrt (flt_t x);
void* modopen (const mod_info_t* info);
void* modopen (const mod_spec_t* spec);
void modclose (void* handle);
void* modsym (void* handle, const char_t* name);

View File

@ -303,6 +303,8 @@ struct qse_awk_val_map_data_t
};
typedef struct qse_awk_val_map_data_t qse_awk_val_map_data_t;
/* ------------------------------------------------------------------------ */
/**
* The qse_awk_nde_type_t defines the node types.
*/
@ -378,6 +380,8 @@ struct qse_awk_nde_t
QSE_AWK_NDE_HDR;
};
/* ------------------------------------------------------------------------ */
/**
* The qse_awk_fun_t type defines a structure to maintain functions
* defined with the keyword 'function'.
@ -390,10 +394,7 @@ struct qse_awk_fun_t
};
typedef struct qse_awk_fun_t qse_awk_fun_t;
#define QSE_AWK_FUN_NAME(fun) ((const qse_xstr_t*)&(fun)->name)
#define QSE_AWK_FUN_NAME_PTR(fun) ((const qse_char_t*)(fun)->name.ptr)
#define QSE_AWK_FUN_NAME_LEN(fun) (*(const qse_size_t*)&(fun)->name.len)
#define QSE_AWK_FUN_NARGS(fun) (*(const qse_size_t*)&(fun)->nargs)
/* ------------------------------------------------------------------------ */
typedef int (*qse_awk_sprintf_t) (
qse_awk_t* awk,
@ -414,9 +415,11 @@ typedef qse_flt_t (*qse_awk_math2_t) (
qse_flt_t y
);
typedef struct qse_awk_mod_info_t qse_awk_mod_info_t;
/* ------------------------------------------------------------------------ */
struct qse_awk_mod_info_t
typedef struct qse_awk_mod_spec_t qse_awk_mod_spec_t;
struct qse_awk_mod_spec_t
{
const qse_char_t* prefix;
const qse_char_t* postfix;
@ -425,7 +428,7 @@ struct qse_awk_mod_info_t
typedef void* (*qse_awk_modopen_t) (
qse_awk_t* awk,
const qse_awk_mod_info_t* info
const qse_awk_mod_spec_t* spec
);
typedef void* (*qse_awk_modsym_t) (
@ -439,6 +442,8 @@ typedef void (*qse_awk_modclose_t) (
void* handle
);
/* ------------------------------------------------------------------------ */
#if 0
typedef void* (*qse_awk_buildrex_t) (
qse_awk_t* awk,
@ -728,8 +733,7 @@ typedef struct qse_awk_rio_t qse_awk_rio_t;
/* ------------------------------------------------------------------------ */
typedef struct qse_awk_mod_t qse_awk_mod_t;
typedef struct qse_awk_mod_sym_t qse_awk_mod_sym_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;
/**
@ -740,12 +744,48 @@ typedef int (*qse_awk_fnc_impl_t) (
const qse_awk_fnc_info_t* fi /**< function information */
);
/**
* The qse_awk_fnc_spec_t type defines a structure to hold the specification
* of an intrinsic function or a module function.
*/
struct qse_awk_fnc_spec_t
{
/** parameter specification */
struct
{
int min; /**< min. numbers of argument for a function */
int max; /**< max. numbers of argument for a function */
const qse_char_t* spec;
} arg;
/** pointer to the function implementing this function */
qse_awk_fnc_impl_t impl;
/**
* when this field is set to a non-zero value bitwise-ORed of
* #qse_awk_trait_t enumerators, the function is available if
* this field bitwise-ANDed the global trait option produces
* this field itself.
*
* this field doesn't take effect for a module function.
*/
int trait;
};
/* ------------------------------------------------------------------------ */
typedef struct qse_awk_mod_t qse_awk_mod_t;
typedef struct qse_awk_mod_sym_t qse_awk_mod_sym_t;
struct qse_awk_fnc_info_t
{
qse_xstr_t name;
qse_awk_mod_t* mod;
/** #QSE_NULL if the function is not registered from module */
qse_awk_mod_t* mod;
};
typedef int (*qse_awk_mod_load_t) (
qse_awk_mod_t* mod,
qse_awk_t* awk
@ -794,20 +834,10 @@ enum qse_awk_mod_sym_type_t
*/
};
typedef enum qse_awk_mod_sym_type_t qse_awk_mod_sym_type_t;
typedef struct qse_awk_mod_sym_fnc_t qse_awk_mod_sym_fnc_t;
typedef qse_awk_fnc_spec_t qse_awk_mod_sym_fnc_t;
typedef struct qse_awk_mod_sym_int_t qse_awk_mod_sym_int_t;
typedef struct qse_awk_mod_sym_flt_t qse_awk_mod_sym_flt_t;
struct qse_awk_mod_sym_fnc_t
{
struct
{
int min; /* min. numbers of argument for a function */
int max; /* max. numbers of argument for a function */
} arg;
qse_awk_fnc_impl_t impl;
};
struct qse_awk_mod_sym_int_t
{
qse_long_t val;
@ -1057,6 +1087,7 @@ enum qse_awk_trait_t
QSE_AWK_CLASSIC | QSE_AWK_EXTRAKWS | QSE_AWK_MAPTOVAR |
QSE_AWK_RWPIPE | QSE_AWK_TOLERANT
};
typedef enum qse_awk_trait_t qse_awk_trait_t;
/* ------------------------------------------------------------------------ */
@ -1581,8 +1612,7 @@ QSE_EXPORT void qse_awk_pushecb (
*/
QSE_EXPORT int qse_awk_addgbl (
qse_awk_t* awk, /**< awk */
const qse_char_t* name, /**< variable name */
qse_size_t len /**< name length */
const qse_cstr_t* name /**< variable name */
);
/**
@ -1591,8 +1621,7 @@ QSE_EXPORT int qse_awk_addgbl (
*/
QSE_EXPORT int qse_awk_delgbl (
qse_awk_t* awk, /**< awk */
const qse_char_t* name, /**< variable name */
qse_size_t len /**< name length */
const qse_cstr_t* name /**< variable name */
);
/**
@ -1602,22 +1631,16 @@ QSE_EXPORT int qse_awk_delgbl (
*/
QSE_EXPORT int qse_awk_findgbl (
qse_awk_t* awk, /**< awk */
const qse_char_t* name, /**< variable name */
qse_size_t len /**< name length */
const qse_cstr_t* name /**< variable name */
);
/**
* The qse_awk_addfnc() function adds an intrinsic function.
*/
QSE_EXPORT void* qse_awk_addfnc (
qse_awk_t* awk,
const qse_char_t* name,
qse_size_t name_len,
int when_valid,
qse_size_t min_args,
qse_size_t max_args,
const qse_char_t* arg_spec,
qse_awk_fnc_impl_t handler
qse_awk_t* awk,
const qse_cstr_t* name,
const qse_awk_fnc_spec_t* spec
);
/**
@ -1626,8 +1649,7 @@ QSE_EXPORT void* qse_awk_addfnc (
*/
QSE_EXPORT int qse_awk_delfnc (
qse_awk_t* awk, /**< awk */
const qse_char_t* name, /**< function name */
qse_size_t len /**< name length */
const qse_cstr_t* name /**< function name */
);
/**

View File

@ -194,6 +194,9 @@
/* Define if libdlloader will be built on this platform */
#undef HAVE_LIBDLLOADER
/* Define to 1 if you have the `ltdl' library (-lltdl). */
#undef HAVE_LIBLTDL
/* Define to 1 if you have the `log' function. */
#undef HAVE_LOG

View File

@ -1493,7 +1493,10 @@ int Awk::addGlobal (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
int n = qse_awk_addgbl (awk, name, qse_strlen(name));
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_addgbl (awk, &nx);
if (n <= -1) retrieveError ();
return n;
}
@ -1501,7 +1504,10 @@ int Awk::addGlobal (const char_t* name)
int Awk::deleteGlobal (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
int n = qse_awk_delgbl (awk, name, qse_strlen(name));
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_delgbl (awk, &nx);
if (n <= -1) retrieveError ();
return n;
}
@ -1509,7 +1515,10 @@ int Awk::deleteGlobal (const char_t* name)
int Awk::findGlobal (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
int n = qse_awk_findgbl (awk, name, qse_strlen(name));
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_findgbl (awk, &nx);
if (n <= -1) retrieveError ();
return n;
}
@ -1547,27 +1556,31 @@ int Awk::addFunction (
QSE_ASSERT (awk != QSE_NULL);
FunctionHandler* tmp = (FunctionHandler*)
qse_awk_allocmem (awk, QSE_SIZEOF(handler));
qse_awk_callocmem (awk, QSE_SIZEOF(handler));
if (tmp == QSE_NULL)
{
setError (QSE_AWK_ENOMEM);
return -1;
}
//QSE_MEMCPY (tmp, &handler, QSE_SIZEOF(handler));
*tmp = handler;
size_t nameLen = qse_strlen(name);
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
void* p = qse_awk_addfnc (
awk, name, nameLen,
validOpts, minArgs, maxArgs,
fnc_spec_t spec;
QSE_MEMSET (&spec, 0, QSE_SIZEOF(spec));
spec.arg.min = minArgs;
spec.arg.max = maxArgs;
#ifdef PASS_BY_REFERENCE
QSE_T("R"), // pass all arguments by reference
#else
QSE_NULL,
spec.arg.spec = QSE_T("R"); // pass all arguments by reference
#endif
functionHandler);
spec.impl = functionHandler;
spec.trait = validOpts;
void* p = qse_awk_addfnc (awk, &nx, &spec);
if (p == QSE_NULL)
{
qse_awk_freemem (awk, tmp);
@ -1576,12 +1589,11 @@ int Awk::addFunction (
}
pair_t* pair = qse_htb_upsert (
functionMap, (char_t*)name, nameLen, tmp, 0);
functionMap, (char_t*)nx.ptr, nx.len, tmp, 0);
if (pair == QSE_NULL)
{
qse_awk_delfnc (awk, name, nameLen);
qse_awk_delfnc (awk, &nx);
qse_awk_freemem (awk, tmp);
setError (QSE_AWK_ENOMEM);
return -1;
}
@ -1593,10 +1605,12 @@ int Awk::deleteFunction (const char_t* name)
{
QSE_ASSERT (awk != QSE_NULL);
size_t nameLen = qse_strlen(name);
qse_cstr_t nx;
nx.ptr = name;
nx.len = qse_strlen(name);
int n = qse_awk_delfnc (awk, name, nameLen);
if (n == 0) qse_htb_delete (functionMap, name, nameLen);
int n = qse_awk_delfnc (awk, &nx);
if (n == 0) qse_htb_delete (functionMap, nx.ptr, nx.len);
else retrieveError ();
return n;
@ -2012,10 +2026,10 @@ Awk::flt_t Awk::sqrt (awk_t* awk, flt_t x)
return xtn->awk->sqrt (x);
}
void* Awk::modopen (awk_t* awk, const mod_info_t* info)
void* Awk::modopen (awk_t* awk, const mod_spec_t* spec)
{
xtn_t* xtn = (xtn_t*) QSE_XTN (awk);
return xtn->awk->modopen (info);
return xtn->awk->modopen (spec);
}
void Awk::modclose (awk_t* awk, void* handle)

View File

@ -1394,7 +1394,7 @@ StdAwk::flt_t StdAwk::sqrt (flt_t x)
#endif
}
void* StdAwk::modopen (const mod_info_t* info)
void* StdAwk::modopen (const mod_spec_t* spec)
{
#if defined(USE_LTDL)
@ -1404,9 +1404,9 @@ void* StdAwk::modopen (const mod_info_t* info)
int count;
count = 0;
if (info->prefix) tmp[count++] = info->prefix;
tmp[count++] = info->name;
if (info->postfix) tmp[count++] = info->postfix;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)
@ -1434,9 +1434,9 @@ void* StdAwk::modopen (const mod_info_t* info)
int count;
count = 0;
if (info->prefix) tmp[count++] = info->prefix;
tmp[count++] = info->name;
if (info->postfix) tmp[count++] = info->postfix;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
path = qse_stradup (tmp, QSE_NULL, this->getMmgr());
@ -1462,9 +1462,9 @@ void* StdAwk::modopen (const mod_info_t* info)
UCHAR errbuf[CCHMAXPATH];
count = 0;
if (info->prefix) tmp[count++] = info->prefix;
tmp[count++] = info->name;
if (info->postfix) tmp[count++] = info->postfix;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)

View File

@ -44,8 +44,7 @@ static int fnc_exp (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static int fnc_sqrt (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
#undef MAX
#define MAX QSE_TYPE_UNSIGNED_MAX(qse_size_t)
#define A_MAX QSE_TYPE_MAX(int)
/* Argument Specifier
*
@ -63,49 +62,43 @@ static int fnc_int (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi);
static qse_awk_fnc_t sys_fnc[] =
{
/* io functions */
{ {QSE_T("close"), 5}, 0, QSE_AWK_RIO, {1, 2, QSE_NULL}, fnc_close, QSE_NULL},
{ {QSE_T("fflush"), 6}, 0, QSE_AWK_RIO, {0, 1, QSE_NULL}, fnc_fflush, QSE_NULL},
{ {QSE_T("close"), 5}, 0, { {1, 2, QSE_NULL}, fnc_close, QSE_AWK_RIO }, QSE_NULL},
{ {QSE_T("fflush"), 6}, 0, { {0, 1, QSE_NULL}, fnc_fflush, QSE_AWK_RIO }, QSE_NULL},
/* string functions */
{ {QSE_T("index"), 5}, 0, 0, {2, 3, QSE_NULL}, fnc_index, QSE_NULL},
{ {QSE_T("substr"), 6}, 0, 0, {2, 3, QSE_NULL}, fnc_substr, QSE_NULL},
{ {QSE_T("length"), 6}, 1, 0, {0, 1, QSE_NULL}, fnc_length, QSE_NULL},
{ {QSE_T("split"), 5}, 0, 0, {2, 3, QSE_T("vrx")}, fnc_split, QSE_NULL},
{ {QSE_T("tolower"), 7}, 0, 0, {1, 1, QSE_NULL}, fnc_tolower, QSE_NULL},
{ {QSE_T("toupper"), 7}, 0, 0, {1, 1, QSE_NULL}, fnc_toupper, QSE_NULL},
{ {QSE_T("gsub"), 4}, 0, 0, {2, 3, QSE_T("xvr")}, fnc_gsub, QSE_NULL},
{ {QSE_T("sub"), 3}, 0, 0, {2, 3, QSE_T("xvr")}, fnc_sub, QSE_NULL},
{ {QSE_T("match"), 5}, 0, 0, {2, 3, QSE_T("vxv")}, fnc_match, QSE_NULL},
{ {QSE_T("sprintf"), 7}, 0, 0, {1, MAX, QSE_NULL}, fnc_sprintf, QSE_NULL},
{ {QSE_T("index"), 5}, 0, { {2, 3, QSE_NULL}, fnc_index, 0 }, QSE_NULL},
{ {QSE_T("substr"), 6}, 0, { {2, 3, QSE_NULL}, fnc_substr, 0 }, QSE_NULL},
{ {QSE_T("length"), 6}, 1, { {0, 1, QSE_NULL}, fnc_length, 0 }, QSE_NULL},
{ {QSE_T("split"), 5}, 0, { {2, 3, QSE_T("vrx")}, fnc_split, 0 }, QSE_NULL},
{ {QSE_T("tolower"), 7}, 0, { {1, 1, QSE_NULL}, fnc_tolower, 0 }, QSE_NULL},
{ {QSE_T("toupper"), 7}, 0, { {1, 1, QSE_NULL}, fnc_toupper, 0 }, QSE_NULL},
{ {QSE_T("gsub"), 4}, 0, { {2, 3, QSE_T("xvr")}, fnc_gsub, 0 }, QSE_NULL},
{ {QSE_T("sub"), 3}, 0, { {2, 3, QSE_T("xvr")}, fnc_sub, 0 }, QSE_NULL},
{ {QSE_T("match"), 5}, 0, { {2, 3, QSE_T("vxv")}, fnc_match, 0 }, QSE_NULL},
{ {QSE_T("sprintf"), 7}, 0, { {1, A_MAX, QSE_NULL}, fnc_sprintf, 0 }, QSE_NULL},
/* math functions */
{ {QSE_T("sin"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_sin, QSE_NULL},
{ {QSE_T("cos"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_cos, QSE_NULL},
{ {QSE_T("tan"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_tan, QSE_NULL},
{ {QSE_T("atan"), 4}, 0, 0, {1, 1, QSE_NULL}, fnc_atan, QSE_NULL},
{ {QSE_T("atan2"), 5}, 0, 0, {2, 2, QSE_NULL}, fnc_atan2, QSE_NULL},
{ {QSE_T("log"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_log, QSE_NULL},
{ {QSE_T("log10"), 5}, 0, 0, {1, 1, QSE_NULL}, fnc_log10, QSE_NULL},
{ {QSE_T("exp"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_exp, QSE_NULL},
{ {QSE_T("sqrt"), 4}, 0, 0, {1, 1, QSE_NULL}, fnc_sqrt, QSE_NULL},
{ {QSE_T("int"), 3}, 0, 0, {1, 1, QSE_NULL}, fnc_int, QSE_NULL},
{ {QSE_T("sin"), 3}, 0, { {1, 1, QSE_NULL}, fnc_sin, 0 }, QSE_NULL},
{ {QSE_T("cos"), 3}, 0, { {1, 1, QSE_NULL}, fnc_cos, 0 }, QSE_NULL},
{ {QSE_T("tan"), 3}, 0, { {1, 1, QSE_NULL}, fnc_tan, 0 }, QSE_NULL},
{ {QSE_T("atan"), 4}, 0, { {1, 1, QSE_NULL}, fnc_atan, 0 }, QSE_NULL},
{ {QSE_T("atan2"), 5}, 0, { {2, 2, QSE_NULL}, fnc_atan2, 0 }, QSE_NULL},
{ {QSE_T("log"), 3}, 0, { {1, 1, QSE_NULL}, fnc_log, 0 }, QSE_NULL},
{ {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, 0, QSE_NULL}, QSE_NULL, QSE_NULL}
{ {QSE_NULL, 0}, 0, { {0, 0, QSE_NULL}, QSE_NULL, 0 }, QSE_NULL}
};
void* qse_awk_addfnc (
qse_awk_t* awk,
const qse_char_t* name, qse_size_t name_len,
int when_valid,
qse_size_t min_args, qse_size_t max_args,
const qse_char_t* arg_spec,
qse_awk_fnc_impl_t handler)
void* qse_awk_addfnc (qse_awk_t* awk, const qse_cstr_t* name, const qse_awk_fnc_spec_t* spec)
{
qse_awk_fnc_t* fnc;
qse_size_t fnc_size;
qse_size_t spec_len;
if (name_len <= 0)
if (name->len <= 0)
{
qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL);
return QSE_NULL;
@ -115,69 +108,59 @@ void* qse_awk_addfnc (
* such a function registered won't take effect because
* the word is treated as a keyword */
if (qse_awk_getfnc (awk, name, name_len) != QSE_NULL)
if (qse_awk_getfnc (awk, name) != QSE_NULL)
{
qse_cstr_t errarg;
errarg.ptr = name;
errarg.len = name_len;
errarg.ptr = name->ptr;
errarg.len = name->len;
qse_awk_seterrnum (awk, QSE_AWK_EEXIST, &errarg);
return QSE_NULL;
}
spec_len = (arg_spec == QSE_NULL)? 0: qse_strlen(arg_spec);
spec_len = 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) +
(name->len+1) * QSE_SIZEOF(qse_char_t) +
(spec_len+1) * QSE_SIZEOF(qse_char_t);
fnc = (qse_awk_fnc_t*) QSE_AWK_ALLOC (awk, fnc_size);
if (fnc == QSE_NULL)
fnc = (qse_awk_fnc_t*) qse_awk_callocmem (awk, fnc_size);
if (fnc)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return QSE_NULL;
}
qse_char_t* tmp;
QSE_MEMSET (fnc, 0, fnc_size);
tmp = (qse_char_t*)(fnc + 1);
fnc->name.len = qse_strxncpy (tmp, name->len+1, name, name->len);
fnc->name.ptr = tmp;
fnc->name.ptr = (qse_char_t*)(fnc + 1);
fnc->name.len = name_len;
qse_strxncpy (fnc->name.ptr, name_len+1, name, name_len);
fnc->spec = *spec;
if (spec->arg.spec)
{
tmp = fnc->name.ptr + fnc->name.len + 1;
qse_strxcpy (tmp, spec_len + 1, spec->arg.spec);
fnc->spec.arg.spec = tmp;
}
fnc->valid = when_valid;
fnc->arg.min = min_args;
fnc->arg.max = max_args;
if (arg_spec == QSE_NULL) fnc->arg.spec = QSE_NULL;
else
{
fnc->arg.spec = fnc->name.ptr + fnc->name.len + 1;
qse_strxcpy (fnc->arg.spec, spec_len+1, arg_spec);
}
fnc->handler = handler;
if (qse_htb_insert (awk->fnc.user,
(qse_char_t*)name, name_len, fnc, 0) == QSE_NULL)
{
QSE_AWK_FREE (awk, fnc);
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return QSE_NULL;
if (qse_htb_insert (awk->fnc.user,
(qse_char_t*)name->ptr, name->len, fnc, 0) == QSE_NULL)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
QSE_AWK_FREE (awk, fnc); fnc = QSE_NULL;
}
}
return fnc;
}
int qse_awk_delfnc (
qse_awk_t* awk, const qse_char_t* name, qse_size_t name_len)
int qse_awk_delfnc (qse_awk_t* awk, const qse_cstr_t* name)
{
if (qse_htb_delete (awk->fnc.user, name, name_len) <= -1)
if (qse_htb_delete (awk->fnc.user, name->ptr, name->len) <= -1)
{
qse_cstr_t errarg;
errarg.ptr = name;
errarg.len = name_len;
errarg.ptr = name->ptr;
errarg.len = name->len;
qse_awk_seterrnum (awk, QSE_AWK_ENOENT, &errarg);
return -1;
@ -191,8 +174,7 @@ 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_char_t* name, qse_size_t len)
qse_awk_fnc_t* qse_awk_getfnc (qse_awk_t* awk, const qse_cstr_t* name)
{
qse_awk_fnc_t* fnc;
qse_htb_pair_t* pair;
@ -202,22 +184,22 @@ qse_awk_fnc_t* qse_awk_getfnc (
* 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++)
{
if (fnc->valid != 0 &&
(awk->opt.trait & fnc->valid) != fnc->valid) continue;
if (fnc->spec.trait != 0 &&
(awk->opt.trait & fnc->spec.trait) != fnc->spec.trait) continue;
if (qse_strxncmp (
fnc->name.ptr, fnc->name.len,
name, len) == 0) return fnc;
name->ptr, name->len) == 0) return fnc;
}
pair = qse_htb_search (awk->fnc.user, name, len);
pair = qse_htb_search (awk->fnc.user, name->ptr, name->len);
if (pair == QSE_NULL) return QSE_NULL;
fnc = (qse_awk_fnc_t*)QSE_HTB_VPTR(pair);
if (fnc->valid != 0 && (awk->opt.trait & fnc->valid) == 0) return QSE_NULL;
if (fnc->spec.trait != 0 && (awk->opt.trait & fnc->spec.trait) == 0) return QSE_NULL;
return fnc;
}

View File

@ -32,27 +32,16 @@ struct qse_awk_fnc_t
int dfl0; /* if set, ($0) is assumed if () is missing.
* this ia mainly for the weird length() function */
int valid; /* the entry is valid when this option is set */
struct
{
qse_size_t min;
qse_size_t max;
qse_char_t* spec;
} arg;
qse_awk_fnc_impl_t handler;
qse_awk_fnc_spec_t spec;
qse_awk_mod_t* mod; /* if it's associated to a module */
/*qse_awk_fnc_t* next;*/
};
#ifdef __cplusplus
extern "C" {
#endif
qse_awk_fnc_t* qse_awk_getfnc (
qse_awk_t* awk, const qse_char_t* name, qse_size_t len);
qse_awk_fnc_t* qse_awk_getfnc (qse_awk_t* awk, const qse_cstr_t* name);
#ifdef __cplusplus
}

View File

@ -158,8 +158,7 @@ struct binmap_t
static int parse_progunit (qse_awk_t* awk);
static qse_awk_t* collect_globals (qse_awk_t* awk);
static void adjust_static_globals (qse_awk_t* awk);
static qse_size_t find_global (
qse_awk_t* awk, const qse_char_t* name, qse_size_t len);
static qse_size_t find_global (qse_awk_t* awk, const qse_cstr_t* name);
static qse_awk_t* collect_locals (
qse_awk_t* awk, qse_size_t nlcls, int istop);
@ -230,8 +229,7 @@ static int get_rexstr (qse_awk_t* awk, qse_awk_tok_t* tok);
static int skip_spaces (qse_awk_t* awk);
static int skip_comment (qse_awk_t* awk);
static int classify_ident (
qse_awk_t* awk, const qse_char_t* name, qse_size_t len);
static int classify_ident (qse_awk_t* awk, const qse_cstr_t* name);
static int deparse (qse_awk_t* awk);
static qse_htb_walk_t deparse_func (
@ -249,7 +247,7 @@ struct kwent_t
{
qse_cstr_t name;
int type;
int valid; /* the entry is valid when this option is set */
int trait; /* the entry is valid when this option is set */
};
static kwent_t kwtab[] =
@ -288,7 +286,7 @@ struct global_t
{
const qse_char_t* name;
qse_size_t namelen;
int valid;
int trait;
};
static global_t gtab[] =
@ -1083,13 +1081,13 @@ 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.ptr, name.len) != QSE_NULL && (rederr = QSE_AWK_EFNCRED)) ||
if ((qse_awk_getfnc (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 */
(qse_htb_search (awk->parse.named, name.ptr, name.len) != QSE_NULL && (rederr = QSE_AWK_EVARRED)) ||
/* check if it coincides to be a global variable name */
(((g = find_global (awk, name.ptr, name.len)) != QSE_LDA_NIL) && (rederr = QSE_AWK_EGBLRED)))
(((g = find_global (awk, &name)) != QSE_LDA_NIL) && (rederr = QSE_AWK_EGBLRED)))
{
SETERR_ARG_LOC (awk, rederr, name.ptr, name.len, &awk->tok.loc);
return QSE_NULL;
@ -1640,8 +1638,7 @@ static void adjust_static_globals (qse_awk_t* awk)
for (id = QSE_AWK_MIN_GBL_ID; id <= QSE_AWK_MAX_GBL_ID; id++)
{
if (gtab[id].valid != 0 &&
(awk->opt.trait & gtab[id].valid) != gtab[id].valid)
if ((awk->opt.trait & gtab[id].trait) != gtab[id].trait)
{
QSE_LDA_DLEN(awk->parse.gbls,id) = 0;
}
@ -1669,8 +1666,7 @@ static qse_size_t get_global (qse_awk_t* awk, const qse_xstr_t* name)
return QSE_LDA_NIL;
}
static qse_size_t find_global (
qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
static qse_size_t find_global (qse_awk_t* awk, const qse_cstr_t* name)
{
qse_size_t i;
qse_lda_t* gbls = awk->parse.gbls;
@ -1679,51 +1675,51 @@ static qse_size_t find_global (
{
if (qse_strxncmp (
QSE_LDA_DPTR(gbls,i), QSE_LDA_DLEN(gbls,i),
name, len) == 0) return i;
name->ptr, name->len) == 0) return i;
}
return QSE_LDA_NIL;
}
static int add_global (
qse_awk_t* awk, const qse_char_t* name, qse_size_t len,
qse_awk_t* awk, const qse_cstr_t* name,
qse_awk_loc_t* xloc, int disabled)
{
qse_size_t ngbls;
/* check if it is a keyword */
if (classify_ident (awk, name, len) != TOK_IDENT)
if (classify_ident (awk, name) != TOK_IDENT)
{
SETERR_ARG_LOC (awk, QSE_AWK_EKWRED, name, len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EKWRED, name->ptr, name->len, xloc);
return -1;
}
/* check if it conflicts with a builtin function name */
if (qse_awk_getfnc (awk, name, len) != QSE_NULL)
if (qse_awk_getfnc (awk, name) != QSE_NULL)
{
SETERR_ARG_LOC (awk, QSE_AWK_EFNCRED, name, len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EFNCRED, name->ptr, name->len, xloc);
return -1;
}
/* check if it conflicts with a function name */
if (qse_htb_search (awk->tree.funs, name, len) != QSE_NULL)
if (qse_htb_search (awk->tree.funs, name->ptr, name->len) != QSE_NULL)
{
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name, len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
return -1;
}
/* check if it conflicts with a function name
* caught in the function call table */
if (qse_htb_search (awk->parse.funs, name, len) != QSE_NULL)
if (qse_htb_search (awk->parse.funs, name->ptr, name->len) != QSE_NULL)
{
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name, len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EFUNRED, name->ptr, name->len, xloc);
return -1;
}
/* check if it conflicts with other global variable names */
if (find_global (awk, name, len) != QSE_LDA_NIL)
if (find_global (awk, name) != QSE_LDA_NIL)
{
SETERR_ARG_LOC (awk, QSE_AWK_EDUPGBL, name, len, xloc);
SETERR_ARG_LOC (awk, QSE_AWK_EDUPGBL, name->ptr, name->len, xloc);
return -1;
}
@ -1750,7 +1746,7 @@ static int add_global (
if (qse_lda_insert (awk->parse.gbls,
QSE_LDA_SIZE(awk->parse.gbls),
(qse_char_t*)name, len) == QSE_LDA_NIL)
(qse_char_t*)name->ptr, name->len) == QSE_LDA_NIL)
{
SETERR_LOC (awk, QSE_AWK_ENOMEM, xloc);
return -1;
@ -1769,11 +1765,11 @@ static int add_global (
return (int)ngbls;
}
int qse_awk_addgbl (qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
int qse_awk_addgbl (qse_awk_t* awk, const qse_cstr_t* name)
{
int n;
if (len <= 0)
if (name->len <= 0)
{
SETERR_COD (awk, QSE_AWK_EINVAL);
return -1;
@ -1786,7 +1782,7 @@ int qse_awk_addgbl (qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
return -1;
}
n = add_global (awk, name, len, QSE_NULL, 0);
n = add_global (awk, name, QSE_NULL, 0);
/* update the count of the static globals.
* the total global count has been updated inside add_global. */
@ -1798,8 +1794,7 @@ int qse_awk_addgbl (qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
#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_char_t* name, qse_size_t len)
int qse_awk_delgbl (qse_awk_t* awk, const qse_cstr_t* name)
{
qse_size_t n;
@ -1811,10 +1806,10 @@ int qse_awk_delgbl (
}
n = qse_lda_search (awk->parse.gbls,
QSE_AWK_NUM_STATIC_GBLS, name, len);
QSE_AWK_NUM_STATIC_GBLS, name->ptr, name->len);
if (n == QSE_LDA_NIL)
{
SETERR_ARG (awk, QSE_AWK_ENOENT, name, len);
SETERR_ARG (awk, QSE_AWK_ENOENT, name->ptr, name->len);
return -1;
}
@ -1833,16 +1828,15 @@ int qse_awk_delgbl (
return 0;
}
int qse_awk_findgbl (
qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
int qse_awk_findgbl (qse_awk_t* awk, const qse_cstr_t* name)
{
qse_size_t n;
n = qse_lda_search (awk->parse.gbls,
QSE_AWK_NUM_STATIC_GBLS, name, len);
QSE_AWK_NUM_STATIC_GBLS, name->ptr, name->len);
if (n == QSE_LDA_NIL)
{
SETERR_ARG (awk, QSE_AWK_ENOENT, name, len);
SETERR_ARG (awk, QSE_AWK_ENOENT, name->ptr, name->len);
return -1;
}
@ -1868,9 +1862,7 @@ static qse_awk_t* collect_globals (qse_awk_t* awk)
}
if (add_global (
awk,
QSE_STR_PTR(awk->tok.name),
QSE_STR_LEN(awk->tok.name),
awk, QSE_STR_CSTR(awk->tok.name),
&awk->tok.loc, 0) <= -1) return QSE_NULL;
if (get_token(awk) <= -1) return QSE_NULL;
@ -1931,7 +1923,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.ptr, lcl.len) != QSE_NULL)
if (qse_awk_getfnc (awk, &lcl) != QSE_NULL)
{
SETERR_ARG_LOC (
awk, QSE_AWK_EFNCRED,
@ -1974,10 +1966,7 @@ static qse_awk_t* collect_locals (
}
/* check if it conflicts with other local variable names */
n = qse_lda_search (
awk->parse.lcls,
nlcls,
lcl.ptr, lcl.len);
n = qse_lda_search (awk->parse.lcls, nlcls, lcl.ptr, lcl.len);
if (n != QSE_LDA_NIL)
{
SETERR_ARG_LOC (
@ -1987,7 +1976,7 @@ static qse_awk_t* collect_locals (
}
/* check if it conflicts with global variable names */
n = find_global (awk, lcl.ptr, lcl.len);
n = find_global (awk, &lcl);
if (n != QSE_LDA_NIL)
{
if (n < awk->tree.ngbls_base)
@ -4139,7 +4128,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->ptr, name->len) != QSE_NULL)
if (qse_awk_getfnc (awk, name) != QSE_NULL)
{
/* implicit function */
return FNTYPE_FNC;
@ -4775,7 +4764,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->ptr, name->len);
fnc = qse_awk_getfnc (awk, name);
if (fnc)
{
if (MATCH(awk,TOK_LPAREN))
@ -4952,14 +4941,18 @@ static qse_awk_nde_t* parse_primary_ident_segs (
switch (sym.type)
{
case QSE_AWK_MOD_FNC:
if ((awk->opt.trait & sym.u.fnc.trait) != sym.u.fnc.trait)
{
SETERR_ARG_LOC (awk, QSE_AWK_EUNDEF, full->ptr, full->len, xloc);
break;
}
if (MATCH(awk,TOK_LPAREN))
{
QSE_MEMSET (&fnc, 0, QSE_SIZEOF(fnc));
fnc.name.ptr = full->ptr;
fnc.name.len = full->len;
fnc.arg.min = sym.u.fnc.arg.min;
fnc.arg.max = sym.u.fnc.arg.max;
fnc.handler = sym.u.fnc.impl;
fnc.spec = sym.u.fnc;
fnc.mod = mod;
nde = parse_fncall (awk, full, &fnc, xloc, 0);
@ -5267,23 +5260,19 @@ make_node:
call->u.fnc.info.name.ptr = name->ptr;
call->u.fnc.info.name.len = name->len;
call->u.fnc.info.mod = fnc->mod;
call->u.fnc.arg.min = fnc->arg.min;
call->u.fnc.arg.max = fnc->arg.max;
call->u.fnc.arg.spec = fnc->arg.spec;
call->u.fnc.handler = fnc->handler;
call->u.fnc.spec = fnc->spec;
call->args = head;
call->nargs = nargs;
if (nargs > call->u.fnc.arg.max)
if (nargs > call->u.fnc.spec.arg.max)
{
SETERR_LOC (awk, QSE_AWK_EARGTM, xloc);
SETERR_LOC (awk, QSE_AWK_EARGTM, xloc);
goto oops;
}
else if (nargs < call->u.fnc.arg.min)
else if (nargs < call->u.fnc.spec.arg.min)
{
SETERR_LOC (awk, QSE_AWK_EARGTF, xloc);
SETERR_LOC (awk, QSE_AWK_EARGTF, xloc);
goto oops;
}
}
@ -5933,9 +5922,7 @@ retry:
QSE_AWK_ISALPHA (awk, c) ||
QSE_AWK_ISDIGIT (awk, c));
type = classify_ident (awk,
QSE_STR_PTR(tok->name),
QSE_STR_LEN(tok->name));
type = classify_ident (awk, QSE_STR_CSTR(tok->name));
SET_TOKEN_TYPE (awk, tok, type);
}
else if (c == QSE_T('\"'))
@ -6014,8 +6001,7 @@ static int preget_token (qse_awk_t* awk)
return get_token_into (awk, &awk->ntok);
}
static int classify_ident (
qse_awk_t* awk, const qse_char_t* name, qse_size_t len)
static int classify_ident (qse_awk_t* awk, const qse_cstr_t* name)
{
/* perform binary search */
@ -6031,7 +6017,7 @@ static int classify_ident (
mid = (left + right) / 2;
kwp = &kwtab[mid];
n = qse_strxncmp (kwp->name.ptr, kwp->name.len, name, len);
n = qse_strxncmp (kwp->name.ptr, kwp->name.len, name->ptr, name->len);
if (n > 0)
{
/* if left, right, mid were of qse_size_t,
@ -6043,10 +6029,7 @@ static int classify_ident (
else if (n < 0) left = mid + 1;
else
{
if (kwp->valid != 0 &&
(awk->opt.trait & kwp->valid) != kwp->valid)
break;
if ((awk->opt.trait & kwp->trait) != kwp->trait) break;
return kwp->type;
}
}
@ -6447,28 +6430,28 @@ static qse_awk_mod_t* query_module (
else
{
qse_awk_mod_load_t load;
qse_awk_mod_info_t info;
qse_awk_mod_spec_t spec;
qse_awk_mod_data_t md;
QSE_MEMSET (&info, 0, QSE_SIZEOF(info));
QSE_MEMSET (&spec, 0, QSE_SIZEOF(spec));
if (awk->opt.mod[0].len > 0)
info.prefix = awk->opt.mod[0].ptr;
spec.prefix = awk->opt.mod[0].ptr;
#if defined(DEFAULT_MODPREFIX)
else info.prefix = QSE_T(DEFAULT_MODPREFIX);
else spec.prefix = QSE_T(DEFAULT_MODPREFIX);
#endif
if (awk->opt.mod[1].len > 0)
info.postfix = awk->opt.mod[1].ptr;
spec.postfix = awk->opt.mod[1].ptr;
#if defined(DEFAULT_MODPOSTFIX)
else info.postfix = QSE_T(DEFAULT_MODPOSTFIX);
else spec.postfix = QSE_T(DEFAULT_MODPOSTFIX);
#endif
QSE_MEMSET (&md, 0, QSE_SIZEOF(md));
if (awk->prm.modopen && awk->prm.modsym && awk->prm.modclose)
{
info.name = segs[0].ptr;
md.handle = awk->prm.modopen (awk, &info);
spec.name = segs[0].ptr;
md.handle = awk->prm.modopen (awk, &spec);
}
else md.handle = QSE_NULL;

View File

@ -39,7 +39,6 @@ enum qse_awk_kwid_t
QSE_AWK_KWID_GLOBAL,
QSE_AWK_KWID_IF,
QSE_AWK_KWID_IN,
QSE_AWK_KWID_INCLUDE,
QSE_AWK_KWID_LOCAL,
QSE_AWK_KWID_NEXT,
QSE_AWK_KWID_NEXTFILE,

View File

@ -5518,24 +5518,12 @@ static qse_awk_val_t* eval_fnc (qse_awk_rtx_t* run, qse_awk_nde_t* nde)
/* the parser must make sure taht the number of arguments
* is proper */
QSE_ASSERT (call->nargs >= call->u.fnc.arg.min &&
call->nargs <= call->u.fnc.arg.max);
QSE_ASSERT (call->nargs >= call->u.fnc.spec.arg.min &&
call->nargs <= call->u.fnc.spec.arg.max);
#if 0
if (call->nargs < call->u.fnc.arg.min)
{
SETERR_LOC (run, QSE_AWK_EARGTF, &nde->loc);
return QSE_NULL;
}
if (call->nargs > call->u.fnc.arg.max)
{
SETERR_LOC (run, QSE_AWK_EARGTM, &nde->loc);
return QSE_NULL;
}
#endif
return eval_call (run, nde, call->u.fnc.arg.spec, QSE_NULL, QSE_NULL, QSE_NULL);
return eval_call (
run, nde, call->u.fnc.spec.arg.spec,
QSE_NULL, QSE_NULL, QSE_NULL);
}
static qse_awk_val_t* eval_fun_ex (
@ -5746,14 +5734,14 @@ static qse_awk_val_t* __eval_call (
/* intrinsic function */
QSE_ASSERT (
call->nargs >= call->u.fnc.arg.min &&
call->nargs <= call->u.fnc.arg.max);
call->nargs >= call->u.fnc.spec.arg.min &&
call->nargs <= call->u.fnc.spec.arg.max);
if (call->u.fnc.handler != QSE_NULL)
if (call->u.fnc.spec.impl)
{
run->errinf.num = QSE_AWK_ENOERR;
n = call->u.fnc.handler (run, &call->u.fnc.info);
n = call->u.fnc.spec.impl (run, &call->u.fnc.info);
if (n <= -1)
{

View File

@ -315,7 +315,7 @@ static int custom_awk_sprintf (
return n;
}
static void* custom_awk_modopen (qse_awk_t* awk, const qse_awk_mod_info_t* info)
static void* custom_awk_modopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec)
{
#if defined(USE_LTDL)
void* h;
@ -324,9 +324,9 @@ static void* custom_awk_modopen (qse_awk_t* awk, const qse_awk_mod_info_t* info)
int count;
count = 0;
if (info->prefix) tmp[count++] = info->prefix;
tmp[count++] = info->name;
if (info->postfix) tmp[count++] = info->postfix;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)
@ -354,9 +354,9 @@ static void* custom_awk_modopen (qse_awk_t* awk, const qse_awk_mod_info_t* info)
int count;
count = 0;
if (info->prefix) tmp[count++] = info->prefix;
tmp[count++] = info->name;
if (info->postfix) tmp[count++] = info->postfix;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
path = qse_stradup (tmp, QSE_NULL, awk->mmgr);
@ -382,9 +382,9 @@ static void* custom_awk_modopen (qse_awk_t* awk, const qse_awk_mod_info_t* info)
UCHAR errbuf[CCHMAXPATH];
count = 0;
if (info->prefix) tmp[count++] = info->prefix;
tmp[count++] = info->name;
if (info->postfix) tmp[count++] = info->postfix;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)
@ -2584,16 +2584,24 @@ 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 = qse_awk_addgbl (awk, QSE_T("ARGC"), 4);
xtn->gbl_argv = qse_awk_addgbl (awk, QSE_T("ARGV"), 4);
xtn->gbl_environ = qse_awk_addgbl (awk, QSE_T("ENVIRON"), 7);
xtn->gbl_procinfo = qse_awk_addgbl (awk, QSE_T("PROCINFO"), 8);
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_procinfo = add_global (awk, QSE_T("PROCINFO"), 8);
if (xtn->gbl_argc <= -1 || xtn->gbl_argv <= -1 ||
xtn->gbl_environ <= -1 || xtn->gbl_procinfo <= -1) return -1;
@ -2601,14 +2609,32 @@ static int add_globals (qse_awk_t* awk)
return 0;
}
struct fnctab_t
{
qse_cstr_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("time"), 4}, { {0, 0, QSE_NULL}, fnc_time, 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 } }
};
static int add_functions (qse_awk_t* awk)
{
if (qse_awk_addfnc (awk, QSE_T("rand"), 4, 0, 0, 0, QSE_NULL, fnc_rand) == QSE_NULL ||
qse_awk_addfnc (awk, QSE_T("srand"), 5, 0, 0, 1, QSE_NULL, fnc_srand) == QSE_NULL ||
qse_awk_addfnc (awk, QSE_T("system"), 6, 0, 1, 1, QSE_NULL, fnc_system) == QSE_NULL ||
qse_awk_addfnc (awk, QSE_T("time"), 4, 0, 0, 0, QSE_NULL, fnc_time) == QSE_NULL ||
qse_awk_addfnc (awk, QSE_T("setioattr"), 9, QSE_AWK_RIO, 3, 3, QSE_NULL, fnc_setioattr) == QSE_NULL ||
qse_awk_addfnc (awk, QSE_T("getioattr"), 9, QSE_AWK_RIO, 2, 2, QSE_NULL, fnc_getioattr) == QSE_NULL) return -1;
int i;
for (i = 0; i < QSE_COUNTOF(fnctab); i++)
{
if (qse_awk_addfnc (awk, &fnctab[i].name, &fnctab[i].spec) == QSE_NULL) return -1;
}
return 0;
}

View File

@ -189,15 +189,7 @@ struct qse_awk_nde_fncall_t
struct
{
qse_awk_fnc_info_t info;
struct
{
qse_size_t min;
qse_size_t max;
const qse_char_t* spec;
} arg;
qse_awk_fnc_impl_t handler;
qse_awk_fnc_spec_t spec;
} fnc;
} u;
qse_awk_nde_t* args;

View File

@ -153,12 +153,12 @@ struct inttab_t
static fnctab_t fnctab[] =
{
{ QSE_T("assign"), { { 1, 1 }, fnc_assign } },
{ QSE_T("barrier"), { { 0, 0 }, fnc_barrier } },
{ QSE_T("hash"), { { 1, 1 }, fnc_hash } },
{ QSE_T("rank"), { { 0, 0 }, fnc_rank } },
{ QSE_T("reduce"), { { 2, 2 }, fnc_reduce } },
{ QSE_T("size"), { { 0, 0 }, fnc_size } }
{ QSE_T("assign"), { { 1, 1, QSE_NULL }, fnc_assign }, 0 },
{ QSE_T("barrier"), { { 0, 0, QSE_NULL }, fnc_barrier }, 0 },
{ QSE_T("hash"), { { 1, 1, QSE_NULL }, fnc_hash }, 0 },
{ QSE_T("rank"), { { 0, 0, QSE_NULL }, fnc_rank }, 0 },
{ QSE_T("reduce"), { { 2, 2, QSE_NULL }, fnc_reduce }, 0 },
{ QSE_T("size"), { { 0, 0, QSE_NULL }, fnc_size }, 0 }
};
static inttab_t inttab[] =

View File

@ -108,6 +108,35 @@ static int fnc_wait (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
return 0;
}
static int fnc_getpgrp (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
qse_long_t pid;
qse_awk_val_t* retv;
#if defined(_WIN32)
/* TOOD: implement this*/
pid = -1;
#elif defined(__OS2__)
/* TOOD: implement this*/
pid = -1;
#elif defined(__DOS__)
/* TOOD: implement this*/
pid = -1;
#else
pid = getpgrp ();
#endif
retv = qse_awk_rtx_makeintval (rtx, pid);
if (retv == QSE_NULL) return -1;
qse_awk_rtx_setretval (rtx, retv);
return 0;
}
static int fnc_getppid (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
{
qse_long_t pid;
@ -272,14 +301,15 @@ struct inttab_t
static fnctab_t fnctab[] =
{
{ QSE_T("fork"), { { 0, 0 }, fnc_fork } },
{ QSE_T("getgid"), { { 0, 0 }, fnc_getgid } },
{ QSE_T("getpid"), { { 0, 0 }, fnc_getpid } },
{ QSE_T("getppid"), { { 0, 0 }, fnc_getppid } },
{ QSE_T("getuid"), { { 0, 0 }, fnc_getuid } },
{ QSE_T("kill"), { { 2, 2 }, fnc_kill } },
{ QSE_T("sleep"), { { 1, 1 }, fnc_sleep } },
{ QSE_T("wait"), { { 1, 1 }, fnc_wait } }
{ QSE_T("fork"), { { 0, 0, QSE_NULL }, fnc_fork, 0 } },
{ QSE_T("getgid"), { { 0, 0, QSE_NULL }, fnc_getgid, 0 } },
{ QSE_T("getpgrp"), { { 0, 0, QSE_NULL }, fnc_getpgrp, 0 } },
{ QSE_T("getpid"), { { 0, 0, QSE_NULL }, fnc_getpid, QSE_AWK_RIO } },
{ QSE_T("getppid"), { { 0, 0, QSE_NULL }, fnc_getppid, 0 } },
{ QSE_T("getuid"), { { 0, 0, QSE_NULL }, fnc_getuid, 0 } },
{ QSE_T("kill"), { { 2, 2, QSE_NULL }, fnc_kill, 0 } },
{ QSE_T("sleep"), { { 1, 1, QSE_NULL }, fnc_sleep, 0 } },
{ QSE_T("wait"), { { 1, 1, QSE_NULL }, fnc_wait, 0 } }
};
#if !defined(SIGHUP)

View File

@ -1208,24 +1208,24 @@ struct fnctab_t
static fnctab_t fnctab[] =
{
{ QSE_T("addlist"), { { 2, 2 }, fnc_uci_addlist } },
{ QSE_T("addsection"), { { 3, 3 }, fnc_uci_addsection } },
{ QSE_T("close"), { { 1, 1 }, fnc_uci_close } },
{ QSE_T("commit"), { { 2, 2 }, fnc_uci_commit } },
{ QSE_T("delete"), { { 2, 2 }, fnc_uci_delete } },
{ QSE_T("errno"), { { 0, 0 }, fnc_uci_errno } },
{ QSE_T("errstr"), { { 0, 1 }, fnc_uci_errstr } },
{ QSE_T("getoption"), { { 2, 2 }, fnc_uci_getoption } },
{ QSE_T("getsection"), { { 2, 2 }, fnc_uci_getsection } },
{ QSE_T("load"), { { 2, 2 }, fnc_uci_load } },
{ QSE_T("open"), { { 0, 0 }, fnc_uci_open } },
{ QSE_T("rename"), { { 2, 2 }, fnc_uci_rename } },
{ QSE_T("revert"), { { 2, 2 }, fnc_uci_revert } },
{ QSE_T("save"), { { 2, 2 }, fnc_uci_save } },
{ QSE_T("set"), { { 2, 2 }, fnc_uci_set } },
{ QSE_T("setconfdir"), { { 2, 2 }, fnc_uci_setconfdir } },
{ QSE_T("setsavedir"), { { 2, 2 }, fnc_uci_setsavedir } },
{ QSE_T("unload"), { { 1, 1 }, fnc_uci_unload } }
{ QSE_T("addlist"), { { 2, 2, QSE_NULL }, fnc_uci_addlist, 0 } },
{ QSE_T("addsection"), { { 3, 3, QSE_NULL }, fnc_uci_addsection, 0 } },
{ QSE_T("close"), { { 1, 1, QSE_NULL }, fnc_uci_close, 0 } },
{ QSE_T("commit"), { { 2, 2, QSE_NULL }, fnc_uci_commit, 0 } },
{ QSE_T("delete"), { { 2, 2, QSE_NULL }, fnc_uci_delete, 0 } },
{ QSE_T("errno"), { { 0, 0, QSE_NULL }, fnc_uci_errno, 0 } },
{ QSE_T("errstr"), { { 0, 1, QSE_NULL }, fnc_uci_errstr, 0 } },
{ QSE_T("getoption"), { { 2, 2, QSE_NULL }, fnc_uci_getoption, 0 } },
{ QSE_T("getsection"), { { 2, 2, QSE_NULL }, fnc_uci_getsection, 0 } },
{ QSE_T("load"), { { 2, 2, QSE_NULL }, fnc_uci_load, 0 } },
{ QSE_T("open"), { { 0, 0, QSE_NULL }, fnc_uci_open, 0 } },
{ QSE_T("rename"), { { 2, 2, QSE_NULL }, fnc_uci_rename, 0 } },
{ QSE_T("revert"), { { 2, 2, QSE_NULL }, fnc_uci_revert, 0 } },
{ QSE_T("save"), { { 2, 2, QSE_NULL }, fnc_uci_save, 0 } },
{ QSE_T("set"), { { 2, 2, QSE_NULL }, fnc_uci_set, 0 } },
{ QSE_T("setconfdir"), { { 2, 2, QSE_NULL }, fnc_uci_setconfdir, 0 } },
{ QSE_T("setsavedir"), { { 2, 2, QSE_NULL }, fnc_uci_setsavedir, 0 } },
{ QSE_T("unload"), { { 1, 1, QSE_NULL }, fnc_uci_unload, 0 } }
};
/* ------------------------------------------------------------------------ */