Partially fixed the critical bug mentioned in the previous revision.

- runcbs->on_enter() is introduced and called when all 
  globals variables are ready.
- changed runcbs->on_start() to return an integer
- run_main() is still under reconstruction. currently it 
  only supports the BEGIN/pattern action/END block exection.
This commit is contained in:
hyung-hwan 2009-01-23 04:40:57 +00:00
parent 5686bb8ac7
commit 8150f4843d
10 changed files with 543 additions and 145 deletions

View File

@ -232,7 +232,7 @@ public:
protected: protected:
void onRunStart (Run& run) bool onRunStart (Run& run)
{ {
if (verbose) qse_printf (QSE_T("*** awk run started ***\n")); if (verbose) qse_printf (QSE_T("*** awk run started ***\n"));
@ -246,6 +246,8 @@ protected:
sa_int.sa_flags = 0; sa_int.sa_flags = 0;
sigaction (SIGINT, &sa_int, NULL); sigaction (SIGINT, &sa_int, NULL);
#endif #endif
return true;
} }
void onRunEnd (Run& run) void onRunEnd (Run& run)
@ -271,6 +273,11 @@ protected:
if (verbose) qse_printf (QSE_T("*** awk run ended ***\n")); if (verbose) qse_printf (QSE_T("*** awk run ended ***\n"));
} }
bool onRunEnter (Run& run)
{
return true;
}
void onRunReturn (Run& run, const Argument& ret) void onRunReturn (Run& run, const Argument& ret)
{ {
if (verbose) if (verbose)

View File

@ -111,32 +111,13 @@ static void unset_intr_run (void)
#endif #endif
} }
static void on_run_start (qse_awk_run_t* run, void* data) static int on_run_start (qse_awk_run_t* run, void* data)
{ {
struct argout_t* ao = (struct argout_t*)data;
app_run = run; app_run = run;
set_intr_run (); set_intr_run ();
if (ao->fs != QSE_NULL)
{
qse_awk_val_t* fs;
qse_printf (QSE_T("1111111111111111111\n"));
fs = qse_awk_makestrval0 (run, ao->fs);
qse_printf (QSE_T("2222222222222222222\n"));
//if (fs == QSE_NULL) return -1;
qse_awk_refupval (run, fs);
qse_printf (QSE_T("3333333333333333333\n"));
qse_awk_setglobal (run, QSE_AWK_GLOBAL_FS, fs);
qse_printf (QSE_T("4444444444444444444\n"));
qse_awk_refdownval (run, fs);
qse_printf (QSE_T("555555555555555555555555\n"));
}
dprint (QSE_T("[AWK ABOUT TO START]\n")); dprint (QSE_T("[AWK ABOUT TO START]\n"));
return 0;
//return 0;
} }
static qse_map_walk_t print_awk_value ( static qse_map_walk_t print_awk_value (
@ -163,13 +144,33 @@ static qse_map_walk_t print_awk_value (
} }
static void on_run_statement ( static void on_run_statement (
qse_awk_run_t* run, qse_size_t line, void* custom) qse_awk_run_t* run, qse_size_t line, void* data)
{ {
/*dprint (L"running %d\n", (int)line);*/ /*dprint (L"running %d\n", (int)line);*/
} }
static void on_run_return ( static int on_run_enter (qse_awk_run_t* run, void* data)
qse_awk_run_t* run, qse_awk_val_t* ret, void* custom) {
struct argout_t* ao = (struct argout_t*)data;
if (ao->fs != QSE_NULL)
{
qse_awk_val_t* fs;
fs = qse_awk_makestrval0 (run, ao->fs);
if (fs == QSE_NULL) return -1;
qse_awk_refupval (run, fs);
qse_awk_setglobal (run, QSE_AWK_GLOBAL_FS, fs);
qse_awk_refdownval (run, fs);
}
return 0;
}
static void on_run_exit (
qse_awk_run_t* run, qse_awk_val_t* ret, void* data)
{ {
qse_size_t len; qse_size_t len;
qse_char_t* str; qse_char_t* str;
@ -575,12 +576,9 @@ static int awk_main (int argc, qse_char_t* argv[])
qse_awk_runcbs_t runcbs; qse_awk_runcbs_t runcbs;
int i, file_count = 0; int i;
const qse_char_t* mfn = QSE_NULL;
int mode = 0;
int runarg_count = 0; int runarg_count = 0;
qse_awk_runarg_t runarg[128]; qse_cstr_t runarg[128];
int deparse = 0;
struct argout_t ao; struct argout_t ao;
int ret = 0; int ret = 0;
@ -615,8 +613,9 @@ static int awk_main (int argc, qse_char_t* argv[])
} }
runcbs.on_start = on_run_start; runcbs.on_start = on_run_start;
runcbs.on_enter = on_run_enter;
runcbs.on_statement = on_run_statement; runcbs.on_statement = on_run_statement;
runcbs.on_return = on_run_return; runcbs.on_exit = on_run_exit;
runcbs.on_end = on_run_end; runcbs.on_end = on_run_end;
runcbs.data = &ao; runcbs.data = &ao;

View File

@ -1055,9 +1055,10 @@ protected:
/*@}*/ /*@}*/
// run-time callbacks // run-time callbacks
virtual void onRunStart (Run& run); virtual bool onRunStart (Run& run);
virtual void onRunEnd (Run& run); virtual void onRunEnd (Run& run);
virtual void onRunReturn (Run& run, const Argument& ret); virtual bool onRunEnter (Run& run);
virtual void onRunExit (Run& run, const Argument& ret);
virtual void onRunStatement (Run& run, size_t line); virtual void onRunStatement (Run& run, size_t line);
// primitive handlers // primitive handlers
@ -1089,9 +1090,10 @@ protected:
run_t* run, const char_t* name, size_t len); run_t* run, const char_t* name, size_t len);
static void freeFunctionMapValue (map_t* map, void* dptr, size_t dlen); static void freeFunctionMapValue (map_t* map, void* dptr, size_t dlen);
static void onRunStart (run_t* run, void* data); static int onRunStart (run_t* run, void* data);
static void onRunEnd (run_t* run, int errnum, void* data); static void onRunEnd (run_t* run, int errnum, void* data);
static void onRunReturn (run_t* run, val_t* ret, void* data); static int onRunEnter (run_t* run, void* data);
static void onRunExit (run_t* run, val_t* ret, void* data);
static void onRunStatement (run_t* run, size_t line, void* data); static void onRunStatement (run_t* run, size_t line, void* data);
static void* allocMem (void* data, size_t n); static void* allocMem (void* data, size_t n);
@ -1122,7 +1124,7 @@ private:
Awk (const Awk&); Awk (const Awk&);
Awk& operator= (const Awk&); Awk& operator= (const Awk&);
void triggerOnRunStart (Run& run); bool triggerOnRunStart (Run& run);
mmgr_t mmgr; mmgr_t mmgr;
ccls_t ccls; ccls_t ccls;

View File

@ -42,7 +42,6 @@ typedef struct qse_awk_prmfns_t qse_awk_prmfns_t;
typedef struct qse_awk_srcios_t qse_awk_srcios_t; typedef struct qse_awk_srcios_t qse_awk_srcios_t;
typedef struct qse_awk_runios_t qse_awk_runios_t; typedef struct qse_awk_runios_t qse_awk_runios_t;
typedef struct qse_awk_runcbs_t qse_awk_runcbs_t; typedef struct qse_awk_runcbs_t qse_awk_runcbs_t;
typedef struct qse_awk_runarg_t qse_awk_runarg_t;
typedef struct qse_awk_rexfns_t qse_awk_rexfns_t; typedef struct qse_awk_rexfns_t qse_awk_rexfns_t;
typedef qse_real_t (*qse_awk_pow_t) (void* data, qse_real_t x, qse_real_t y); typedef qse_real_t (*qse_awk_pow_t) (void* data, qse_real_t x, qse_real_t y);
@ -109,13 +108,16 @@ struct qse_awk_runios_t
struct qse_awk_runcbs_t struct qse_awk_runcbs_t
{ {
void (*on_start) ( int (*on_start) (
qse_awk_run_t* run, void* data);
int (*on_enter) (
qse_awk_run_t* run, void* data); qse_awk_run_t* run, void* data);
void (*on_statement) ( void (*on_statement) (
qse_awk_run_t* run, qse_size_t line, void* data); qse_awk_run_t* run, qse_size_t line, void* data);
void (*on_return) ( void (*on_exit) (
qse_awk_run_t* run, qse_awk_val_t* ret, void* data); qse_awk_run_t* run, qse_awk_val_t* ret, void* data);
void (*on_end) ( void (*on_end) (
@ -124,12 +126,6 @@ struct qse_awk_runcbs_t
void* data; void* data;
}; };
struct qse_awk_runarg_t
{
qse_char_t* ptr;
qse_size_t len;
};
struct qse_awk_rexfns_t struct qse_awk_rexfns_t
{ {
void* (*build) ( void* (*build) (
@ -888,7 +884,7 @@ int qse_awk_runsimple (
int qse_awk_run ( int qse_awk_run (
qse_awk_t* awk, const qse_char_t* main, qse_awk_t* awk, const qse_char_t* main,
qse_awk_runios_t* runios, qse_awk_runcbs_t* runcbs, qse_awk_runios_t* runios, qse_awk_runcbs_t* runcbs,
qse_awk_runarg_t* runarg, void* data); const qse_cstr_t* runarg, void* data);
void qse_awk_stop (qse_awk_run_t* run); void qse_awk_stop (qse_awk_run_t* run);
void qse_awk_stopall (qse_awk_t* awk); void qse_awk_stopall (qse_awk_t* awk);

View File

@ -1335,7 +1335,7 @@ int Awk::run (const char_t* main, const char_t** args, size_t nargs)
size_t i; size_t i;
qse_awk_runios_t runios; qse_awk_runios_t runios;
qse_awk_runcbs_t runcbs; qse_awk_runcbs_t runcbs;
qse_awk_runarg_t* runarg = QSE_NULL; qse_xstr_t* runarg = QSE_NULL;
// make sure that the run field is set in Awk::onRunStart. // make sure that the run field is set in Awk::onRunStart.
Run runctx (this); Run runctx (this);
@ -1350,15 +1350,16 @@ int Awk::run (const char_t* main, const char_t** args, size_t nargs)
if (runCallback) if (runCallback)
{ {
runcbs.on_end = onRunEnd; runcbs.on_end = onRunEnd;
runcbs.on_return = onRunReturn; runcbs.on_enter = onRunEnter;
runcbs.on_statement = onRunStatement; runcbs.on_statement = onRunStatement;
runcbs.on_exit = onRunExit;
} }
runcbs.data = &runctx; runcbs.data = &runctx;
if (nargs > 0) if (nargs > 0)
{ {
runarg = (qse_awk_runarg_t*) qse_awk_alloc ( runarg = (qse_xstr_t*) qse_awk_alloc (
awk, QSE_SIZEOF(qse_awk_runarg_t)*(nargs+1)); awk, QSE_SIZEOF(qse_xstr_t)*(nargs+1));
if (runarg == QSE_NULL) if (runarg == QSE_NULL)
{ {
@ -1383,7 +1384,10 @@ int Awk::run (const char_t* main, const char_t** args, size_t nargs)
runarg[i].len = 0; runarg[i].len = 0;
} }
int n = qse_awk_run (awk, main, &runios, &runcbs, runarg, &runctx); int n = qse_awk_run (
awk, main, &runios, &runcbs,
(qse_cstr_t*)runarg, &runctx
);
if (n == -1) retrieveError (); if (n == -1) retrieveError ();
if (runarg != QSE_NULL) if (runarg != QSE_NULL)
@ -1543,20 +1547,27 @@ void Awk::disableRunCallback ()
runCallback = false; runCallback = false;
} }
void Awk::triggerOnRunStart (Run& run) bool Awk::triggerOnRunStart (Run& run)
{ {
if (runCallback) onRunStart (run); if (runCallback) return onRunStart (run);
return true;
} }
void Awk::onRunStart (Run& run) bool Awk::onRunStart (Run& run)
{ {
return true;
} }
void Awk::onRunEnd (Run& run) void Awk::onRunEnd (Run& run)
{ {
} }
void Awk::onRunReturn (Run& run, const Argument& ret) bool Awk::onRunEnter (Run& run)
{
return true;
}
void Awk::onRunExit (Run& run, const Argument& ret)
{ {
} }
@ -1710,7 +1721,7 @@ void Awk::freeFunctionMapValue (map_t* map, void* dptr, size_t dlen)
qse_awk_free (awk->awk, dptr); qse_awk_free (awk->awk, dptr);
} }
void Awk::onRunStart (run_t* run, void* data) int Awk::onRunStart (run_t* run, void* data)
{ {
Run* r = (Run*)data; Run* r = (Run*)data;
@ -1723,7 +1734,7 @@ void Awk::onRunStart (run_t* run, void* data)
r->run = run; r->run = run;
r->callbackFailed = false; r->callbackFailed = false;
r->awk->triggerOnRunStart (*r); return r->awk->triggerOnRunStart(*r)? 0: -1;
} }
void Awk::onRunEnd (run_t* run, int errnum, void* data) void Awk::onRunEnd (run_t* run, int errnum, void* data)
@ -1738,7 +1749,14 @@ void Awk::onRunEnd (run_t* run, int errnum, void* data)
r->awk->onRunEnd (*r); r->awk->onRunEnd (*r);
} }
void Awk::onRunReturn (run_t* run, val_t* ret, void* data) int Awk::onRunEnter (run_t* run, void* data)
{
Run* r = (Run*)data;
if (r->callbackFailed) return false;
return r->awk->onRunEnter(*r)? 0: -1;
}
void Awk::onRunExit (run_t* run, val_t* ret, void* data)
{ {
Run* r = (Run*)data; Run* r = (Run*)data;
if (r->callbackFailed) return; if (r->callbackFailed) return;
@ -1750,7 +1768,7 @@ void Awk::onRunReturn (run_t* run, val_t* ret, void* data)
} }
else else
{ {
r->awk->onRunReturn (*r, x); r->awk->onRunExit (*r, x);
} }
} }

View File

@ -337,20 +337,8 @@ qse_ccls_t* qse_awk_getccls (qse_awk_t* awk)
void qse_awk_setccls (qse_awk_t* awk, qse_ccls_t* ccls) void qse_awk_setccls (qse_awk_t* awk, qse_ccls_t* ccls)
{ {
QSE_ASSERT (ccls->is_upper != QSE_NULL); QSE_ASSERT (ccls->is != QSE_NULL);
QSE_ASSERT (ccls->is_lower != QSE_NULL); QSE_ASSERT (ccls->to != QSE_NULL);
QSE_ASSERT (ccls->is_alpha != QSE_NULL);
QSE_ASSERT (ccls->is_digit != QSE_NULL);
QSE_ASSERT (ccls->is_xdigit != QSE_NULL);
QSE_ASSERT (ccls->is_alnum != QSE_NULL);
QSE_ASSERT (ccls->is_space != QSE_NULL);
QSE_ASSERT (ccls->is_print != QSE_NULL);
QSE_ASSERT (ccls->is_graph != QSE_NULL);
QSE_ASSERT (ccls->is_cntrl != QSE_NULL);
QSE_ASSERT (ccls->is_punct != QSE_NULL);
QSE_ASSERT (ccls->to_upper != QSE_NULL);
QSE_ASSERT (ccls->to_lower != QSE_NULL);
awk->ccls = ccls; awk->ccls = ccls;
} }
@ -363,7 +351,6 @@ void qse_awk_setprmfns (qse_awk_t* awk, qse_awk_prmfns_t* prmfns)
{ {
QSE_ASSERT (prmfns->pow != QSE_NULL); QSE_ASSERT (prmfns->pow != QSE_NULL);
QSE_ASSERT (prmfns->sprintf != QSE_NULL); QSE_ASSERT (prmfns->sprintf != QSE_NULL);
QSE_ASSERT (prmfns->dprintf != QSE_NULL);
awk->prmfns = prmfns; awk->prmfns = prmfns;
} }

View File

@ -463,7 +463,7 @@ const qse_char_t* qse_awk_getglobalname (
return gtab[idx].name; return gtab[idx].name;
*/ */
QSE_ASSERT (idx < QSE_LDA_SIZE(&awk->parse.globals)); QSE_ASSERT (idx < QSE_LDA_SIZE(awk->parse.globals));
*len = QSE_LDA_DLEN(awk->parse.globals,idx); *len = QSE_LDA_DLEN(awk->parse.globals,idx);
return QSE_LDA_DPTR(awk->parse.globals,idx); return QSE_LDA_DPTR(awk->parse.globals,idx);
@ -580,7 +580,7 @@ static int parse (qse_awk_t* awk)
} }
} }
QSE_ASSERT (awk->tree.nglobals == awk->parse.globals.size); QSE_ASSERT (awk->tree.nglobals == QSE_LDA_SIZE(awk->parse.globals));
if (awk->src.ios.out != QSE_NULL) if (awk->src.ios.out != QSE_NULL)
{ {
@ -628,7 +628,7 @@ static qse_awk_t* parse_progunit (qse_awk_t* awk)
if (get_token(awk) == -1) return QSE_NULL; if (get_token(awk) == -1) return QSE_NULL;
QSE_ASSERT (awk->tree.nglobals == QSE_LDA_SIZE(&awk->parse.globals)); QSE_ASSERT (awk->tree.nglobals == QSE_LDA_SIZE(awk->parse.globals));
nglobals = awk->tree.nglobals; nglobals = awk->tree.nglobals;
if (collect_globals (awk) == QSE_NULL) if (collect_globals (awk) == QSE_NULL)
{ {
@ -912,7 +912,7 @@ static qse_awk_nde_t* parse_function (qse_awk_t* awk)
} }
/* make sure that parameter table is empty */ /* make sure that parameter table is empty */
QSE_ASSERT (QSE_LDA_SIZE(&awk->parse.params) == 0); QSE_ASSERT (QSE_LDA_SIZE(awk->parse.params) == 0);
/* read parameter list */ /* read parameter list */
if (MATCH(awk,TOKEN_RPAREN)) if (MATCH(awk,TOKEN_RPAREN))
@ -5868,7 +5868,7 @@ static qse_map_walk_t deparse_func (qse_map_t* map, qse_map_pair_t* pair, void*
qse_size_t i, n; qse_size_t i, n;
qse_cstr_t kw; qse_cstr_t kw;
QSE_ASSERT (qse_strxncmp (QSE_PAIR_KEYPTR(pair), QSE_PAIR_KEYLEN(pair), afn->name.ptr, afn->name.len) == 0); QSE_ASSERT (qse_strxncmp (QSE_MAP_KPTR(pair), QSE_MAP_KLEN(pair), afn->name.ptr, afn->name.len) == 0);
#define PUT_C(x,c) \ #define PUT_C(x,c) \
if (put_char(x->awk,c)==-1) { \ if (put_char(x->awk,c)==-1) { \

View File

@ -77,14 +77,9 @@ static int init_run (
qse_awk_runios_t* runios, void* data); qse_awk_runios_t* runios, void* data);
static void deinit_run (qse_awk_run_t* run); static void deinit_run (qse_awk_run_t* run);
static int build_runarg (
qse_awk_run_t* run, qse_awk_runarg_t* runarg, qse_size_t* nargs);
static void cleanup_globals (qse_awk_run_t* run);
static int set_globals_to_default (qse_awk_run_t* run);
static int run_main ( static int run_main (
qse_awk_run_t* run, const qse_char_t* main, qse_awk_run_t* run, const qse_char_t* main,
qse_awk_runarg_t* runarg); const qse_cstr_t* runarg);
static int run_pattern_blocks (qse_awk_run_t* run); static int run_pattern_blocks (qse_awk_run_t* run);
static int run_pattern_block_chain ( static int run_pattern_block_chain (
@ -225,7 +220,6 @@ static int __raw_push (qse_awk_run_t* run, void* val);
QSE_ASSERT ((run)->stack_top > (run)->stack_base); \ QSE_ASSERT ((run)->stack_top > (run)->stack_base); \
(run)->stack_top--; \ (run)->stack_top--; \
} while (0) } while (0)
static void __raw_pop_times (qse_awk_run_t* run, qse_size_t times);
static int read_record (qse_awk_run_t* run); static int read_record (qse_awk_run_t* run);
static int shorten_record (qse_awk_run_t* run, qse_size_t nflds); static int shorten_record (qse_awk_run_t* run, qse_size_t nflds);
@ -249,13 +243,13 @@ qse_awk_val_t* qse_awk_getarg (qse_awk_run_t* run, qse_size_t idx)
qse_awk_val_t* qse_awk_getglobal (qse_awk_run_t* run, int id) qse_awk_val_t* qse_awk_getglobal (qse_awk_run_t* run, int id)
{ {
QSE_ASSERT (id >= 0 && id < (int)qse_awk_tab_getsize(&run->awk->parse.globals)); QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(run->awk->parse.globals));
return STACK_GLOBAL (run, id); return STACK_GLOBAL (run, id);
} }
int qse_awk_setglobal (qse_awk_run_t* run, int id, qse_awk_val_t* val) int qse_awk_setglobal (qse_awk_run_t* run, int id, qse_awk_val_t* val)
{ {
QSE_ASSERT (id >= 0 && id < (int)qse_awk_tab_getsize(&run->awk->parse.globals)); QSE_ASSERT (id >= 0 && id < (int)QSE_LDA_SIZE(run->awk->parse.globals));
return set_global (run, (qse_size_t)id, QSE_NULL, val); return set_global (run, (qse_size_t)id, QSE_NULL, val);
} }
@ -265,15 +259,12 @@ static int set_global (
{ {
qse_awk_val_t* old; qse_awk_val_t* old;
qse_printf (QSE_T("################\n"));
old = STACK_GLOBAL (run, idx); old = STACK_GLOBAL (run, idx);
qse_printf (QSE_T("@@@@@@@@@@@@@@@@@@@\n"));
if (old->type == QSE_AWK_VAL_MAP) if (old->type == QSE_AWK_VAL_MAP)
{ {
/* once a variable becomes a map, /* once a variable becomes a map,
* it cannot be changed to a scalar variable */ * it cannot be changed to a scalar variable */
qse_printf (QSE_T("%%%%%%%%%%%%%%%%%%%%\n"));
if (var != QSE_NULL) if (var != QSE_NULL)
{ {
/* global variable */ /* global variable */
@ -350,16 +341,13 @@ qse_printf (QSE_T("%%%%%%%%%%%%%%%%%%%%\n"));
qse_char_t* fs_ptr; qse_char_t* fs_ptr;
qse_size_t fs_len; qse_size_t fs_len;
qse_printf (QSE_T("aaaaaaaaaaaa\n"));
if (val->type == QSE_AWK_VAL_STR) if (val->type == QSE_AWK_VAL_STR)
{ {
qse_printf (QSE_T("bbbbbbbbbbbbb\n"));
fs_ptr = ((qse_awk_val_str_t*)val)->ptr; fs_ptr = ((qse_awk_val_str_t*)val)->ptr;
fs_len = ((qse_awk_val_str_t*)val)->len; fs_len = ((qse_awk_val_str_t*)val)->len;
} }
else else
{ {
qse_printf (QSE_T("ccccccccccc\n"));
/* due to the expression evaluation rule, the /* due to the expression evaluation rule, the
* regular expression can not be an assigned value */ * regular expression can not be an assigned value */
QSE_ASSERT (val->type != QSE_AWK_VAL_REX); QSE_ASSERT (val->type != QSE_AWK_VAL_REX);
@ -373,8 +361,6 @@ qse_printf (QSE_T("%%%%%%%%%%%%%%%%%%%%\n"));
{ {
void* rex; void* rex;
qse_printf (QSE_T("dddddddddddddd\n"));
/* compile the regular expression */
/* TODO: use safebuild */ /* TODO: use safebuild */
rex = QSE_AWK_BUILDREX ( rex = QSE_AWK_BUILDREX (
run->awk, fs_ptr, fs_len, &run->errnum); run->awk, fs_ptr, fs_len, &run->errnum);
@ -390,12 +376,9 @@ qse_printf (QSE_T("%%%%%%%%%%%%%%%%%%%%\n"));
QSE_AWK_FREEREX (run->awk, run->global.fs); QSE_AWK_FREEREX (run->awk, run->global.fs);
} }
run->global.fs = rex; run->global.fs = rex;
qse_printf (QSE_T("eeeeeeeeeeeeee\n"));
} }
qse_printf (QSE_T("fffffffffffff\n"));
if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, fs_ptr); if (val->type != QSE_AWK_VAL_STR) QSE_AWK_FREE (run->awk, fs_ptr);
qse_printf (QSE_T("ggggggggggggg\n"));
} }
else if (idx == QSE_AWK_GLOBAL_IGNORECASE) else if (idx == QSE_AWK_GLOBAL_IGNORECASE)
{ {
@ -640,7 +623,7 @@ int qse_awk_run (qse_awk_t* awk,
const qse_char_t* main, const qse_char_t* main,
qse_awk_runios_t* runios, qse_awk_runios_t* runios,
qse_awk_runcbs_t* runcbs, qse_awk_runcbs_t* runcbs,
qse_awk_runarg_t* runarg, const qse_cstr_t* runarg,
void* data) void* data)
{ {
qse_awk_run_t* run; qse_awk_run_t* run;
@ -694,7 +677,8 @@ int qse_awk_run (qse_awk_t* awk,
/* execute the start callback if it exists */ /* execute the start callback if it exists */
if (runcbs != QSE_NULL && runcbs->on_start != QSE_NULL) if (runcbs != QSE_NULL && runcbs->on_start != QSE_NULL)
{ {
runcbs->on_start (run, runcbs->data); n = runcbs->on_start (run, runcbs->data);
if (n <= -1) n = -1;
} }
/* enter the main run loop */ /* enter the main run loop */
@ -1012,9 +996,9 @@ static void deinit_run (qse_awk_run_t* run)
} }
static int build_runarg ( static int build_runarg (
qse_awk_run_t* run, qse_awk_runarg_t* runarg, qse_size_t* nargs) qse_awk_run_t* run, const qse_cstr_t* runarg, qse_size_t* nargs)
{ {
qse_awk_runarg_t* p; const qse_cstr_t* p;
qse_size_t argc; qse_size_t argc;
qse_awk_val_t* v_argc; qse_awk_val_t* v_argc;
qse_awk_val_t* v_argv; qse_awk_val_t* v_argv;
@ -1113,16 +1097,6 @@ static int build_runarg (
return 0; return 0;
} }
static void cleanup_globals (qse_awk_run_t* run)
{
qse_size_t nglobals = run->awk->tree.nglobals;
while (nglobals > 0)
{
--nglobals;
qse_awk_refdownval (run, STACK_GLOBAL(run,nglobals));
STACK_GLOBAL (run, nglobals) = qse_awk_val_nil;
}
}
static int update_fnr (qse_awk_run_t* run, qse_long_t fnr, qse_long_t nr) static int update_fnr (qse_awk_run_t* run, qse_long_t fnr, qse_long_t nr)
{ {
@ -1242,9 +1216,425 @@ static void capture_retval_on_exit (void* arg)
qse_awk_refupval (data->run, data->val); qse_awk_refupval (data->run, data->val);
} }
static int prepare_globals (qse_awk_run_t* run, const qse_cstr_t* runarg)
{
qse_size_t saved_stack_top;
qse_size_t nglobals;
qse_size_t nrunargs;
saved_stack_top = run->stack_top;
nglobals = run->awk->tree.nglobals;
/* initialize all global variables to nil by push nils to the stack */
while (nglobals > 0)
{
--nglobals;
if (__raw_push(run,qse_awk_val_nil) == -1)
{
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
goto oops;
}
}
/* override NF to zero */
if (qse_awk_setglobal (
run, QSE_AWK_GLOBAL_NF, qse_awk_val_zero) == -1) goto oops;
/* override ARGC and ARGV */
if (build_runarg (run, runarg, &nrunargs) == -1) goto oops;
/* return success */
return 0;
oops:
/* restore the stack_top this way instead of calling __raw_pop()
* as many times as successful __raw_push(). it is ok because
* the values pushed so far are qse_awk_val_nils and qse_awk_val_zeros.
*/
run->stack_top = saved_stack_top;
return -1;
}
static void refdown_globals (qse_awk_run_t* run, int pop)
{
qse_size_t nglobals;
nglobals = run->awk->tree.nglobals;
while (nglobals > 0)
{
--nglobals;
qse_awk_refdownval (run, STACK_GLOBAL(run,nglobals));
if (pop) __raw_pop (run);
else STACK_GLOBAL(run,nglobals) = qse_awk_val_nil;
}
}
static int enter_stack_frame (qse_awk_run_t* run)
{
qse_size_t saved_stack_top;
/* remember the current stack top */
saved_stack_top = run->stack_top;
/* push the current stack base */
if (__raw_push(run,(void*)run->stack_base) == -1) goto oops;
/* push the current stack top before push the current stack base */
if (__raw_push(run,(void*)saved_stack_top) == -1) goto oops;
/* secure space for a return value */
if (__raw_push(run,qse_awk_val_nil) == -1) goto oops;
/* secure space for STACK_NARGS */
if (__raw_push(run,qse_awk_val_nil) == -1) goto oops;
/* let the stack top remembered be the base of a new stack frame */
run->stack_base = saved_stack_top;
return 0;
oops:
/* restore the stack top in a cheesy(?) way.
* it is ok to do so as the values pushed are
* nils and binary numbers. */
run->stack_top = saved_stack_top;
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
return -1;
}
static void exit_stack_frame (qse_awk_run_t* run)
{
/* At this point, the current stack frame should have
* the 4 entries pushed in enter_stack_frame(). */
QSE_ASSERT ((run->stack_top-run->stack_base) == 4);
run->stack_top = (qse_size_t)run->stack[run->stack_base+1];
run->stack_base = (qse_size_t)run->stack[run->stack_base+0];
}
static int run_bpae_loop (qse_awk_run_t* run)
{
qse_awk_nde_t* nde;
qse_size_t nargs, i;
qse_awk_val_t* v;
int ret = 0;
/* set nargs to zero */
nargs = 0;
STACK_NARGS(run) = (void*)nargs;
/* call the callback */
if (run->cbs != QSE_NULL && run->cbs->on_enter != QSE_NULL)
{
ret = run->cbs->on_enter (run, run->cbs->data);
if (ret <= -1) ret = -1;
}
/* execute the BEGIN block */
for (nde = run->awk->tree.begin;
ret == 0 && nde != QSE_NULL && run->exit_level < EXIT_GLOBAL;
nde = nde->next)
{
qse_awk_nde_blk_t* blk;
blk = (qse_awk_nde_blk_t*)nde;
QSE_ASSERT (blk->type == QSE_AWK_NDE_BLK);
run->active_block = blk;
run->exit_level = EXIT_NONE;
if (run_block (run, blk) == -1) ret = -1;
}
if (ret == -1 && run->errnum == QSE_AWK_ENOERR)
{
/* an error is returned with no error number set.
* this feature is used by eval_expression to
* abort the evaluation when exit() is executed
* during function evaluation */
ret = 0;
run->errlin = 0;
run->errmsg[0] = QSE_T('\0');
}
/* run pattern block loops */
if (ret == 0 &&
(run->awk->tree.chain != QSE_NULL ||
run->awk->tree.end != QSE_NULL) &&
run->exit_level < EXIT_GLOBAL)
{
if (run_pattern_blocks(run) == -1) ret = -1;
}
if (ret == -1 && run->errnum == QSE_AWK_ENOERR)
{
/* an error is returned with no error number set.
* this feature is used by eval_expression to
* abort the evaluation when exit() is executed
* during function evaluation */
ret = 0;
run->errlin = 0;
run->errmsg[0] = QSE_T('\0');
}
/* execute END blocks. the first END block is executed if the
* program is not explicitly aborted with qse_awk_stop().*/
for (nde = run->awk->tree.end;
ret == 0 && nde != QSE_NULL && run->exit_level < EXIT_ABORT;
nde = nde->next)
{
qse_awk_nde_blk_t* blk;
blk = (qse_awk_nde_blk_t*)nde;
QSE_ASSERT (blk->type == QSE_AWK_NDE_BLK);
run->active_block = blk;
run->exit_level = EXIT_NONE;
if (run_block (run, blk) == -1) ret = -1;
else if (run->exit_level >= EXIT_GLOBAL)
{
/* once exit is called inside one of END blocks,
* subsequent END blocks must not be executed */
break;
}
}
if (ret == -1 && run->errnum == QSE_AWK_ENOERR)
{
/* an error is returned with no error number set.
* this feature is used by eval_expression to
* abort the evaluation when exit() is executed
* during function evaluation */
ret = 0;
run->errlin = 0;
run->errmsg[0] = QSE_T('\0');
}
/* derefrence all arguments. however, there should be no arguments
* pushed to the stack as asserted below. we didn't push any arguments
* for BEGIN/pattern action/END block execution.*/
nargs = (qse_size_t)STACK_NARGS(run);
QSE_ASSERT (nargs == 0);
for (i = 0; i < nargs; i++) qse_awk_refdownval (run, STACK_ARG(run,i));
/* get the return value in the current stack frame */
v = STACK_RETVAL(run);
if (ret == 0)
{
if (run->cbs != QSE_NULL && run->cbs->on_exit != QSE_NULL)
{
run->cbs->on_exit (run, v, run->cbs->data);
}
}
/* end the life of the global return value */
qse_awk_refdownval (run, v);
return ret;
}
static int run_bpae (qse_awk_run_t* run, const qse_cstr_t* runarg)
{
int ret;
/* the stack must be clean when this function
* is invoked */
QSE_ASSERT (run->stack_base == 0);
QSE_ASSERT (run->stack_top == 0);
run->exit_level = EXIT_NONE;
/* prepare global variables with initial primitive values */
ret = prepare_globals (run, runarg);
if (ret == 0)
{
/* adjust global variables a little more */
ret = update_fnr (run, 0, 0);
if (ret == 0) ret = set_globals_to_default(run);
/* run the BEGIN/pattern action/END blocks */
if (ret == 0)
{
ret = enter_stack_frame (run);
if (ret == 0)
{
ret = run_bpae_loop (run);
exit_stack_frame (run);
}
}
/* destroy global variables */
refdown_globals (run, 1);
}
/* reset the exit level */
run->exit_level = EXIT_NONE;
return ret;
}
static int qse_awk_pushfuncarg (qse_awk_run_t* run, qse_awk_val_t* val)
{
}
static int qse_awk_runfunc (qse_awk_run_t* run, const qse_char_t* name)
{
int ret = 0;
struct capture_retval_data_t crdata;
qse_awk_nde_call_t nde;
qse_awk_val_t* v;
/* forge a fake node containing a function call */
nde.type = QSE_AWK_NDE_AFN;
nde.line = 0;
nde.next = QSE_NULL;
nde.what.afn.name.ptr = (qse_char_t*)name;
nde.what.afn.name.len = qse_strlen(name);
nde.args = QSE_NULL;
nde.nargs = 0;
#if 0
if (runarg != QSE_NULL)
{
/* prepare to pass the arguments to the main function */
for (i = nrunargs; i > 0; )
{
qse_awk_nde_str_t* tmp, * tmp2;
i--;
tmp = (qse_awk_nde_str_t*) QSE_AWK_ALLOC (
run->awk, QSE_SIZEOF(*tmp));
if (tmp == QSE_NULL)
{
tmp = (qse_awk_nde_str_t*)nde.args;
while (tmp != QSE_NULL)
{
tmp2 = (qse_awk_nde_str_t*)tmp->next;
QSE_AWK_FREE (run->awk, tmp->ptr);
QSE_AWK_FREE (run->awk, tmp);
tmp = tmp2;
}
refdown_globals (run, 0);
run->stack_top = saved_stack_top;
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
return -1;
}
tmp->type = QSE_AWK_NDE_STR;
tmp->ptr = QSE_AWK_STRXDUP (run->awk,
runarg[i].ptr, runarg[i].len);
if (tmp->ptr == QSE_NULL)
{
QSE_AWK_FREE (run->awk, tmp);
tmp = (qse_awk_nde_str_t*)nde.args;
while (tmp != QSE_NULL)
{
tmp2 = (qse_awk_nde_str_t*)tmp->next;
QSE_AWK_FREE (run->awk, tmp->ptr);
QSE_AWK_FREE (run->awk, tmp);
tmp = tmp2;
}
refdown_globals (run, 0);
run->stack_top = saved_stack_top;
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
return -1;
}
tmp->len = runarg[i].len;
tmp->next = nde.args;
nde.args = (qse_awk_nde_t*)tmp;
nde.nargs++;
}
QSE_ASSERT (nrunargs == nde.nargs);
}
#endif
crdata.run = run;
crdata.val = QSE_NULL;
v = eval_afn_intrinsic (run, (qse_awk_nde_t*)&nde,
capture_retval_on_exit, &crdata);
if (v == QSE_NULL)
{
if (crdata.val == QSE_NULL)
{
QSE_ASSERT (run->errnum != QSE_AWK_ENOERR);
ret = -1;
}
else
{
if (run->errnum == QSE_AWK_ENOERR)
{
if (run->cbs != QSE_NULL && run->cbs->on_exit != QSE_NULL)
{
run->cbs->on_exit (run, crdata.val, run->cbs->data);
}
}
else ret = -1;
qse_awk_refdownval(run, crdata.val);
}
}
else
{
qse_awk_refupval (run, v);
if (run->cbs != QSE_NULL && run->cbs->on_exit != QSE_NULL)
{
run->cbs->on_exit (run, v, run->cbs->data);
}
qse_awk_refdownval (run, v);
}
if (nde.args != QSE_NULL) qse_awk_clrpt (run->awk, nde.args);
return ret;
}
static int run_function (
qse_awk_run_t* run, const qse_char_t* main, const qse_cstr_t* runarg)
{
int ret;
run->exit_level = EXIT_NONE;
ret = prepare_globals (run, runarg);
if (ret == 0)
{
/* adjust global variables a little more */
ret = update_fnr (run, 0, 0);
if (ret == 0) ret = set_globals_to_default(run);
if (ret == 0)
{
/* TODO: */
}
refdown_globals (run, 1);
}
return ret;
}
static int run_main ( static int run_main (
qse_awk_run_t* run, const qse_char_t* name,
const qse_cstr_t* runarg)
{
return (name == QSE_NULL)?
run_bpae (run, runarg):
run_function (run, name, runarg);
}
static int ____run_main_to_be_removed____ (
qse_awk_run_t* run, const qse_char_t* main, qse_awk_run_t* run, const qse_char_t* main,
qse_awk_runarg_t* runarg) const qse_cstr_t* runarg)
{ {
qse_size_t nglobals, nargs, nrunargs, i; qse_size_t nglobals, nargs, nrunargs, i;
qse_size_t saved_stack_top; qse_size_t saved_stack_top;
@ -1341,7 +1731,7 @@ static int run_main (
QSE_AWK_FREE (run->awk, tmp); QSE_AWK_FREE (run->awk, tmp);
tmp = tmp2; tmp = tmp2;
} }
cleanup_globals (run); refdown_globals (run, 0);
run->stack_top = saved_stack_top; run->stack_top = saved_stack_top;
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM); qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
@ -1362,7 +1752,7 @@ static int run_main (
QSE_AWK_FREE (run->awk, tmp); QSE_AWK_FREE (run->awk, tmp);
tmp = tmp2; tmp = tmp2;
} }
cleanup_globals (run); refdown_globals (run, 0);
run->stack_top = saved_stack_top; run->stack_top = saved_stack_top;
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM); qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
@ -1393,9 +1783,9 @@ static int run_main (
{ {
if (run->errnum == QSE_AWK_ENOERR) if (run->errnum == QSE_AWK_ENOERR)
{ {
if (run->cbs != QSE_NULL && run->cbs->on_return != QSE_NULL) if (run->cbs != QSE_NULL && run->cbs->on_exit != QSE_NULL)
{ {
run->cbs->on_return (run, crdata.val, run->cbs->data); run->cbs->on_exit (run, crdata.val, run->cbs->data);
} }
} }
else n = -1; else n = -1;
@ -1407,9 +1797,9 @@ static int run_main (
{ {
qse_awk_refupval (run, v); qse_awk_refupval (run, v);
if (run->cbs != QSE_NULL && run->cbs->on_return != QSE_NULL) if (run->cbs != QSE_NULL && run->cbs->on_exit != QSE_NULL)
{ {
run->cbs->on_return (run, v, run->cbs->data); run->cbs->on_exit (run, v, run->cbs->data);
} }
qse_awk_refdownval (run, v); qse_awk_refdownval (run, v);
@ -1422,7 +1812,7 @@ static int run_main (
qse_awk_nde_t* nde; qse_awk_nde_t* nde;
/* no main function is specified. /* no main function is specified.
* run the normal patter blocks including BEGIN and END */ * run the normal pattern blocks including BEGIN and END */
saved_stack_top = run->stack_top; saved_stack_top = run->stack_top;
if (__raw_push(run,(void*)run->stack_base) == -1) if (__raw_push(run,(void*)run->stack_base) == -1)
@ -1430,8 +1820,9 @@ static int run_main (
/* restore the stack top in a cheesy(?) way */ /* restore the stack top in a cheesy(?) way */
run->stack_top = saved_stack_top; run->stack_top = saved_stack_top;
/* pops off global variables in a decent way */ /* pops off global variables in a decent way */
cleanup_globals (run); /*refdown_globals (run);
__raw_pop_times (run, run->awk->tree.nglobals); __raw_pop_times (run, run->awk->tree.nglobals);*/
refdown_globals (run, 1);
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM); qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
return -1; return -1;
@ -1440,8 +1831,9 @@ static int run_main (
if (__raw_push(run,(void*)saved_stack_top) == -1) if (__raw_push(run,(void*)saved_stack_top) == -1)
{ {
run->stack_top = saved_stack_top; run->stack_top = saved_stack_top;
cleanup_globals (run); /*refdown_globals (run);
__raw_pop_times (run, run->awk->tree.nglobals); __raw_pop_times (run, run->awk->tree.nglobals); */
refdown_globals (run, 1);
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM); qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
return -1; return -1;
@ -1451,8 +1843,9 @@ static int run_main (
if (__raw_push(run,qse_awk_val_nil) == -1) if (__raw_push(run,qse_awk_val_nil) == -1)
{ {
run->stack_top = saved_stack_top; run->stack_top = saved_stack_top;
cleanup_globals (run); /*refdown_globals (run);
__raw_pop_times (run, run->awk->tree.nglobals); __raw_pop_times (run, run->awk->tree.nglobals);*/
refdown_globals (run, 1);
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM); qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
return -1; return -1;
@ -1462,8 +1855,9 @@ static int run_main (
if (__raw_push(run,qse_awk_val_nil) == -1) if (__raw_push(run,qse_awk_val_nil) == -1)
{ {
run->stack_top = saved_stack_top; run->stack_top = saved_stack_top;
cleanup_globals (run); /*refdown_globals (run);
__raw_pop_times (run, run->awk->tree.nglobals); __raw_pop_times (run, run->awk->tree.nglobals);*/
refdown_globals (run, 1);
qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM); qse_awk_setrunerrnum (run, QSE_AWK_ENOMEM);
return -1; return -1;
@ -1564,9 +1958,9 @@ static int run_main (
v = STACK_RETVAL(run); v = STACK_RETVAL(run);
if (n == 0) if (n == 0)
{ {
if (run->cbs != QSE_NULL && run->cbs->on_return != QSE_NULL) if (run->cbs != QSE_NULL && run->cbs->on_exit != QSE_NULL)
{ {
run->cbs->on_return (run, v, run->cbs->data); run->cbs->on_exit (run, v, run->cbs->data);
} }
} }
/* end the life of the global return value */ /* end the life of the global return value */
@ -6347,15 +6741,6 @@ static int __raw_push (qse_awk_run_t* run, void* val)
return 0; return 0;
} }
static void __raw_pop_times (qse_awk_run_t* run, qse_size_t times)
{
while (times > 0)
{
--times;
__raw_pop (run);
}
}
static int read_record (qse_awk_run_t* run) static int read_record (qse_awk_run_t* run)
{ {
qse_ssize_t n; qse_ssize_t n;

View File

@ -96,9 +96,15 @@ extern "C" {
#endif #endif
qse_char_t* qse_awk_format ( qse_char_t* qse_awk_format (
qse_awk_run_t* run, qse_str_t* out, qse_str_t* fbu, qse_awk_run_t* run,
const qse_char_t* fmt, qse_size_t fmt_len, qse_str_t* out,
qse_size_t nargs_on_stack, qse_awk_nde_t* args, qse_size_t* len); qse_str_t* fbu,
const qse_char_t* fmt,
qse_size_t fmt_len,
qse_size_t nargs_on_stack,
qse_awk_nde_t* args,
qse_size_t* len
);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -95,8 +95,6 @@ qse_pcp_t* qse_pcp_init (
}; };
int i, minidx = -1, maxidx = -1; int i, minidx = -1, maxidx = -1;
QSE_ASSERT (QSE_COUNTOF(pcp->hanlde) == QSE_COUNTOF(handle));
QSE_MEMSET (pcp, 0, QSE_SIZEOF(*pcp)); QSE_MEMSET (pcp, 0, QSE_SIZEOF(*pcp));
pcp->mmgr = mmgr; pcp->mmgr = mmgr;