From d963a79bd2759e9cb9816ea16ede4183e8cc0975 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 22 Oct 2012 09:36:15 +0000 Subject: [PATCH] touched up code for module call in awk --- qse/include/qse/awk/awk.h | 93 ++++++++++---- qse/include/qse/awk/std.h | 19 --- qse/lib/awk/awk.c | 66 +++++++++- qse/lib/awk/awk.h | 16 ++- qse/lib/awk/parse.c | 133 +++++++++++++++----- qse/lib/awk/rec.c | 16 +-- qse/lib/awk/run.c | 102 ++++++++++++--- qse/lib/awk/std.c | 255 ++++++++++++++++++-------------------- qse/lib/awk/val.c | 18 +-- qse/lib/awk/val.h | 2 +- qse/lib/cmn/rbt.c | 2 + qse/mod/awk/Makefile.am | 6 +- qse/mod/awk/sys.c | 159 ++++++++++++++++++++++-- 13 files changed, 630 insertions(+), 257 deletions(-) diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index f2eae8a0..7a7bc855 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -390,6 +390,22 @@ typedef qse_flt_t (*qse_awk_math2_t) ( qse_flt_t y ); +typedef void* (*qse_awk_modopen_t) ( + qse_awk_t* awk, + const qse_char_t* dir, + const qse_char_t* name +); + +typedef void* (*qse_awk_modsym_t) ( + qse_awk_t* awk, + void* handle, + const qse_char_t* name +); + +typedef void (*qse_awk_modclose_t) ( + qse_awk_t* awk, + void* handle +); #if 0 typedef void* (*qse_awk_buildrex_t) ( @@ -413,7 +429,7 @@ typedef void (*qse_awk_freerex_t) ( void* code ); -typedef qse_bool_t (*qse_awk_isemptyrex_t) ( +typedef int (*qse_awk_isemptyrex_t) ( qse_awk_t* awk, void* code ); @@ -606,6 +622,10 @@ struct qse_awk_prm_t qse_awk_math1_t sqrt; } math; + qse_awk_modopen_t modopen; + qse_awk_modclose_t modclose; + qse_awk_modsym_t modsym; + #if 0 struct { @@ -685,18 +705,56 @@ 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_info_t qse_awk_mod_info_t; +typedef struct qse_awk_mod_sym_t qse_awk_mod_sym_t; -enum qse_awk_mod_type_t +typedef int (*qse_awk_mod_load_t) ( + qse_awk_mod_t* mod, + qse_awk_t* awk +); + +typedef int (*qse_awk_mod_query_t) ( + qse_awk_mod_t* mod, + qse_awk_t* awk, + const qse_char_t* name, + qse_awk_mod_sym_t* sym +); + +typedef void (*qse_awk_mod_unload_t) ( + qse_awk_mod_t* mod, + qse_awk_t* awk +); + +typedef int (*qse_awk_mod_init_t) ( + qse_awk_mod_t* mod, + qse_awk_rtx_t* rtx +); + +typedef void (*qse_awk_mod_fini_t) ( + qse_awk_mod_t* mod, + qse_awk_rtx_t* rtx +); + +struct qse_awk_mod_t +{ + qse_awk_mod_query_t query; + qse_awk_mod_unload_t unload; + + qse_awk_mod_init_t init; + qse_awk_mod_fini_t fini; + + void* ctx; +}; + +enum qse_awk_mod_sym_type_t { QSE_AWK_MOD_FNC = 0 /*, QSE_AWK_MOD_VAR */ }; -typedef enum qse_awk_mod_type_t qse_awk_mod_type_t; +typedef enum qse_awk_mod_sym_type_t qse_awk_mod_sym_type_t; -struct qse_awk_mod_info_t +struct qse_awk_mod_sym_t { - qse_awk_mod_type_t type; + qse_awk_mod_sym_type_t type; union { struct @@ -711,19 +769,6 @@ struct qse_awk_mod_info_t } u; }; -typedef int (*qse_awk_mod_query_t) ( - qse_awk_t* awk, - const qse_char_t* name, - qse_awk_mod_info_t* info -); - -struct qse_awk_mod_t -{ - qse_awk_mod_query_t query; - int (*init) (qse_awk_t* awk, qse_awk_rtx_t* rtx); - void (*fini) (qse_awk_t* awk, qse_awk_rtx_t* rtx); -}; - /* ------------------------------------------------------------------------ */ /** @@ -814,6 +859,8 @@ struct qse_awk_rtx_ecb_t enum qse_awk_opt_t { QSE_AWK_TRAIT = 0, + QSE_AWK_MODDIR, + QSE_AWK_DEPTH_INCLUDE, QSE_AWK_DEPTH_BLOCK_PARSE, QSE_AWK_DEPTH_BLOCK_RUN, @@ -1784,7 +1831,7 @@ void qse_awk_stopall ( * The qse_awk_rtx_isstop() function tests if qse_awk_rtx_stop() has been * called. */ -qse_bool_t qse_awk_rtx_isstop ( +int qse_awk_rtx_isstop ( qse_awk_rtx_t* rtx /**< runtime context */ ); @@ -2015,7 +2062,7 @@ void qse_awk_rtx_seterror ( */ int qse_awk_rtx_clrrec ( qse_awk_rtx_t* rtx, /**< runtime context */ - qse_bool_t skip_inrec_line + int skip_inrec_line ); /** @@ -2191,7 +2238,7 @@ qse_awk_val_t* qse_awk_rtx_makerefval ( * is closed. * @return QSE_TRUE if @a val is static, QSE_FALSE if @a val is false */ -qse_bool_t qse_awk_rtx_isstaticval ( +int qse_awk_rtx_isstaticval ( qse_awk_rtx_t* rtx, /**< runtime context */ qse_awk_val_t* val /**< value to check */ ); @@ -2228,7 +2275,7 @@ void qse_awk_rtx_refdownval_nofree ( * The qse_awk_rtx_valtobool() function converts a value @a val to a boolean * value. */ -qse_bool_t qse_awk_rtx_valtobool ( +int qse_awk_rtx_valtobool ( qse_awk_rtx_t* rtx, /**< runtime context */ const qse_awk_val_t* val /**< value pointer */ ); diff --git a/qse/include/qse/awk/std.h b/qse/include/qse/awk/std.h index bb2c04f6..7ee3a93e 100644 --- a/qse/include/qse/awk/std.h +++ b/qse/include/qse/awk/std.h @@ -44,13 +44,6 @@ * */ -enum qse_awk_optstd_t -{ - QSE_AWK_MODDIR = 0 -}; - -typedef enum qse_awk_optstd_t qse_awk_optstd_t; - /** * The qse_awk_parsestd_type_t type defines the types of source I/O. */ @@ -135,18 +128,6 @@ void* qse_awk_getxtnstd ( qse_awk_t* awk ); -int qse_awk_getoptstd ( - qse_awk_t* awk, - qse_awk_optstd_t id, - void* value -); - -int qse_awk_setoptstd ( - qse_awk_t* awk, - qse_awk_optstd_t id, - const void* value -); - /** * The qse_awk_parsestd() functions parses source script. * The code below shows how to parse a literal string 'BEGIN { print 10; }' diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index eb24a0bd..3309b828 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -219,7 +219,7 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_awk_prm_t* pr awk->errinf.loc.colm = 0; awk->errinf.loc.file = QSE_NULL; awk->errstr = qse_awk_dflerrstr; - awk->stopall = QSE_FALSE; + awk->stopall = 0; awk->tree.ngbls = 0; awk->tree.ngbls_base = 0; @@ -239,11 +239,19 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtnsize, qse_awk_prm_t* pr *(qse_awk_t**)QSE_XTN(awk->fnc.user) = awk; qse_htb_setmancbs (awk->fnc.user, &fncusercbs); + awk->modtab = qse_rbt_open (mmgr, 0, QSE_SIZEOF(qse_char_t), 1); + if (awk->modtab == QSE_NULL) goto oops; + qse_rbt_setmancbs ( + awk->modtab, + qse_getrbtmancbs(QSE_RBT_MANCBS_INLINE_COPIERS) + ); + if (qse_awk_initgbls (awk) <= -1) goto oops; return awk; oops: + if (awk->modtab) qse_rbt_close (awk->modtab); if (awk->fnc.user) qse_htb_close (awk->fnc.user); if (awk->parse.params) qse_lda_close (awk->parse.params); if (awk->parse.lcls) qse_lda_close (awk->parse.lcls); @@ -270,6 +278,7 @@ int qse_awk_close (qse_awk_t* awk) for (ecb = awk->ecb; ecb; ecb = ecb->next) if (ecb->close) ecb->close (awk); + qse_rbt_close (awk->modtab); qse_htb_close (awk->fnc.user); qse_lda_close (awk->parse.params); @@ -285,12 +294,27 @@ int qse_awk_close (qse_awk_t* awk) fini_token (&awk->tok); fini_token (&awk->ptok); + /* destroy dynamically allocated options */ + if (awk->opt.moddir.ptr) + QSE_MMGR_FREE (awk->mmgr, awk->opt.moddir.ptr); + /* QSE_AWK_ALLOC, QSE_AWK_FREE, etc can not be used * from the next line onwards */ QSE_AWK_FREE (awk, awk); return 0; } +static qse_rbt_walk_t unload_module (qse_rbt_t* rbt, qse_rbt_pair_t* pair, void* ctx) +{ + qse_awk_t* awk = (qse_awk_t*)ctx; + qse_awk_mod_data_t* md; + + md = QSE_RBT_VPTR(pair); + awk->prm.modclose (awk, md->handle); + + return QSE_RBT_WALK_FORWARD; +} + int qse_awk_clear (qse_awk_t* awk) { qse_awk_ecb_t* ecb; @@ -298,12 +322,15 @@ int qse_awk_clear (qse_awk_t* awk) for (ecb = awk->ecb; ecb; ecb = ecb->next) if (ecb->clear) ecb->clear (awk); - awk->stopall = QSE_FALSE; + awk->stopall = 0; clear_token (&awk->tok); clear_token (&awk->ntok); clear_token (&awk->ptok); + qse_rbt_walk (awk->modtab, unload_module, awk); + qse_rbt_clear (awk->modtab); + QSE_ASSERT (QSE_LDA_SIZE(awk->parse.gbls) == awk->tree.ngbls); /* delete all non-builtin global variables */ qse_lda_delete ( @@ -395,6 +422,33 @@ int qse_awk_setopt (qse_awk_t* awk, qse_awk_opt_t id, const void* value) awk->opt.trait = *(const int*)value; return 0; + case QSE_AWK_MODDIR: + { + qse_xstr_t tmp; + + if (value) + { + tmp.ptr = qse_strdup (value, awk->mmgr); + if (tmp.ptr == QSE_NULL) + { + qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return -1; + } + tmp.len = qse_strlen (tmp.ptr); + } + else + { + tmp.ptr = QSE_NULL; + tmp.len = 0; + } + + if (awk->opt.moddir.ptr) + QSE_MMGR_FREE (awk->mmgr, awk->opt.moddir.ptr); + + awk->opt.moddir = tmp; + return 0; + } + case QSE_AWK_DEPTH_INCLUDE: case QSE_AWK_DEPTH_BLOCK_PARSE: case QSE_AWK_DEPTH_BLOCK_RUN: @@ -418,6 +472,11 @@ int qse_awk_getopt (qse_awk_t* awk, qse_awk_opt_t id, void* value) *(int*)value = awk->opt.trait; return 0; + case QSE_AWK_MODDIR: + *(const qse_char_t**)value = awk->opt.moddir.ptr; + return 0; + + case QSE_AWK_DEPTH_INCLUDE: case QSE_AWK_DEPTH_BLOCK_PARSE: case QSE_AWK_DEPTH_BLOCK_RUN: @@ -435,9 +494,8 @@ int qse_awk_getopt (qse_awk_t* awk, qse_awk_opt_t id, void* value) void qse_awk_stopall (qse_awk_t* awk) { - awk->stopall = QSE_TRUE; + awk->stopall = 1; qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); - return -1; } qse_awk_ecb_t* qse_awk_popecb (qse_awk_t* awk) diff --git a/qse/lib/awk/awk.h b/qse/lib/awk/awk.h index 2faa8e7b..6a7dea03 100644 --- a/qse/lib/awk/awk.h +++ b/qse/lib/awk/awk.h @@ -27,6 +27,7 @@ #include #include #include +#include typedef struct qse_awk_chain_t qse_awk_chain_t; typedef struct qse_awk_tree_t qse_awk_tree_t; @@ -122,6 +123,8 @@ struct qse_awk_t struct { int trait; + qse_xstr_t moddir; + union { qse_size_t a[7]; @@ -217,9 +220,10 @@ struct qse_awk_t qse_awk_errstr_t errstr; qse_awk_errinf_t errinf; - qse_bool_t stopall; + int stopall; qse_awk_ecb_t* ecb; - qse_awk_mod_t* mod; + + qse_rbt_t* modtab; }; struct qse_awk_chain_t @@ -265,7 +269,7 @@ struct qse_awk_rtx_t qse_char_t buf[1024]; qse_size_t buf_pos; qse_size_t buf_len; - qse_bool_t eof; + int eof; qse_str_t line; /* entire line */ qse_str_t linew; /* line for manipulation, if necessary */ @@ -353,6 +357,12 @@ struct qse_awk_rtx_t qse_awk_rtx_ecb_t* ecb; }; +typedef struct qse_awk_mod_data_t qse_awk_mod_data_t; +struct qse_awk_mod_data_t +{ + void* handle; + qse_awk_mod_t mod; +}; #define QSE_AWK_FREEREX(awk,code) qse_freerex((awk)->mmgr,code) #define QSE_AWK_BUILDREX(awk,ptn,len,errnum) \ diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index dec1293a..4b9a7bc8 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -161,16 +161,16 @@ 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_awk_t* collect_locals ( - qse_awk_t* awk, qse_size_t nlcls, qse_bool_t istop); + qse_awk_t* awk, qse_size_t nlcls, int istop); static qse_awk_nde_t* parse_function (qse_awk_t* awk); static qse_awk_nde_t* parse_begin (qse_awk_t* awk); static qse_awk_nde_t* parse_end (qse_awk_t* awk); static qse_awk_chain_t* parse_action_block ( - qse_awk_t* awk, qse_awk_nde_t* ptn, qse_bool_t blockless); + qse_awk_t* awk, qse_awk_nde_t* ptn, int blockless); static qse_awk_nde_t* parse_block_dc ( - qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_bool_t istop); + qse_awk_t* awk, const qse_awk_loc_t* xloc, int istop); static qse_awk_nde_t* parse_statement ( qse_awk_t* awk, const qse_awk_loc_t* xloc); @@ -240,6 +240,10 @@ static qse_htb_walk_t deparse_func ( static int put_char (qse_awk_t* awk, qse_char_t c); static int flush_out (qse_awk_t* awk); +static int query_module ( + qse_awk_t* awk, const qse_xstr_t* segs, int nsegs, + qse_awk_mod_sym_t* sym); + typedef struct kwent_t kwent_t; struct kwent_t @@ -933,8 +937,7 @@ retry: } awk->parse.id.block = PARSE_ACTION_BLOCK; - if (parse_action_block ( - awk, QSE_NULL, QSE_FALSE) == QSE_NULL) return QSE_NULL; + if (parse_action_block (awk, QSE_NULL, 0) == QSE_NULL) return QSE_NULL; /* skip a semicolon after an action block if any */ if (MATCH(awk,TOK_SEMICOLON) && @@ -989,11 +992,11 @@ retry: if (MATCH(awk,TOK_NEWLINE) || MATCH(awk,TOK_SEMICOLON) || MATCH(awk,TOK_EOF)) { /* blockless pattern */ - qse_bool_t eof = MATCH(awk,TOK_EOF); + int eof = MATCH(awk,TOK_EOF); qse_awk_loc_t ploc = awk->ptok.loc; awk->parse.id.block = PARSE_ACTION_BLOCK; - if (parse_action_block (awk, ptn, QSE_TRUE) == QSE_NULL) + if (parse_action_block (awk, ptn, 1) == QSE_NULL) { qse_awk_clrpt (awk, ptn); return QSE_NULL; @@ -1031,7 +1034,7 @@ retry: } awk->parse.id.block = PARSE_ACTION_BLOCK; - if (parse_action_block (awk, ptn, QSE_FALSE) == QSE_NULL) + if (parse_action_block (awk, ptn, 0) == QSE_NULL) { qse_awk_clrpt (awk, ptn); return QSE_NULL; @@ -1264,7 +1267,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk) /* actual function body */ { qse_awk_loc_t xloc = awk->ptok.loc; - body = parse_block_dc (awk, &xloc, QSE_TRUE); + body = parse_block_dc (awk, &xloc, 1); } /* clear the current function name remembered */ @@ -1330,7 +1333,7 @@ static qse_awk_nde_t* parse_begin (qse_awk_t* awk) QSE_ASSERT (MATCH(awk,TOK_LBRACE)); if (get_token(awk) <= -1) return QSE_NULL; - nde = parse_block_dc (awk, &xloc, QSE_TRUE); + nde = parse_block_dc (awk, &xloc, 1); if (nde == QSE_NULL) return QSE_NULL; if (awk->tree.begin == QSE_NULL) @@ -1355,7 +1358,7 @@ static qse_awk_nde_t* parse_end (qse_awk_t* awk) QSE_ASSERT (MATCH(awk,TOK_LBRACE)); if (get_token(awk) <= -1) return QSE_NULL; - nde = parse_block_dc (awk, &xloc, QSE_TRUE); + nde = parse_block_dc (awk, &xloc, 1); if (nde == QSE_NULL) return QSE_NULL; if (awk->tree.end == QSE_NULL) @@ -1372,7 +1375,7 @@ static qse_awk_nde_t* parse_end (qse_awk_t* awk) } static qse_awk_chain_t* parse_action_block ( - qse_awk_t* awk, qse_awk_nde_t* ptn, qse_bool_t blockless) + qse_awk_t* awk, qse_awk_nde_t* ptn, int blockless) { qse_awk_nde_t* nde; qse_awk_chain_t* chain; @@ -1383,7 +1386,7 @@ static qse_awk_chain_t* parse_action_block ( { QSE_ASSERT (MATCH(awk,TOK_LBRACE)); if (get_token(awk) <= -1) return QSE_NULL; - nde = parse_block_dc (awk, &xloc, QSE_TRUE); + nde = parse_block_dc (awk, &xloc, 1); if (nde == QSE_NULL) return QSE_NULL; } @@ -1417,7 +1420,7 @@ static qse_awk_chain_t* parse_action_block ( } static qse_awk_nde_t* parse_block ( - qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_bool_t istop) + qse_awk_t* awk, const qse_awk_loc_t* xloc, int istop) { qse_awk_nde_t* head, * curr, * nde; qse_awk_nde_blk_t* block; @@ -1574,7 +1577,7 @@ static qse_awk_nde_t* parse_block ( } static qse_awk_nde_t* parse_block_dc ( - qse_awk_t* awk, const qse_awk_loc_t* xloc, qse_bool_t istop) + qse_awk_t* awk, const qse_awk_loc_t* xloc, int istop) { qse_awk_nde_t* nde; @@ -1901,7 +1904,7 @@ static qse_awk_t* collect_globals (qse_awk_t* awk) } static qse_awk_t* collect_locals ( - qse_awk_t* awk, qse_size_t nlcls, qse_bool_t istop) + qse_awk_t* awk, qse_size_t nlcls, int istop) { if (MATCH(awk,TOK_NEWLINE)) { @@ -3016,7 +3019,7 @@ static qse_awk_nde_t* parse_statement ( /* a block statemnt { ... } */ qse_awk_loc_t tloc = awk->ptok.loc; if (get_token(awk) <= -1) return QSE_NULL; - nde = parse_block_dc (awk, &tloc, QSE_FALSE); + nde = parse_block_dc (awk, &tloc, 0); } else { @@ -3525,7 +3528,7 @@ static qse_awk_nde_t* parse_binary ( { qse_awk_loc_t rloc; const binmap_t* p = binmap; - qse_bool_t matched = QSE_FALSE; + int matched = 0; int opcode, fold; folded_t folded; @@ -3534,7 +3537,7 @@ static qse_awk_nde_t* parse_binary ( if (MATCH(awk,p->token)) { opcode = p->binop; - matched = QSE_TRUE; + matched = 1; break; } p++; @@ -4990,29 +4993,30 @@ static qse_awk_nde_t* parse_primary_ident_noseg ( } static qse_awk_nde_t* parse_primary_ident_segs ( - qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_xstr_t* full) + qse_awk_t* awk, const qse_awk_loc_t* xloc, const qse_xstr_t* full, + const qse_xstr_t segs[], int nsegs) { qse_awk_nde_t* nde = QSE_NULL; - qse_awk_mod_info_t info; + qse_awk_mod_sym_t sym; qse_awk_fnc_t fnc; CLRERR (awk); - if (!awk->mod || awk->mod->query (awk, full->ptr, &info) <= -1) + if (query_module (awk, segs, nsegs, &sym) <= -1) { if (ISNOERR(awk)) SETERR_LOC (awk, QSE_AWK_ENOSUP, xloc); } else { - if (info.type == QSE_AWK_MOD_FNC) + if (sym.type == QSE_AWK_MOD_FNC) { 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 = info.u.f.arg.min; - fnc.arg.max = info.u.f.arg.max; - fnc.handler = info.u.f.impl; + fnc.arg.min = sym.u.f.arg.min; + fnc.arg.max = sym.u.f.arg.max; + fnc.handler = sym.u.f.impl; nde = parse_fncall (awk, full, &fnc, xloc, 0); } @@ -5067,7 +5071,7 @@ static qse_awk_nde_t* parse_primary_ident ( full.ptr[capa] = QSE_T('\0'); full.len = capa; - nde = parse_primary_ident_segs (awk, xloc, &full); + nde = parse_primary_ident_segs (awk, xloc, &full, name, nsegs); if (!nde) QSE_MMGR_FREE (awk->mmgr, full.ptr); } else @@ -5457,7 +5461,7 @@ static int get_number (qse_awk_t* awk, qse_awk_tok_t* tok) static int get_string ( qse_awk_t* awk, qse_char_t end_char, - qse_char_t esc_char, qse_bool_t keep_esc_char, + qse_char_t esc_char, int keep_esc_char, int preescaped, qse_awk_tok_t* tok) { qse_cint_t c; @@ -5619,7 +5623,7 @@ static int get_charstr (qse_awk_t* awk, qse_awk_tok_t* tok) * has been called */ ADD_TOKEN_CHAR (awk, tok, awk->sio.last.c); } - return get_string (awk, QSE_T('\"'), QSE_T('\\'), QSE_FALSE, 0, tok); + return get_string (awk, QSE_T('\"'), QSE_T('\\'), 0, 0, tok); } static int get_rexstr (qse_awk_t* awk, qse_awk_tok_t* tok) @@ -5654,7 +5658,7 @@ static int get_rexstr (qse_awk_t* awk, qse_awk_tok_t* tok) ADD_TOKEN_CHAR (awk, tok, awk->sio.last.c); } return get_string ( - awk, QSE_T('/'), QSE_T('\\'), QSE_TRUE, escaped, tok); + awk, QSE_T('/'), QSE_T('\\'), 1, escaped, tok); } } @@ -6487,3 +6491,72 @@ int qse_awk_putsrcstrn ( return 0; } + +static int query_module ( + qse_awk_t* awk, const qse_xstr_t segs[], int nsegs, qse_awk_mod_sym_t* sym) +{ + qse_rbt_pair_t* pair; + qse_awk_mod_data_t md; + qse_cstr_t ea; + + QSE_ASSERT (nsegs == 2); + + pair = qse_rbt_search (awk->modtab, segs[0].ptr, segs[0].len); + if (pair) + { + md = *(qse_awk_mod_data_t*)QSE_RBT_VPTR(pair); + } + else + { + qse_awk_mod_load_t load; + const qse_char_t* moddir; + + if (awk->opt.moddir.len > 0) + { + moddir = awk->opt.moddir.ptr; + } + #if defined(DEFAULT_MODDIR) + else + { + moddir = QSE_T(DEFAULT_MODDIR); + } + #endif + + QSE_MEMSET (&md, 0, QSE_SIZEOF(md)); + md.handle = awk->prm.modopen (awk, moddir, segs[0].ptr); + if (!md.handle) + { + ea.ptr = segs[0].ptr; + ea.len = segs[0].len; + qse_awk_seterror (awk, QSE_AWK_ENOENT, &ea, QSE_NULL); + return -1; + } + + load = awk->prm.modsym (awk, md.handle, QSE_T("load")); + if (!load) + { + awk->prm.modclose (awk, md.handle); + + ea.ptr = QSE_T("load"); + ea.len = 4; + qse_awk_seterror (awk, QSE_AWK_ENOENT, &ea, QSE_NULL); + return -1; + } + + if (load (&md.mod, awk) <= -1) + { + awk->prm.modclose (awk, md.handle); + return -1; + } + + if (qse_rbt_insert (awk->modtab, segs[0].ptr, segs[0].len, &md, QSE_SIZEOF(md)) == QSE_NULL) + { + awk->prm.modclose (awk, md.handle); + qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return -1; + } + } + + return md.mod.query (&md.mod, awk, segs[1].ptr, sym); +} + diff --git a/qse/lib/awk/rec.c b/qse/lib/awk/rec.c index 272fd674..f54c5b82 100644 --- a/qse/lib/awk/rec.c +++ b/qse/lib/awk/rec.c @@ -36,15 +36,15 @@ int qse_awk_rtx_setrec ( if (str == QSE_STR_PTR(&run->inrec.line) && len == QSE_STR_LEN(&run->inrec.line)) { - if (qse_awk_rtx_clrrec (run, QSE_TRUE) == -1) return -1; + if (qse_awk_rtx_clrrec (run, 1) == -1) return -1; } else { - if (qse_awk_rtx_clrrec (run, QSE_FALSE) == -1) return -1; + if (qse_awk_rtx_clrrec (run, 0) == -1) return -1; if (qse_str_ncpy (&run->inrec.line, str, len) == (qse_size_t)-1) { - qse_awk_rtx_clrrec (run, QSE_FALSE); + qse_awk_rtx_clrrec (run, 0); qse_awk_rtx_seterrnum (run, QSE_AWK_ENOMEM, QSE_NULL); return -1; } @@ -54,7 +54,7 @@ int qse_awk_rtx_setrec ( if (v == QSE_NULL) { - qse_awk_rtx_clrrec (run, QSE_FALSE); + qse_awk_rtx_clrrec (run, 0); return -1; } @@ -66,7 +66,7 @@ int qse_awk_rtx_setrec ( if (split_record (run) == -1) { - qse_awk_rtx_clrrec (run, QSE_FALSE); + qse_awk_rtx_clrrec (run, 0); return -1; } } @@ -74,7 +74,7 @@ int qse_awk_rtx_setrec ( { if (recomp_record_fields (run, idx, str, len) == -1) { - qse_awk_rtx_clrrec (run, QSE_FALSE); + qse_awk_rtx_clrrec (run, 0); return -1; } @@ -84,7 +84,7 @@ int qse_awk_rtx_setrec ( QSE_STR_LEN(&run->inrec.line)); if (v == QSE_NULL) { - qse_awk_rtx_clrrec (run, QSE_FALSE); + qse_awk_rtx_clrrec (run, 0); return -1; } @@ -363,7 +363,7 @@ static int split_record (qse_awk_rtx_t* rtx) return 0; } -int qse_awk_rtx_clrrec (qse_awk_rtx_t* run, qse_bool_t skip_inrec_line) +int qse_awk_rtx_clrrec (qse_awk_rtx_t* run, int skip_inrec_line) { qse_size_t i; int n = 0; diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index 10e9de9a..9b15a1f9 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -694,10 +694,56 @@ qse_htb_t* qse_awk_rtx_getnvmap (qse_awk_rtx_t* rtx) return rtx->named; } +struct module_init_ctx_t +{ + qse_size_t count; + qse_awk_rtx_t* rtx; +}; + +struct module_fini_ctx_t +{ + qse_size_t limit; + qse_size_t count; + qse_awk_rtx_t* rtx; +}; + +static qse_rbt_walk_t init_module (qse_rbt_t* rbt, qse_rbt_pair_t* pair, void* ctx) +{ + qse_awk_mod_data_t* md; + struct module_init_ctx_t* mic; + + mic = (struct module_init_ctx_t*)ctx; + + md = (qse_awk_mod_data_t*)QSE_RBT_VPTR(pair); + if (md->mod.init && md->mod.init (&md->mod, mic->rtx) <= -1) + return QSE_RBT_WALK_STOP; + + mic->count++; + return QSE_RBT_WALK_FORWARD; +} + +static qse_rbt_walk_t fini_module (qse_rbt_t* rbt, qse_rbt_pair_t* pair, void* ctx) +{ + qse_awk_mod_data_t* md; + struct module_fini_ctx_t* mfc; + + mfc = (struct module_fini_ctx_t*)ctx; + + if (mfc->limit > 0 && mfc->count >= mfc->limit) + return QSE_RBT_WALK_STOP; + + md = (qse_awk_mod_data_t*)QSE_RBT_VPTR(pair); + if (md->mod.fini) md->mod.fini (&md->mod, mfc->rtx); + + mfc->count++; + return QSE_RBT_WALK_FORWARD; +} + qse_awk_rtx_t* qse_awk_rtx_open ( qse_awk_t* awk, qse_size_t xtnsize, qse_awk_rio_t* rio) { qse_awk_rtx_t* rtx; + struct module_init_ctx_t mic; QSE_ASSERTX (awk->prm.math.pow != QSE_NULL, "Call qse_awk_setprm() first"); QSE_ASSERTX (awk->prm.sprintf != QSE_NULL, "Call qse_awk_setprm() first"); @@ -743,16 +789,42 @@ qse_awk_rtx_t* qse_awk_rtx_open ( return QSE_NULL; } + mic.count = 0; + mic.rtx = rtx; + qse_rbt_walk (rtx->awk->modtab, init_module, &mic); + if (mic.count != QSE_RBT_SIZE(rtx->awk->modtab)) + { + awk->errinf = rtx->errinf; /* transfer error info */ + + if (mic.count > 0) + { + struct module_fini_ctx_t mfc; + mfc.limit = mic.count; + mfc.count = 0; + qse_rbt_walk (rtx->awk->modtab, fini_module, &mfc); + } + + fini_rtx (rtx, 1); + QSE_AWK_FREE (awk, rtx); + return QSE_NULL; + } + return rtx; } void qse_awk_rtx_close (qse_awk_rtx_t* rtx) { qse_awk_rtx_ecb_t* ecb; + struct module_fini_ctx_t mfc; for (ecb = rtx->ecb; ecb; ecb = ecb->next) if (ecb->close) ecb->close (rtx); + mfc.limit = 0; + mfc.count = 0; + mfc.rtx = rtx; + qse_rbt_walk (rtx->awk->modtab, fini_module, &mfc); + /* NOTE: * the close callbacks are called before data in rtx * is destroyed. if the destruction count on any data @@ -769,7 +841,7 @@ void qse_awk_rtx_stop (qse_awk_rtx_t* rtx) rtx->exit_level = EXIT_ABORT; } -qse_bool_t qse_awk_rtx_isstop (qse_awk_rtx_t* rtx) +int qse_awk_rtx_isstop (qse_awk_rtx_t* rtx) { return (rtx->exit_level == EXIT_ABORT || rtx->awk->stopall); } @@ -987,7 +1059,7 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals) /* destroy input record. qse_awk_rtx_clrrec() should be called * before the stack has been destroyed because it may try * to change the value to QSE_AWK_GBL_NF. */ - qse_awk_rtx_clrrec (rtx, QSE_FALSE); + qse_awk_rtx_clrrec (rtx, 0); if (rtx->inrec.flds) { QSE_AWK_FREE (rtx->awk, rtx->inrec.flds); @@ -1019,7 +1091,7 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals) while (rtx->fcache_count > 0) { qse_awk_val_ref_t* tmp = rtx->fcache[--rtx->fcache_count]; - qse_awk_rtx_freeval (rtx, (qse_awk_val_t*)tmp, QSE_FALSE); + qse_awk_rtx_freeval (rtx, (qse_awk_val_t*)tmp, 0); } #ifdef ENABLE_FEATURE_SCACHE @@ -1032,7 +1104,7 @@ static void fini_rtx (qse_awk_rtx_t* rtx, int fini_globals) qse_awk_val_str_t* t = rtx->scache[i][--rtx->scache_count[i]]; qse_awk_rtx_freeval ( - rtx, (qse_awk_val_t*)t, QSE_FALSE); + rtx, (qse_awk_val_t*)t, 0); } } } @@ -1567,7 +1639,7 @@ static int run_pblocks (qse_awk_rtx_t* run) run->inrec.buf_pos = 0; run->inrec.buf_len = 0; - run->inrec.eof = QSE_FALSE; + run->inrec.eof = 0; /* run each pattern block */ while (run->exit_level < EXIT_GLOBAL) @@ -5156,7 +5228,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -5176,7 +5248,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -5209,7 +5281,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -5229,7 +5301,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -5253,7 +5325,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -5273,7 +5345,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -5306,7 +5378,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -5326,7 +5398,7 @@ static qse_awk_val_t* eval_incpst (qse_awk_rtx_t* run, qse_awk_nde_t* nde) if (res2 == QSE_NULL) { qse_awk_rtx_refdownval (run, left); - qse_awk_rtx_freeval (run, res, QSE_TRUE); + qse_awk_rtx_freeval (run, res, 1); ADJERR_LOC (run, &nde->loc); return QSE_NULL; } @@ -6407,13 +6479,13 @@ static int read_record (qse_awk_rtx_t* rtx) qse_str_t* buf; read_again: - if (qse_awk_rtx_clrrec (rtx, QSE_FALSE) == -1) return -1; + if (qse_awk_rtx_clrrec (rtx, 0) == -1) return -1; buf = &rtx->inrec.line; n = qse_awk_rtx_readio (rtx, QSE_AWK_IN_CONSOLE, QSE_T(""), buf); if (n <= -1) { - qse_awk_rtx_clrrec (rtx, QSE_FALSE); + qse_awk_rtx_clrrec (rtx, 0); return -1; } diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index d8e172ad..2763826d 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include /* TODO: remove dependency on qse_vsprintf */ @@ -112,13 +111,6 @@ typedef struct xtn_t int gbl_environ; int gbl_procinfo; - struct - { - qse_xstr_t moddir; - } opt; - - qse_rbt_t modtab; - qse_awk_ecb_t ecb; } xtn_t; @@ -158,12 +150,6 @@ typedef struct ioattr_t int tmout[4]; } ioattr_t; -typedef struct mod_data_t -{ - lt_dlhandle dh; - qse_awk_mod_query_t query; -} mod_data_t; - static ioattr_t* get_ioattr (qse_htb_t* tab, const qse_char_t* ptr, qse_size_t len); static qse_flt_t custom_awk_pow (qse_awk_t* awk, qse_flt_t x, qse_flt_t y) @@ -323,21 +309,105 @@ static int custom_awk_sprintf ( return n; } +static void* custom_awk_modopen ( + qse_awk_t* awk, const qse_char_t* dir, const qse_char_t* name) +{ +#if defined(_WIN32) + /*TODO: implemente this - use LoadLibrary... */ + 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__) + /*TODO: implemente this */ + qse_awk_seterrnum (awk, QSE_AWK_ENOIMPL, QSE_NULL); + return -1; +#else + + void* h; + qse_mchar_t* modpath; + qse_char_t* tmp[5]; + int count = 0; + + if (dir && dir[0] != QSE_T('\0')) + { + tmp[count++] = dir; + tmp[count++] = QSE_T("/"); + } + tmp[count++] = QSE_T("lib"); + tmp[count++] = name; + tmp[count] = QSE_NULL; + + #if defined(QSE_CHAR_IS_MCHAR) + modpath = qse_mbsadup (tmp, QSE_NULL, awk->mmgr); + #else + modpath = qse_wcsatombsdup (tmp, QSE_NULL, awk->mmgr); + #endif + + h = lt_dlopenext (modpath); + + QSE_MMGR_FREE (awk->mmgr, modpath); + + return h; + +#endif +} + +static void custom_awk_modclose (qse_awk_t* awk, void* handle) +{ +#if defined(_WIN32) + /*TODO: implemente this */ +#elif defined(__OS2__) + /*TODO: implemente this */ +#elif defined(__DOS__) + /*TODO: implemente this */ +#else + lt_dlclose (handle); +#endif +} + +static void* custom_awk_modsym (qse_awk_t* awk, void* handle, const qse_char_t* name) +{ +#if defined(_WIN32) + /*TODO: implemente this */ +#elif defined(__OS2__) + /*TODO: implemente this */ +#elif defined(__DOS__) + /*TODO: implemente this */ +#else + + void* s; + qse_mchar_t* mname; + + #if defined(QSE_CHAR_IS_MCHAR) + mname = name; + #else + mname = qse_wcstombsdup (name, QSE_NULL, awk->mmgr); + if (!mname) + { + qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); + return QSE_NULL; + } + #endif + + s = lt_dlsym (handle, mname); + + #if defined(QSE_CHAR_IS_MCHAR) + /* nothing to do */ + #else + QSE_MMGR_FREE (awk->mmgr, mname); + #endif + + return s; + +#endif +} + 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); @@ -345,20 +415,12 @@ qse_awk_t* qse_awk_openstd (qse_size_t xtnsize) static void fini_xtn (qse_awk_t* awk) { - xtn_t* xtn; - xtn = (xtn_t*) QSE_XTN (awk); - - if (xtn->opt.moddir.ptr) - QSE_MMGR_FREE (awk->mmgr, xtn->opt.moddir.ptr); - - qse_rbt_fini (&xtn->modtab); + /* nothing to do */ } static void clear_xtn (qse_awk_t* awk) { - xtn_t* xtn; - xtn = (xtn_t*) QSE_XTN (awk); - qse_rbt_clear (&xtn->modtab); + /* nothing to do */ } qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize) @@ -380,6 +442,9 @@ qse_awk_t* qse_awk_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize) prm.math.log10 = custom_awk_log10; prm.math.exp = custom_awk_exp; prm.math.sqrt = custom_awk_sqrt; + prm.modopen = custom_awk_modopen; + prm.modclose = custom_awk_modclose; + prm.modsym = custom_awk_modsym; /* create an object */ awk = qse_awk_open (mmgr, QSE_SIZEOF(xtn_t) + xtnsize, &prm); @@ -396,19 +461,6 @@ 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), 1) <= -1) - { - qse_awk_close (awk); - return QSE_NULL; - } - qse_rbt_setmancbs ( - &xtn->modtab, - qse_getrbtmancbs(QSE_RBT_MANCBS_INLINE_COPIERS) - ); - xtn->ecb.close = fini_xtn; xtn->ecb.clear = clear_xtn; qse_awk_pushecb (awk, &xtn->ecb); @@ -421,65 +473,6 @@ void* qse_awk_getxtnstd (qse_awk_t* awk) return (void*)((xtn_t*)QSE_XTN(awk) + 1); } -int qse_awk_getoptstd (qse_awk_t* awk, qse_awk_optstd_t id, void* value) -{ - xtn_t* xtn; - - xtn = (xtn_t*) QSE_XTN (awk); - - switch (id) - { - case QSE_AWK_MODDIR: - { - *(const qse_char_t**)value = xtn->opt.moddir.ptr; - return 0; - } - } - - qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); - return -1; -} - -int qse_awk_setoptstd (qse_awk_t* awk, qse_awk_optstd_t id, const void* value) -{ - xtn_t* xtn; - - xtn = (xtn_t*) QSE_XTN (awk); - - switch (id) - { - case QSE_AWK_MODDIR: - { - qse_xstr_t tmp; - - if (value) - { - tmp.ptr = qse_strdup (value, awk->mmgr); - if (tmp.ptr == QSE_NULL) - { - qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); - return -1; - } - tmp.len = qse_strlen (tmp.ptr); - } - else - { - tmp.ptr = QSE_NULL; - tmp.len = 0; - } - - if (xtn->opt.moddir.ptr) - QSE_MMGR_FREE (awk->mmgr, xtn->opt.moddir.ptr); - - xtn->opt.moddir = tmp; - return 0; - } - } - - qse_awk_seterrnum (awk, QSE_AWK_EINVAL, QSE_NULL); - return -1; -} - static qse_sio_t* open_sio (qse_awk_t* awk, const qse_char_t* file, int flags) { qse_sio_t* sio; @@ -1605,6 +1598,7 @@ static qse_ssize_t awk_rio_console ( static void fini_rxtn (qse_awk_rtx_t* rtx) { rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); + /*xtn_t* xtn = (xtn_t*) QSE_XTN (rtx->awk);*/ if (rxtn->cmgrtab_inited) { @@ -2550,9 +2544,10 @@ static int add_functions (qse_awk_t* awk) return 0; } +#if 0 static int query_module ( - qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_info_t* info) + qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym) { const qse_char_t* dc; xtn_t* xtn; @@ -2589,7 +2584,9 @@ static int query_module ( } else { - qse_mchar_t* mod; + qse_mchar_t* modpath; + qse_awk_modstd_load_t load; + #if defined(QSE_CHAR_IS_MCHAR) qse_mcstr_t tmp[5] = { @@ -2629,18 +2626,18 @@ static int query_module ( tmp[3].len = namelen; #if defined(QSE_CHAR_IS_MCHAR) - mod = qse_mbsxadup (tmp, QSE_NULL, awk->mmgr); + modpath = qse_mbsxadup (tmp, QSE_NULL, awk->mmgr); #else - mod = qse_wcsnatombsdup (tmp, QSE_NULL, awk->mmgr); + modpath = qse_wcsnatombsdup (tmp, QSE_NULL, awk->mmgr); #endif - if (!mod) + if (!modpath) { qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); return -1; } - md.dh = lt_dlopenext (mod); - QSE_MMGR_FREE (awk->mmgr, mod); + md.dh = lt_dlopenext (modpath); + QSE_MMGR_FREE (awk->mmgr, modpath); if (!md.dh) { ea.ptr = name; @@ -2649,21 +2646,23 @@ static int query_module ( return -1; } - md.query = lt_dlsym (md.dh, QSE_MT("query")); - if (!md.query) + load = lt_dlsym (md.dh, QSE_MT("load")); + if (!load) { lt_dlclose (md.dh); - ea.ptr = QSE_MT("query"); - ea.len = 5; + ea.ptr = QSE_T("load"); + ea.len = 4; qse_awk_seterror (awk, QSE_AWK_ENOENT, &ea, QSE_NULL); return -1; } -/* - md.init = lt_dlsym (md.dh, QSE_MT("init")); - md.fini = lt_dlsym (md.dh, QSE_MT("fini")); -*/ + if (load (&md.modstd, awk) <= -1) + { + lt_dlclose (md.dh); + return -1; + } + if (qse_rbt_insert (&xtn->modtab, (void*)name, namelen, &md, QSE_SIZEOF(md)) == QSE_NULL) { qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); @@ -2672,15 +2671,9 @@ static int query_module ( } } - return md.query (awk, dc + 2, info); + return md.modstd.query (&md.modstd, awk, dc + 2, sym); #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) -{ -} +#endif diff --git a/qse/lib/awk/val.c b/qse/lib/awk/val.c index 404f0c9f..762cea56 100644 --- a/qse/lib/awk/val.c +++ b/qse/lib/awk/val.c @@ -582,13 +582,13 @@ qse_awk_val_t* qse_awk_rtx_makerefval ( ((val) >= (qse_awk_val_t*)&awk_int[0] && \ (val) <= (qse_awk_val_t*)&awk_int[QSE_COUNTOF(awk_int)-1])) -qse_bool_t qse_awk_rtx_isstaticval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) +int qse_awk_rtx_isstaticval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) { return IS_STATICVAL(val); } void qse_awk_rtx_freeval ( - qse_awk_rtx_t* rtx, qse_awk_val_t* val, qse_bool_t cache) + qse_awk_rtx_t* rtx, qse_awk_val_t* val, int cache) { if (IS_STATICVAL(val)) return; @@ -710,7 +710,7 @@ void qse_awk_rtx_refdownval (qse_awk_rtx_t* rtx, qse_awk_val_t* val) val->ref--; if (val->ref <= 0) { - qse_awk_rtx_freeval(rtx, val, QSE_TRUE); + qse_awk_rtx_freeval(rtx, val, 1); } } @@ -734,14 +734,14 @@ void qse_awk_rtx_freevalchunk (qse_awk_rtx_t* rtx, qse_awk_val_chunk_t* chunk) } } -qse_bool_t qse_awk_rtx_valtobool (qse_awk_rtx_t* run, const qse_awk_val_t* val) +int qse_awk_rtx_valtobool (qse_awk_rtx_t* run, const qse_awk_val_t* val) { - if (val == QSE_NULL) return QSE_FALSE; + if (val == QSE_NULL) return 0; switch (val->type) { case QSE_AWK_VAL_NIL: - return QSE_FALSE; + return 0; case QSE_AWK_VAL_INT: return ((qse_awk_val_int_t*)val)->val != 0; case QSE_AWK_VAL_FLT: @@ -751,15 +751,15 @@ qse_bool_t qse_awk_rtx_valtobool (qse_awk_rtx_t* run, const qse_awk_val_t* val) case QSE_AWK_VAL_REX: /* TODO: is this correct? */ return ((qse_awk_val_rex_t*)val)->len > 0; case QSE_AWK_VAL_MAP: - return QSE_FALSE; /* TODO: is this correct? */ + return 0; /* TODO: is this correct? */ case QSE_AWK_VAL_REF: - return QSE_FALSE; /* TODO: is this correct? */ + return 0; /* TODO: is this correct? */ } QSE_ASSERTX ( !"should never happen - invalid value type", "the type of a value should be one of QSE_AWK_VAL_XXX's defined in awk.h"); - return QSE_FALSE; + return 0; } static int str_to_str ( diff --git a/qse/lib/awk/val.h b/qse/lib/awk/val.h index 60d1f268..800ead78 100644 --- a/qse/lib/awk/val.h +++ b/qse/lib/awk/val.h @@ -57,7 +57,7 @@ extern "C" { void qse_awk_rtx_freeval ( qse_awk_rtx_t* rtx, qse_awk_val_t* val, - qse_bool_t cache + int cache ); void qse_awk_rtx_freevalchunk ( diff --git a/qse/lib/cmn/rbt.c b/qse/lib/cmn/rbt.c index c59d809c..176b0726 100644 --- a/qse/lib/cmn/rbt.c +++ b/qse/lib/cmn/rbt.c @@ -561,6 +561,7 @@ static pair_t* insert ( } rbt->root->color = QSE_RBT_BLACK; + rbt->size++; return x_new; } @@ -680,6 +681,7 @@ pair_t* qse_rbt_cbsert ( } rbt->root->color = QSE_RBT_BLACK; + rbt->size++; return x_new; } diff --git a/qse/mod/awk/Makefile.am b/qse/mod/awk/Makefile.am index 44c1126e..dd575177 100644 --- a/qse/mod/awk/Makefile.am +++ b/qse/mod/awk/Makefile.am @@ -6,8 +6,12 @@ AM_CPPFLAGS = \ -I$(includedir) moddir = $(libdir)/qseawk -mod_LTLIBRARIES = libsys.la +mod_LTLIBRARIES = libsys.la libuci.la libsys_la_SOURCES = sys.c libsys_la_LDFLAGS = -L$(abs_builddir)/../../lib/cmn -L$(abs_builddir)/../../lib/awk -L$(libdir) -version-info 1:0:0 -no-undefined libsys_la_LIBADD = -lqseawk -lqsecmn + +libuci_la_SOURCES = uci.c +libuci_la_LDFLAGS = -L$(abs_builddir)/../../lib/cmn -L$(abs_builddir)/../../lib/awk -L$(libdir) -version-info 1:0:0 -no-undefined +libuci_la_LIBADD = -lqseawk -lqsecmn diff --git a/qse/mod/awk/sys.c b/qse/mod/awk/sys.c index 9afd9801..e2e7a25b 100644 --- a/qse/mod/awk/sys.c +++ b/qse/mod/awk/sys.c @@ -1,4 +1,4 @@ -#include +#include #include #if defined(_WIN32) @@ -13,10 +13,37 @@ # include #else # include +# include # include #endif -static int fnc_sleep (qse_awk_rtx_t* run, const qse_cstr_t* fnm) +static int fnc_fork (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm) +{ +#if defined(_WIN32) + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOIMPL, QSE_NULL); + return -1; + +#elif defined(__OS2__) + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOIMPL, QSE_NULL); + return -1; + +#elif defined(__DOS__) + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOIMPL, QSE_NULL); + return -1; + +#else + pid_t pid; + qse_awk_val_t* r; + + pid = fork (); + r = qse_awk_rtx_makeintval (rtx, pid); + if (r == QSE_NULL) return -1; + qse_awk_rtx_setretval (rtx, r); + return 0; +#endif +} + +static int fnc_wait (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm) { qse_size_t nargs; qse_awk_val_t* a0; @@ -25,12 +52,55 @@ static int fnc_sleep (qse_awk_rtx_t* run, const qse_cstr_t* fnm) qse_awk_val_t* r; int n; - nargs = qse_awk_rtx_getnargs (run); + nargs = qse_awk_rtx_getnargs (rtx); QSE_ASSERT (nargs == 1); - a0 = qse_awk_rtx_getarg (run, 0); +/* TODO: handel more parameters */ - n = qse_awk_rtx_valtonum (run, a0, &lv, &rv); + a0 = qse_awk_rtx_getarg (rtx, 0); + + n = qse_awk_rtx_valtonum (rtx, a0, &lv, &rv); + if (n == -1) return -1; + if (n == 1) lv = (qse_long_t)rv; + +#if defined(_WIN32) + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOIMPL, QSE_NULL); + return -1; + +#elif defined(__OS2__) + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOIMPL, QSE_NULL); + return -1; + +#elif defined(__DOS__) + qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOIMPL, QSE_NULL); + return -1; + +#else + n = waitpid (lv, QSE_NULL, 0); +#endif + + r = qse_awk_rtx_makeintval (rtx, n); + if (r == QSE_NULL) return -1; + + qse_awk_rtx_setretval (rtx, r); + return 0; +} + +static int fnc_sleep (qse_awk_rtx_t* rtx, const qse_cstr_t* fnm) +{ + qse_size_t nargs; + qse_awk_val_t* a0; + qse_long_t lv; + qse_flt_t rv; + qse_awk_val_t* r; + int n; + + nargs = qse_awk_rtx_getnargs (rtx); + QSE_ASSERT (nargs == 1); + + a0 = qse_awk_rtx_getarg (rtx, 0); + + n = qse_awk_rtx_valtonum (rtx, a0, &lv, &rv); if (n == -1) return -1; if (n == 1) lv = (qse_long_t)rv; @@ -40,27 +110,55 @@ static int fnc_sleep (qse_awk_rtx_t* run, const qse_cstr_t* fnm) #elif defined(__OS2__) DosSleep ((ULONG)(lv * 1000)); n = 0; +#elif defined(__DOS__) + n = sleep (lv); #else n = sleep (lv); #endif - r = qse_awk_rtx_makeintval (run, n); + r = qse_awk_rtx_makeintval (rtx, n); if (r == QSE_NULL) return -1; - qse_awk_rtx_setretval (run, r); + qse_awk_rtx_setretval (rtx, r); return 0; } -int query (qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_info_t* info) +static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_sym_t* sym) { qse_cstr_t ea; - if (qse_strcmp (name, QSE_T("sleep")) == 0) +/* TODO: tabulation and binary search or something better */ + + if (qse_strcmp (name, QSE_T("fork")) == 0) { - info->type = QSE_AWK_MOD_FNC; - info->u.f.arg.min = 1; - info->u.f.arg.max = 1; - info->u.f.impl = fnc_sleep; + sym->type = QSE_AWK_MOD_FNC; + sym->u.f.arg.min = 0; + sym->u.f.arg.max = 0; + sym->u.f.impl = fnc_fork; + return 0; + } + else if (qse_strcmp (name, QSE_T("wait")) == 0) + { + sym->type = QSE_AWK_MOD_FNC; + sym->u.f.arg.min = 1; /* TODO: accept more parameters.. */ + sym->u.f.arg.max = 1; + sym->u.f.impl = fnc_wait; + return 0; + } +/* + else if (qse_strcmp (name, QSE_T("WNOHANG")) == 0) + { + sym->type = QSE_AWK_MOD_INTCON; + sym->u.c.ivalue = WNOHANG; + return 0; + } +*/ + else if (qse_strcmp (name, QSE_T("sleep")) == 0) + { + sym->type = QSE_AWK_MOD_FNC; + sym->u.f.arg.min = 1; + sym->u.f.arg.max = 1; + sym->u.f.impl = fnc_sleep; return 0; } @@ -69,3 +167,38 @@ int query (qse_awk_t* awk, const qse_char_t* name, qse_awk_mod_info_t* info) qse_awk_seterror (awk, QSE_AWK_ENOENT, &ea, QSE_NULL); return -1; } + +/* TODO: proper resource management */ + +int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx) +{ + return 0; +} + +void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx) +{ + /* TODO: + for (each pid for rtx) kill (pid, SIGKILL); + for (each pid for rtx) waitpid (pid, QSE_NULL, 0); + */ +} + +static void unload (qse_awk_mod_t* mod, qse_awk_t* awk) +{ + /* TODO: anything */ +} + +int load (qse_awk_mod_t* mod, qse_awk_t* awk) +{ + mod->query = query; + mod->unload = unload; + + mod->init = init; + mod->fini = fini; + /* + mod->ctx... + */ + + return 0; +} +