added some code to support module calls using module-name::function-name syntax to awk.

reorganized a few awk error code
This commit is contained in:
2012-10-20 15:58:20 +00:00
parent 3cec861547
commit 11b9829c9b
29 changed files with 670 additions and 440 deletions

View File

@ -8,7 +8,7 @@ AM_CPPFLAGS = \
lib_LTLIBRARIES = libqseawk.la
libqseawk_la_SOURCES = awk.c err.c tree.c parse.c run.c rec.c val.c fnc.c misc.c rio.c std.c awk.h err.h rio.h val.h fnc.h misc.h parse.h run.h tree.h
libqseawk_la_LDFLAGS = -L../cmn -L$(libdir) -version-info 1:0:0 -no-undefined
libqseawk_la_LIBADD = -lqsecmn $(LIBM)
libqseawk_la_LIBADD = -lqsecmn $(LIBM) -lltdl
if ENABLE_CXX
lib_LTLIBRARIES += libqseawkxx.la

View File

@ -295,7 +295,7 @@ AM_CPPFLAGS = \
lib_LTLIBRARIES = libqseawk.la $(am__append_1) $(am__append_2)
libqseawk_la_SOURCES = awk.c err.c tree.c parse.c run.c rec.c val.c fnc.c misc.c rio.c std.c awk.h err.h rio.h val.h fnc.h misc.h parse.h run.h tree.h
libqseawk_la_LDFLAGS = -L../cmn -L$(libdir) -version-info 1:0:0 -no-undefined
libqseawk_la_LIBADD = -lqsecmn $(LIBM)
libqseawk_la_LIBADD = -lqsecmn $(LIBM) -lltdl
@ENABLE_CXX_TRUE@libqseawkxx_la_SOURCES = Awk.cpp StdAwk.cpp
@ENABLE_CXX_TRUE@libqseawkxx_la_LDFLAGS = -L. -L../cmn -L$(libdir) -version-info 1:0:0 -no-undefined
@ENABLE_CXX_TRUE@libqseawkxx_la_LIBADD = -lqseawk -lqsecmn $(LIBM)

View File

@ -72,7 +72,7 @@ static void clear_token (qse_awk_tok_t* tok)
tok->loc.colm = 0;
}
qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_awk_prm_t* prm)
{
qse_awk_t* awk;
@ -109,11 +109,11 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
};
/* allocate the object */
awk = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_awk_t) + xtn);
awk = QSE_MMGR_ALLOC (mmgr, QSE_SIZEOF(qse_awk_t) + xtnsize);
if (awk == QSE_NULL) return QSE_NULL;
/* zero out the object */
QSE_MEMSET (awk, 0, QSE_SIZEOF(qse_awk_t) + xtn);
/* zero out the object + extension area */
QSE_MEMSET (awk, 0, QSE_SIZEOF(qse_awk_t) + xtnsize);
/* remember the memory manager */
awk->mmgr = mmgr;

View File

@ -174,8 +174,8 @@ struct qse_awk_t
/* source code management */
struct
{
qse_awk_sio_fun_t inf;
qse_awk_sio_fun_t outf;
qse_awk_sio_impl_t inf;
qse_awk_sio_impl_t outf;
qse_awk_sio_lxc_t last;
@ -236,6 +236,7 @@ struct qse_awk_t
qse_bool_t stopall;
qse_awk_ecb_t* ecb;
qse_awk_mod_t* mod;
};
struct qse_awk_chain_t
@ -340,7 +341,7 @@ struct qse_awk_rtx_t
/* rio chain */
struct
{
qse_awk_rio_fun_t handler[QSE_AWK_RIO_NUM];
qse_awk_rio_impl_t handler[QSE_AWK_RIO_NUM];
qse_awk_rio_arg_t* chain;
} rio;
@ -352,7 +353,7 @@ struct qse_awk_rtx_t
struct
{
qse_char_t* ptr;
qse_size_t len; /* length */
qse_size_t len; /* length */
qse_size_t inc; /* increment */
} tmp;
} format;

View File

@ -88,15 +88,15 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
QSE_T("too many global variables"),
QSE_T("too many local variables"),
QSE_T("too many parameters"),
QSE_T("'delete' not followed by variable"),
QSE_T("'reset' not followed by variable"),
QSE_T("too many identifier segments"),
QSE_T("bad argument"),
QSE_T("no argument provided"),
QSE_T("'break' outside a loop"),
QSE_T("'continue' outside a loop"),
QSE_T("'next' illegal in the BEGIN block"),
QSE_T("'next' illegal in the END block"),
QSE_T("'nextfile' illegal in the BEGIN block"),
QSE_T("'nextfile' illegal in the END block"),
QSE_T("'printf' not followed by argument"),
QSE_T("both prefix and postfix increment/decrement operator present"),
QSE_T("illegal operand for increment/decrement operator"),
QSE_T("'include' not followed by a string"),
@ -116,20 +116,18 @@ const qse_char_t* qse_awk_dflerrstr (const qse_awk_t* awk, qse_awk_errnum_t errn
QSE_T("right-hand side of the 'in' operator not a map nor nil"),
QSE_T("value not referenceable"),
QSE_T("value not assignable"),
QSE_T("an indexed value cannot be assigned a map"),
QSE_T("a positional value cannot be assigned a map"),
QSE_T("indexed value cannot be assigned a map"),
QSE_T("positional value cannot be assigned a map"),
QSE_T("map '${0}' not assignable with a scalar"),
QSE_T("cannot change a scalar value to a map"),
QSE_T("map not allowed"),
QSE_T("invalid value type"),
QSE_T("'delete' called with wrong target"),
QSE_T("'reset' called with wrong target"),
QSE_T("'next' called from BEGIN block"),
QSE_T("'next' called from END block"),
QSE_T("'nextfile' called from BEGIN block"),
QSE_T("'nextfile' called from END block"),
QSE_T("intrinsic function handler for '${0}' failed"),
QSE_T("wrong implementation of user-defined io handler"),
QSE_T("wrong implementation of user-defined I/O handler"),
QSE_T("I/O handler returned an error"),
QSE_T("no such I/O name found"),
QSE_T("I/O name empty"),

View File

@ -99,7 +99,7 @@ void* qse_awk_addfnc (
int when_valid,
qse_size_t min_args, qse_size_t max_args,
const qse_char_t* arg_spec,
qse_awk_fnc_fun_t handler)
qse_awk_fnc_impl_t handler)
{
qse_awk_fnc_t* fnc;
qse_size_t fnc_size;
@ -111,6 +111,10 @@ void* qse_awk_addfnc (
return QSE_NULL;
}
/* Note it doesn't check if it conflicts with a keyword.
* 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)
{
qse_cstr_t errarg;

View File

@ -22,7 +22,6 @@
#define _QSE_LIB_AWK_FNC_H_
typedef struct qse_awk_fnc_t qse_awk_fnc_t;
struct qse_awk_fnc_t
{
struct
@ -42,7 +41,7 @@ struct qse_awk_fnc_t
qse_char_t* spec;
} arg;
qse_awk_fnc_fun_t handler;
qse_awk_fnc_impl_t handler;
/*qse_awk_fnc_t* next;*/
};

File diff suppressed because it is too large Load Diff

View File

@ -89,10 +89,10 @@ static int out_mask_map[] =
static int find_rio_in (
qse_awk_rtx_t* run, int in_type, const qse_char_t* name,
qse_awk_rio_arg_t** rio, qse_awk_rio_fun_t* fun)
qse_awk_rio_arg_t** rio, qse_awk_rio_impl_t* fun)
{
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int io_type, io_mode, io_mask;
QSE_ASSERT (in_type >= 0 && in_type <= QSE_COUNTOF(in_type_map));
@ -297,7 +297,7 @@ int qse_awk_rtx_readio (
const qse_char_t* name, qse_str_t* buf)
{
qse_awk_rio_arg_t* p;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int ret;
qse_awk_val_t* rs;
@ -673,7 +673,7 @@ int qse_awk_rtx_writeio_str (
const qse_char_t* name, qse_char_t* str, qse_size_t len)
{
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int io_type, io_mode, io_mask;
qse_ssize_t n;
@ -816,7 +816,7 @@ int qse_awk_rtx_flushio (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name)
{
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int io_type, /*io_mode,*/ io_mask;
qse_ssize_t n;
int ok = 0;
@ -871,7 +871,7 @@ int qse_awk_rtx_nextio_read (
qse_awk_rtx_t* run, int in_type, const qse_char_t* name)
{
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int io_type, /*io_mode,*/ io_mask;
qse_ssize_t n;
@ -949,7 +949,7 @@ int qse_awk_rtx_nextio_write (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name)
{
qse_awk_rio_arg_t* p = run->rio.chain;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int io_type, /*io_mode,*/ io_mask;
qse_ssize_t n;
@ -1022,7 +1022,7 @@ int qse_awk_rtx_closio_read (
qse_awk_rtx_t* run, int in_type, const qse_char_t* name)
{
qse_awk_rio_arg_t* p = run->rio.chain, * px = QSE_NULL;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int io_type, /*io_mode,*/ io_mask;
QSE_ASSERT (in_type >= 0 && in_type <= QSE_COUNTOF(in_type_map));
@ -1047,7 +1047,7 @@ int qse_awk_rtx_closio_read (
if (p->type == (io_type | io_mask) &&
qse_strcmp (p->name, name) == 0)
{
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
handler = run->rio.handler[p->type & IO_MASK_CLEAR];
if (handler != QSE_NULL)
@ -1081,7 +1081,7 @@ int qse_awk_rtx_closio_write (
qse_awk_rtx_t* run, int out_type, const qse_char_t* name)
{
qse_awk_rio_arg_t* p = run->rio.chain, * px = QSE_NULL;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
int io_type, /*io_mode,*/ io_mask;
QSE_ASSERT (out_type >= 0 && out_type <= QSE_COUNTOF(out_type_map));
@ -1106,7 +1106,7 @@ int qse_awk_rtx_closio_write (
if (p->type == (io_type | io_mask) &&
qse_strcmp (p->name, name) == 0)
{
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
handler = run->rio.handler[p->type & IO_MASK_CLEAR];
if (handler != QSE_NULL)
@ -1147,7 +1147,7 @@ int qse_awk_rtx_closeio (
* regardless of the io type */
if (qse_strcmp (p->name, name) == 0)
{
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
qse_awk_rio_rwcmode_t rwcmode = QSE_AWK_RIO_CLOSE_FULL;
if (opt != QSE_NULL)
@ -1232,7 +1232,7 @@ int qse_awk_rtx_closeio (
void qse_awk_rtx_cleario (qse_awk_rtx_t* run)
{
qse_awk_rio_arg_t* next;
qse_awk_rio_fun_t handler;
qse_awk_rio_impl_t handler;
qse_ssize_t n;
while (run->rio.chain != QSE_NULL)

View File

@ -695,7 +695,7 @@ qse_htb_t* qse_awk_rtx_getnvmap (qse_awk_rtx_t* rtx)
}
qse_awk_rtx_t* qse_awk_rtx_open (
qse_awk_t* awk, qse_size_t xtn, qse_awk_rio_t* rio)
qse_awk_t* awk, qse_size_t xtnsize, qse_awk_rio_t* rio)
{
qse_awk_rtx_t* rtx;
@ -718,7 +718,7 @@ qse_awk_rtx_t* qse_awk_rtx_open (
/* allocate the storage for the rtx object */
rtx = (qse_awk_rtx_t*) QSE_AWK_ALLOC (
awk, QSE_SIZEOF(qse_awk_rtx_t) + xtn);
awk, QSE_SIZEOF(qse_awk_rtx_t) + xtnsize);
if (rtx == QSE_NULL)
{
/* if it fails, the failure is reported thru
@ -727,7 +727,8 @@ qse_awk_rtx_t* qse_awk_rtx_open (
return QSE_NULL;
}
/* initialize the run object */
/* initialize the rtx object */
QSE_MEMSET (rtx, 0, QSE_SIZEOF(qse_awk_rtx_t) + xtnsize);
if (init_rtx (rtx, awk, rio) <= -1)
{
QSE_AWK_FREE (awk, rtx);
@ -830,9 +831,6 @@ static int init_rtx (qse_awk_rtx_t* rtx, qse_awk_t* awk, qse_awk_rio_t* rio)
QSE_HTB_HASHER_DEFAULT
};
/* zero out the runtime context excluding the extension */
QSE_MEMSET (rtx, 0, QSE_SIZEOF(qse_awk_rtx_t));
rtx->awk = awk;
CLRERR (rtx);
@ -2629,14 +2627,13 @@ static int run_delete (qse_awk_rtx_t* rtx, qse_awk_nde_delete_t* nde)
case QSE_AWK_NDE_LCLIDX:
case QSE_AWK_NDE_ARGIDX:
return run_delete_nonnamed (rtx, var);
}
QSE_ASSERTX (
!"should never happen - wrong target for delete",
"the delete statement cannot be called with other nodes than the variables such as a named variable, a named indexed variable, etc");
SETERR_LOC (rtx, QSE_AWK_ERDELETE, &var->loc);
SETERR_LOC (rtx, QSE_AWK_EBADARG, &var->loc);
return -1;
}
@ -2687,7 +2684,7 @@ static int run_reset (qse_awk_rtx_t* rtx, qse_awk_nde_reset_t* nde)
!"should never happen - wrong target for reset",
"the reset statement can only be called with plain variables");
SETERR_LOC (rtx, QSE_AWK_ERRESET, &var->loc);
SETERR_LOC (rtx, QSE_AWK_EBADARG, &var->loc);
return -1;
}

View File

@ -28,6 +28,7 @@
#include <qse/cmn/time.h>
#include <qse/cmn/path.h>
#include <qse/cmn/htb.h>
#include <qse/cmn/rbt.h>
#include <qse/cmn/env.h>
#include <qse/cmn/alg.h>
#include <qse/cmn/stdio.h> /* TODO: remove dependency on qse_vsprintf */
@ -48,6 +49,7 @@
/* anything ? */
#else
# include <unistd.h>
# include <ltdl.h>
#endif
#ifndef QSE_HAVE_CONFIG_H
@ -109,6 +111,9 @@ typedef struct xtn_t
int gbl_argv;
int gbl_environ;
int gbl_procinfo;
qse_rbt_t modtab;
qse_awk_ecb_t ecb;
} xtn_t;
typedef struct rxtn_t
@ -136,6 +141,8 @@ typedef struct rxtn_t
int cmgrtab_inited;
qse_htb_t cmgrtab;
qse_awk_rtx_ecb_t ecb;
} rxtn_t;
typedef struct ioattr_t
@ -307,11 +314,37 @@ static int custom_awk_sprintf (
static int add_globals (qse_awk_t* awk);
static int add_functions (qse_awk_t* awk);
static int query_module (
qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_info_t* info);
static int init_module (qse_awk_t* awk, qse_awk_rtx_t* rtx);
static void fini_module (qse_awk_t* awk, qse_awk_rtx_t* rtx);
static qse_awk_mod_t awk_mod =
{
query_module,
init_module,
fini_module
};
qse_awk_t* qse_awk_openstd (qse_size_t xtnsize)
{
return qse_awk_openstdwithmmgr (QSE_MMGR_GETDFL(), xtnsize);
}
static void fini_xtn (qse_awk_t* awk)
{
xtn_t* xtn;
xtn = (xtn_t*) QSE_XTN (awk);
qse_rbt_fini (&xtn->modtab);
}
static void clear_xtn (qse_awk_t* awk)
{
xtn_t* xtn;
xtn = (xtn_t*) QSE_XTN (awk);
qse_rbt_clear (&xtn->modtab);
}
qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
{
qse_awk_t* awk;
@ -338,7 +371,6 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
/* initialize extension */
xtn = (xtn_t*) QSE_XTN (awk);
QSE_MEMSET (xtn, 0, QSE_SIZEOF(xtn_t));
/* add intrinsic global variables and functions */
if (add_globals(awk) <= -1 ||
@ -348,6 +380,19 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize)
return QSE_NULL;
}
/* TODO: change the way to set this... */
awk->mod = &awk_mod;
if (qse_rbt_init (&xtn->modtab, mmgr, QSE_SIZEOF(qse_char_t), 0) <= -1)
{
qse_awk_close (awk);
return QSE_NULL;
}
xtn->ecb.close = fini_xtn;
xtn->ecb.clear = clear_xtn;
qse_awk_pushecb (awk, &xtn->ecb);
return awk;
}
@ -1874,12 +1919,6 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
const qse_char_t* ocf[],
qse_cmgr_t* cmgr)
{
static qse_awk_rtx_ecb_t ecb =
{
QSE_FV (.close, fini_rxtn),
QSE_FV (.stmt, QSE_NULL)
};
qse_awk_rtx_t* rtx;
qse_awk_rio_t rio;
rxtn_t* rxtn;
@ -1897,11 +1936,9 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
QSE_SIZEOF(rxtn_t) + xtnsize,
&rio
);
if (rtx == QSE_NULL) return QSE_NULL;
rxtn = (rxtn_t*) QSE_XTN (rtx);
QSE_MEMSET (rxtn, 0, QSE_SIZEOF(rxtn_t));
if (rtx->awk->option & QSE_AWK_RIO)
{
@ -1918,7 +1955,8 @@ qse_awk_rtx_t* qse_awk_rtx_openstd (
rxtn->cmgrtab_inited = 1;
}
qse_awk_rtx_pushecb (rtx, &ecb);
rxtn->ecb.close = fini_rxtn;
qse_awk_rtx_pushecb (rtx, &rxtn->ecb);
rxtn->seed = (qse_gettime (&now) <= -1)? 0u: (qse_long_t)now;
/* i don't care if the seed becomes negative or overflows.
@ -2432,3 +2470,82 @@ static int add_functions (qse_awk_t* awk)
qse_awk_addfnc (awk, QSE_T("getioattr"), 9, QSE_AWK_RIO, 2, 2, QSE_NULL, fnc_getioattr) == QSE_NULL) return -1;
return 0;
}
static int query_module (
qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_info_t* info)
{
const qse_char_t* dc;
qse_awk_mod_query_t query;
xtn_t* xtn;
qse_rbt_pair_t* pair;
xtn = (xtn_t*)QSE_XTN(awk);
/* TODO: support module calls with deeper levels ... */
dc = qse_strstr (name, QSE_T("::"));
QSE_ASSERT (dc != QSE_NULL);
#if defined(_WIN32)
/*TODO: implemente this */
qse_awk_seterrnum (awk, QSE_AWK_ENOIMPL, QSE_NULL);
return -1;
#elif defined(__OS2__)
/*TODO: implemente this */
qse_awk_seterrnum (awk, QSE_AWK_ENOIMPL, QSE_NULL);
return -1;
#elif defined(__DOS__)
qse_awk_seterrnum (awk, QSE_AWK_ENOIMPL, QSE_NULL);
return -1;
#else
pair = qse_rbt_search (&xtn->modtab, name, dc - name);
if (pair)
{
/*query = QSE_RBT_VPTR(pair)->query;*/
}
else
{
void* dh;
const qse_mchar_t* mod;
#if defined(QSE_CHAR_IS_MCHAR)
mod = qse_mbsxdup (name, dc - name, QSE_NULL, awk->mmgr);
#else
mod = qse_wcsntombsdup (name, dc - name, QSE_NULL, awk->mmgr);
#endif
if (!mod)
{
qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL);
return -1;
}
dh = lt_dlopen (mod);
QSE_MMGR_FREE (awk->mmgr, mod);
if (!dh)
{
return -1;
}
query = lt_dlsym (dh, QSE_MT("query"));
if (!query)
{
lt_dlclose (dh);
return -1;
}
}
return query (awk, dc + 2, info);
#endif
}
static int init_module (qse_awk_t* awk, qse_awk_rtx_t* rtx)
{
return 0;
}
static void fini_module (qse_awk_t* awk, qse_awk_rtx_t* rtx)
{
}

View File

@ -198,7 +198,7 @@ struct qse_awk_nde_fncall_t
const qse_char_t* spec;
} arg;
qse_awk_fnc_fun_t handler;
qse_awk_fnc_impl_t handler;
} fnc;
} u;
qse_awk_nde_t* args;