diff --git a/qse/cmd/awk/awk.c b/qse/cmd/awk/awk.c index 63eca514..1c8055f2 100644 --- a/qse/cmd/awk/awk.c +++ b/qse/cmd/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c 220 2009-07-01 13:14:39Z hyunghwan.chung $ + * $Id: awk.c 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -233,14 +233,7 @@ static int apply_fs_and_gvm (qse_awk_rtx_t* rtx, struct arg_t* arg) return 0; } -static int on_loop_enter (qse_awk_rtx_t* rtx, void* data) -{ - /* TODO: anything to do? */ - return 0; -} - -static void on_loop_exit ( - qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* data) +static void dprint_return (qse_awk_rtx_t* rtx, qse_awk_val_t* ret) { qse_size_t len; qse_char_t* str; @@ -274,8 +267,7 @@ static void on_statement ( /*dprint (L"running %d\n", (int)line);*/ } -static int fnc_sleep ( - qse_awk_rtx_t* run, const qse_char_t* fnm, qse_size_t fnl) +static int fnc_sleep (qse_awk_rtx_t* run, const qse_cstr_t* fnm) { qse_size_t nargs; qse_awk_val_t* a0; @@ -681,6 +673,7 @@ static int awk_main (int argc, qse_char_t* argv[]) { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; + qse_awk_val_t* retv; qse_awk_rcb_t rcb; int i; @@ -751,8 +744,6 @@ static int awk_main (int argc, qse_char_t* argv[]) goto oops; } - rcb.on_loop_enter = on_loop_enter; - rcb.on_loop_exit = on_loop_exit; rcb.on_statement = on_statement; rcb.udd = &arg; @@ -773,18 +764,18 @@ static int awk_main (int argc, qse_char_t* argv[]) qse_awk_rtx_setrcb (rtx, &rcb); set_intr_run (); - if (arg.call == QSE_NULL) + + retv = (arg.call == QSE_NULL)? + qse_awk_rtx_loop (rtx): + qse_awk_rtx_call (rtx, arg.call, QSE_NULL, 0); + if (retv != QSE_NULL) { - ret = qse_awk_rtx_loop (rtx); - } - else - { - qse_awk_val_t* rv; - - rv = qse_awk_rtx_call (rtx, arg.call, QSE_NULL, 0); - ret = (rv == QSE_NULL)? -1: 0; - qse_awk_rtx_refdownval (rtx, rv); + qse_awk_rtx_refdownval (rtx, retv); + ret = 0; + + dprint_return (rtx, retv); } + unset_intr_run (); if (ret <= -1) diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 7e3a1aac..e6174bd1 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp 235 2009-07-15 10:43:31Z hyunghwan.chung $ + * $Id: Awk.hpp 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -255,7 +255,9 @@ protected: void retrieveError (Run* run); /*@}*/ +protected: class NoSource; + public: /** * The Source class is an abstract class to encapsulate @@ -677,6 +679,7 @@ public: static const char_t* EMPTY_STRING; }; +public: /** * Defines an identifier of predefined global variables. * Awk::setGlobal and Awk::getGlobal can take one of these enumerators. @@ -802,24 +805,26 @@ public: * @return a Run object on success, #QSE_NULL on failure */ Awk::Run* parse ( - Source& in, /**< script to parse */ - Source& out /**< deparsing target */ + Source& in, ///< script to parse + Source& out ///< deparsing target ); /** * Executes the BEGIN block, pattern-action blocks, and the END block. * @return 0 on succes, -1 on failure */ - int loop (); + int loop ( + Value* ret ///< return value holder + ); /** * Calls a function */ int call ( - const char_t* name, - Value* ret, - const Value* args, - size_t nargs + const char_t* name, ///< function name + Value* ret, ///< return value holder + const Value* args, ///< argument array + size_t nargs ///< number of arguments ); /** @@ -982,16 +987,6 @@ public: int deleteFunction (const char_t* name); /*@}*/ - /** - * Enables the run-time callback - */ - void enableRunCallback (); - - /** - * Disables the run-time callback - */ - void disableRunCallback (); - /** * @name Word Substitution */ @@ -1058,11 +1053,6 @@ protected: virtual int nextConsole (Console& io) = 0; /*@}*/ - // run-time callbacks - virtual bool onLoopEnter (Run& run); - virtual void onLoopExit (Run& run, const Value& ret); - virtual void onStatement (Run& run, size_t line); - // primitive handlers virtual real_t pow (real_t x, real_t y) = 0; virtual int vsprintf (char_t* buf, size_t size, @@ -1086,10 +1076,6 @@ protected: static int functionHandler (rtx_t* rtx, const cstr_t* name); - static int onLoopEnter (rtx_t* run, void* data); - static void onLoopExit (rtx_t* run, val_t* ret, void* data); - static void onStatement (rtx_t* run, size_t line, void* data); - static real_t pow (awk_t* data, real_t x, real_t y); static int sprintf (awk_t* data, char_t* buf, size_t size, const char_t* fmt, ...); @@ -1108,8 +1094,6 @@ protected: Source* sourceReader; Source* sourceWriter; - bool runCallback; - struct xstrs_t { xstrs_t (): ptr (QSE_NULL), len (0), capa (0) {} diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index da6b5849..43c10c65 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h 235 2009-07-15 10:43:31Z hyunghwan.chung $ + * $Id: awk.h 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -58,7 +58,9 @@ * awk = qse_awk_open (mmgr, 0, prm); // create an interpreter * qse_awk_parse (awk, &sio); // parse a script * rtx = qse_awk_rtx_open (awk, 0, &rio, args); // create a runtime context - * qse_awk_rtx_loop (rtx); // run a standard AWK loop + * retv = qse_awk_rtx_loop (rtx); // run a standard AWK loop + * if (retv != QSE_NULL) + * qse_awk_rtx_refdownval (rtx, retv); // free return value * qse_awk_rtx_close (rtx); // destroy the runtime context * qse_awk_close (awk); // destroy the interpreter * @endcode @@ -466,20 +468,6 @@ typedef struct qse_awk_rio_t qse_awk_rio_t; */ struct qse_awk_rcb_t { - /** - * called by qse_awk_rtx_loop() before entering pattern-action loop. - * A @b BEGIN block is executed after this callback. - */ - int (*on_loop_enter) ( - qse_awk_rtx_t* rtx, void* udd); - - /** - * called by qse_awk_rtx_loop() when exiting pattern-action loop. - * An @b END block is executed before this callback. - */ - void (*on_loop_exit) ( - qse_awk_rtx_t* rtx, qse_awk_val_t* ret, void* udd); - /** * called by qse_awk_rtx_loop() and qse_awk_rtx_call() for * each statement executed. @@ -1304,22 +1292,25 @@ void qse_awk_rtx_close ( /** * The qse_awk_rtx_loop() function executes the BEGIN block, pattern-action - * blocks and the END blocks in an AWk program. Multiple invocations of the - * function for the lifetime of a runtime context is not desirable. + * blocks and the END blocks in an AWk program. It returns the global return + * value of which the reference count must be decremented when not necessary. + * Multiple invocations of the function for the lifetime of a runtime context + * is not desirable. * + * The example shows typical usage of the function. * @code - * The example shows typical usage of the function. - * rtx = qse_awk_rtx_open (awk, 0, rio, QSE_NULL); - * if (rtx != QSE_NULL) - * { - * qse_awk_rtx_loop (rtx); - * qse_awk_rtx_close (rtx); - * } + * rtx = qse_awk_rtx_open (awk, 0, rio, QSE_NULL); + * if (rtx != QSE_NULL) + * { + * retv = qse_awk_rtx_loop (rtx); + * if (retv != QSE_NULL) qse_awk_rtx_refdownval (rtx, retv); + * qse_awk_rtx_close (rtx); + * } * @endcode * - * @return 0 on success, -1 on failure. + * @return return value on success, QSE_NULL on failure. */ -int qse_awk_rtx_loop ( +qse_awk_val_t* qse_awk_rtx_loop ( qse_awk_rtx_t* rtx /**< runtime context */ ); diff --git a/qse/include/qse/cmn/rex.h b/qse/include/qse/cmn/rex.h index e75e87ad..24590290 100644 --- a/qse/include/qse/cmn/rex.h +++ b/qse/include/qse/cmn/rex.h @@ -1,5 +1,5 @@ /* - * $Id: rex.h 203 2009-06-17 12:43:50Z hyunghwan.chung $ + * $Id: rex.h 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -54,6 +54,7 @@ * * @todo * - support \\n to refer to the nth matching substring + * - change to adopt Thomson's NFA (http://swtch.com/~rsc/regexp/regexp1.html) */ #define QSE_REX_NA(code) (*(qse_size_t*)(code)) diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index e1577668..2294e5e2 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 235 2009-07-15 10:43:31Z hyunghwan.chung $ + * $Id: Awk.cpp 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -21,6 +21,9 @@ #include "../cmn/mem.h" #include "awk.h" +// enable this once addFunction() is extended with argument spec (rxv...). +//#define PASS_BY_REFERENCE + ///////////////////////////////// QSE_BEGIN_NAMESPACE(QSE) ///////////////////////////////// @@ -994,7 +997,7 @@ int Awk::Run::getGlobal (int id, Value& g) const Awk::Awk () : awk (QSE_NULL), functionMap (QSE_NULL), sourceIn (this, Source::READ), sourceOut (this, Source::WRITE), - runCallback (false), runctx (this) + runctx (this) { errinf.num = (errnum_t)ERR_NOERR; @@ -1140,7 +1143,6 @@ int Awk::open () qse_map_setfreeer (functionMap, QSE_MAP_VAL, free_function_map_value); qse_map_setscale (functionMap, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t)); - runCallback = false; return 0; } @@ -1162,7 +1164,6 @@ void Awk::close () } clearError (); - runCallback = false; } Awk::Run* Awk::parse (Source& in, Source& out) @@ -1195,19 +1196,27 @@ Awk::Run* Awk::parse (Source& in, Source& out) return &runctx; } -int Awk::loop () +int Awk::loop (Value* ret) { QSE_ASSERT (awk != QSE_NULL); QSE_ASSERT (runctx.rtx != QSE_NULL); - int n = qse_awk_rtx_loop (runctx.rtx); - if (n <= -1) retrieveError (&runctx); - return n; + val_t* rv = qse_awk_rtx_loop (runctx.rtx); + if (rv == QSE_NULL) + { + retrieveError (&runctx); + return -1; + } + + ret->setVal (&runctx, rv); + qse_awk_rtx_refdownval (runctx.rtx, rv); + + return 0; } int Awk::call ( const char_t* name, Value* ret, - const Value* args, size_t nargs) + const Value* args, size_t nargs) { QSE_ASSERT (awk != QSE_NULL); QSE_ASSERT (runctx.rtx != QSE_NULL); @@ -1260,21 +1269,11 @@ int Awk::init_runctx () if (runctx.rtx != QSE_NULL) return 0; qse_awk_rio_t rio; - qse_awk_rcb_t rcb; rio.pipe = pipeHandler; rio.file = fileHandler; rio.console = consoleHandler; - if (runCallback) - { - QSE_MEMSET (&rcb, 0, QSE_SIZEOF(rcb)); - rcb.on_loop_enter = onLoopEnter; - rcb.on_loop_exit = onLoopExit; - rcb.on_statement = onStatement; - rcb.udd = &runctx; - } - rtx_t* rtx = qse_awk_rtx_open ( awk, QSE_SIZEOF(rxtn_t), &rio, (qse_cstr_t*)runarg.ptr); if (rtx == QSE_NULL) @@ -1288,7 +1287,6 @@ int Awk::init_runctx () rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); rxtn->run = &runctx; - if (runCallback) qse_awk_rtx_setrcb (rtx, &rcb); return 0; } @@ -1357,12 +1355,23 @@ int Awk::dispatch_function (Run* run, const cstr_t* name) for (i = 0; i < nargs; i++) { val_t* v = qse_awk_rtx_getarg (run->rtx, i); +#ifdef PASS_BY_REFERENCE + QSE_ASSERT (v->type == QSE_AWK_VAL_REF); + val_t** ref = (val_t**)((qse_awk_val_ref_t*)v)->adr; + if (args[i].setVal (run, *ref) == -1) + { + run->setError (ERR_NOMEM); + if (args != buf) delete[] args; + return -1; + } +#else if (args[i].setVal (run, v) == -1) { run->setError (ERR_NOMEM); if (args != buf) delete[] args; return -1; } +#endif } Value ret (run); @@ -1372,6 +1381,28 @@ int Awk::dispatch_function (Run* run, const cstr_t* name) try { n = (this->*handler) (*run, ret, args, nargs, name); } catch (...) { n = -1; } +#ifdef PASS_BY_REFERENCE + if (n >= 0) + { + for (i = 0; i < nargs; i++) + { + QSE_ASSERTX (args[i].run == run, + "Do NOT change Run from function handler"); + + val_t* v = qse_awk_rtx_getarg (run->rtx, i); + val_t* nv = args[i].toVal(); + + if (nv == v) continue; + + QSE_ASSERT (v->type == QSE_AWK_VAL_REF); + val_t** ref = (val_t**)((qse_awk_val_ref_t*)v)->adr; + + qse_awk_rtx_refdownval (run->rtx, *ref); + *ref = nv; + qse_awk_rtx_refupval (run->rtx, *ref); + } + } +#endif if (args != buf) delete[] args; if (n <= -1) @@ -1505,9 +1536,15 @@ int Awk::addFunction ( size_t nameLen = qse_strlen(name); - void* p = qse_awk_addfnc (awk, name, nameLen, - 0, minArgs, maxArgs, QSE_NULL, - functionHandler); + void* p = qse_awk_addfnc ( + awk, name, nameLen, + 0, minArgs, maxArgs, +#ifdef PASS_BY_REFERENCE + QSE_T("R"), // pass all arguments by reference +#else + QSE_NULL, +#endif + functionHandler); if (p == QSE_NULL) { qse_awk_free (awk, tmp); @@ -1542,16 +1579,6 @@ int Awk::deleteFunction (const char_t* name) return n; } -void Awk::enableRunCallback () -{ - runCallback = true; -} - -void Awk::disableRunCallback () -{ - runCallback = false; -} - int Awk::getWord ( const char_t* ow, qse_size_t owl, const char_t** nw, qse_size_t* nwl) @@ -1590,20 +1617,6 @@ int Awk::unsetAllWords () return qse_awk_setword (awk, QSE_NULL, 0, QSE_NULL, 0); } - -bool Awk::onLoopEnter (Run& run) -{ - return true; -} - -void Awk::onLoopExit (Run& run, const Value& ret) -{ -} - -void Awk::onStatement (Run& run, size_t line) -{ -} - Awk::ssize_t Awk::readSource ( awk_t* awk, qse_awk_sio_cmd_t cmd, char_t* data, size_t count) { @@ -1762,28 +1775,6 @@ int Awk::functionHandler (rtx_t* rtx, const cstr_t* name) return rxtn->run->awk->dispatch_function (rxtn->run, name); } -int Awk::onLoopEnter (rtx_t* rtx, void* data) -{ - Run* run = (Run*)data; - return run->awk->onLoopEnter(*run)? 0: -1; -} - -void Awk::onLoopExit (rtx_t* rtx, val_t* ret, void* data) -{ - Run* run = (Run*)data; - - Value x; - if (x.setVal (run, ret) == -1) - qse_awk_rtx_seterrnum (run->rtx, (errnum_t)ERR_NOMEM); - else run->awk->onLoopExit (*run, x); -} - -void Awk::onStatement (rtx_t* rtx, size_t line, void* data) -{ - Run* run = (Run*)data; - run->awk->onStatement (*run, line); -} - Awk::real_t Awk::pow (awk_t* awk, real_t x, real_t y) { xtn_t* xtn = (xtn_t*) QSE_XTN (awk); diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index c4929608..389e2ebf 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c 235 2009-07-15 10:43:31Z hyunghwan.chung $ + * $Id: run.c 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -1318,30 +1318,17 @@ static void exit_stack_frame (qse_awk_rtx_t* run) run->stack_base = (qse_size_t)run->stack[run->stack_base+0]; } -static int run_bpae_loop (qse_awk_rtx_t* rtx) +static qse_awk_val_t* run_bpae_loop (qse_awk_rtx_t* rtx) { qse_awk_nde_t* nde; qse_size_t nargs, i; - qse_awk_val_t* v; + qse_awk_val_t* retv; int ret = 0; /* set nargs to zero */ nargs = 0; STACK_NARGS(rtx) = (void*)nargs; - /* call the callback */ - if (rtx->rcb.on_loop_enter != QSE_NULL) - { - qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOERR); - ret = rtx->rcb.on_loop_enter (rtx, rtx->rcb.udd); - if (ret <= -1) - { - if (rtx->errinf.num == QSE_AWK_ENOMEM) - qse_awk_rtx_seterrnum (rtx, QSE_AWK_EUNKNOWN); - ret = -1; - } - } - /* execute the BEGIN block */ for (nde = rtx->awk->tree.begin; ret == 0 && nde != QSE_NULL && rtx->exit_level < EXIT_GLOBAL; @@ -1357,7 +1344,7 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx) if (run_block (rtx, blk) == -1) ret = -1; } - if (ret == -1 && rtx->errinf.num == QSE_AWK_ENOERR) + if (ret <= -1 && rtx->errinf.num == QSE_AWK_ENOERR) { /* an error is returned with no error number set. * this feature is used by eval_expression() to @@ -1374,10 +1361,10 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx) rtx->awk->tree.end != QSE_NULL) && rtx->exit_level < EXIT_GLOBAL) { - if (run_pattern_blocks(rtx) == -1) ret = -1; + if (run_pattern_blocks(rtx) <= -1) ret = -1; } - if (ret == -1 && rtx->errinf.num == QSE_AWK_ENOERR) + if (ret <= -1 && rtx->errinf.num == QSE_AWK_ENOERR) { /* an error is returned with no error number set. * this feature is used by eval_expression() to @@ -1401,7 +1388,7 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx) rtx->active_block = blk; rtx->exit_level = EXIT_NONE; - if (run_block (rtx, blk) == -1) ret = -1; + if (run_block (rtx, blk) <= -1) ret = -1; else if (rtx->exit_level >= EXIT_GLOBAL) { /* once exit is called inside one of END blocks, @@ -1410,7 +1397,7 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx) } } - if (ret == -1 && rtx->errinf.num == QSE_AWK_ENOERR) + if (ret <= -1 && rtx->errinf.num == QSE_AWK_ENOERR) { /* an error is returned with no error number set. * this feature is used by eval_expression() to @@ -1430,39 +1417,34 @@ static int run_bpae_loop (qse_awk_rtx_t* rtx) qse_awk_rtx_refdownval (rtx, STACK_ARG(rtx,i)); /* get the return value in the current stack frame */ - v = STACK_RETVAL(rtx); + retv = STACK_RETVAL(rtx); - if (rtx->rcb.on_loop_exit != QSE_NULL) + if (ret <= -1) { - /* we call the on_exit handler regardless of ret. - * the return value passed is the global return value - * in the stack. */ - rtx->rcb.on_loop_exit (rtx, v, rtx->rcb.udd); + /* end the life of the global return value upon error */ + qse_awk_rtx_refdownval (rtx, retv); + retv = QSE_NULL; } - /* end the life of the global return value */ - qse_awk_rtx_refdownval (rtx, v); - - return ret; + return retv; } /* start the BEGIN-pattern block-END loop */ -int qse_awk_rtx_loop (qse_awk_rtx_t* rtx) +qse_awk_val_t* qse_awk_rtx_loop (qse_awk_rtx_t* rtx) { - int ret; + qse_awk_val_t* retv = QSE_NULL; rtx->exit_level = EXIT_NONE; - ret = enter_stack_frame (rtx); - if (ret == 0) + if (enter_stack_frame (rtx) == 0) { - ret = run_bpae_loop (rtx); + retv = run_bpae_loop (rtx); exit_stack_frame (rtx); } /* reset the exit level */ rtx->exit_level = EXIT_NONE; - return ret; + return retv; } /* call an AWK function */ @@ -5846,7 +5828,8 @@ static qse_size_t push_arg_from_nde ( qse_strlen(fnc_arg_spec) > nargs)); if (fnc_arg_spec != QSE_NULL && - fnc_arg_spec[nargs] == QSE_T('r')) + (fnc_arg_spec[nargs] == QSE_T('r') || + fnc_arg_spec[0] == QSE_T('R'))) { qse_awk_val_t** ref; @@ -5872,6 +5855,7 @@ static qse_size_t push_arg_from_nde ( { v = eval_expression (rtx, p); } + if (v == QSE_NULL) { UNWIND_RTX_STACK_ARG (rtx, nargs); diff --git a/qse/lib/awk/tree.h b/qse/lib/awk/tree.h index 0373aec7..c8aca547 100644 --- a/qse/lib/awk/tree.h +++ b/qse/lib/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h 235 2009-07-15 10:43:31Z hyunghwan.chung $ + * $Id: tree.h 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -76,6 +76,8 @@ enum qse_awk_nde_type_t QSE_AWK_NDE_GETLINE }; +typedef enum qse_awk_nde_type_t qse_awk_nde_type_t; + enum qse_awk_in_type_t { /* the order of these values match @@ -149,7 +151,7 @@ struct qse_awk_fun_t }; #define QSE_AWK_NDE_HDR \ - int type; \ + qse_awk_nde_type_t type; \ qse_size_t line; \ qse_awk_nde_t* next @@ -162,7 +164,7 @@ struct qse_awk_nde_t struct qse_awk_nde_blk_t { QSE_AWK_NDE_HDR; - qse_size_t nlcls; + qse_size_t nlcls; /* number of local variables */ qse_awk_nde_t* body; }; diff --git a/qse/samples/awk/awk01.c b/qse/samples/awk/awk01.c index 4254f0b8..a0b9cfcc 100644 --- a/qse/samples/awk/awk01.c +++ b/qse/samples/awk/awk01.c @@ -1,5 +1,5 @@ /* - * $Id: awk01.c 195 2009-06-10 13:18:25Z hyunghwan.chung $ + * $Id: awk01.c 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -35,13 +35,14 @@ int main () { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; + qse_awk_val_t* retv; qse_awk_parsestd_in_t psin; int ret; awk = qse_awk_openstd (0); if (awk == QSE_NULL) { - qse_fprintf (QSE_STDERR, QSE_T("error: cannot open awk\n")); + qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n")); goto oops; } @@ -49,11 +50,11 @@ int main () psin.u.cp = src; ret = qse_awk_parsestd (awk, &psin, QSE_NULL); - if (ret == -1) + if (ret <= -1) { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk)); - goto oops; + ret = -1; goto oops; } rtx = qse_awk_rtx_openstd ( @@ -65,22 +66,25 @@ int main () ); if (rtx == QSE_NULL) { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk)); - goto oops; + ret = -1; goto oops; } - ret = qse_awk_rtx_loop (rtx); - if (ret == -1) + retv = qse_awk_rtx_loop (rtx); + if (retv == QSE_NULL) { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx)); - goto oops; + ret = -1; goto oops; } + qse_awk_rtx_refdownval (rtx, retv); + ret = 0; + oops: if (rtx != QSE_NULL) qse_awk_rtx_close (rtx); if (awk != QSE_NULL) qse_awk_close (awk); - return -1; + return ret; } diff --git a/qse/samples/awk/awk02.c b/qse/samples/awk/awk02.c index a068283a..a4434327 100644 --- a/qse/samples/awk/awk02.c +++ b/qse/samples/awk/awk02.c @@ -1,5 +1,5 @@ /* - * $Id: awk02.c 195 2009-06-10 13:18:25Z hyunghwan.chung $ + * $Id: awk02.c 236 2009-07-16 08:27:53Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -38,6 +38,7 @@ int main () { qse_awk_t* awk = QSE_NULL; qse_awk_rtx_t* rtx = QSE_NULL; + qse_awk_val_t* retv; qse_awk_parsestd_in_t psin; qse_awk_parsestd_out_t psout; @@ -47,8 +48,8 @@ int main () awk = qse_awk_openstd (0); if (awk == QSE_NULL) { - qse_fprintf (QSE_STDERR, QSE_T("error: cannot open awk\n")); - goto oops; + qse_fprintf (QSE_STDERR, QSE_T("ERROR: cannot open awk\n")); + ret = -1; goto oops; } qse_memset (srcout, QSE_T(' '), QSE_COUNTOF(srcout)-1); @@ -60,11 +61,11 @@ int main () psout.u.cp = srcout; ret = qse_awk_parsestd (awk, &psin, &psout); - if (ret == -1) + if (ret <= -1) { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk)); - goto oops; + ret = -1; goto oops; } qse_printf (QSE_T("DEPARSED SOURCE:\n%s\n"), srcout); @@ -80,19 +81,22 @@ int main () ); if (rtx == QSE_NULL) { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_geterrmsg(awk)); - goto oops; + ret = -1; goto oops; } - ret = qse_awk_rtx_loop (rtx); - if (ret == -1) + retv = qse_awk_rtx_loop (rtx); + if (retv == QSE_NULL) { - qse_fprintf (QSE_STDERR, QSE_T("error: %s\n"), + qse_fprintf (QSE_STDERR, QSE_T("ERROR: %s\n"), qse_awk_rtx_geterrmsg(rtx)); - goto oops; + ret = -1; goto oops; } + qse_awk_rtx_refdownval (rtx, retv); + ret = 0; + oops: if (rtx != QSE_NULL) qse_awk_rtx_close (rtx); if (awk != QSE_NULL) qse_awk_close (awk); diff --git a/qse/samples/awk/awk05.cpp b/qse/samples/awk/awk05.cpp index 39e94ca1..b7d548ab 100644 --- a/qse/samples/awk/awk05.cpp +++ b/qse/samples/awk/awk05.cpp @@ -49,8 +49,9 @@ static int run_awk (QSE::StdAwk& awk) // parse the script string and deparse it to awk05.out. if (awk.parse (in, out) == QSE_NULL) return -1; + QSE::StdAwk::Value r; // execute the BEGIN, pattern-action, END blocks. - return awk.loop (); + return awk.loop (&r); } static int awk_main (int argc, qse_char_t* argv[]) diff --git a/qse/samples/awk/awk06.cpp b/qse/samples/awk/awk06.cpp index e165d693..fd4781ad 100644 --- a/qse/samples/awk/awk06.cpp +++ b/qse/samples/awk/awk06.cpp @@ -37,6 +37,7 @@ static int run_awk (QSE::StdAwk& awk) "function add (a, b) { return a + b }\n" "function mul (a, b) { return a * b }\n" "function div (a, b) { return a / b }\n" + "function sine (a) { return sin(a) }\n" ); QSE::StdAwk::SourceString in (script); @@ -52,16 +53,25 @@ static int run_awk (QSE::StdAwk& awk) // ret = add (-20, 51) QSE::StdAwk::Value ret; - if (awk.call (QSE_T("add"), &ret, arg, QSE_COUNTOF(arg)) <= -1) return -1; + if (awk.call (QSE_T("add"), &ret, arg, 2) <= -1) return -1; // ret = mul (ret, 51); arg[0] = ret; - if (awk.call (QSE_T("mul"), &ret, arg, QSE_COUNTOF(arg)) <= -1) return -1; + if (awk.call (QSE_T("mul"), &ret, arg, 2) <= -1) return -1; // ret = div (ret, 2); arg[0] = ret; if (arg[1].setReal (run, 2) <= -1) return -1; - if (awk.call (QSE_T("div"), &ret, arg, QSE_COUNTOF(arg)) <= -1) return -1; + if (awk.call (QSE_T("div"), &ret, arg, 2) <= -1) return -1; + + // output the result in various types + qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt()); + qse_printf (QSE_T(" (real) [%Lf]\n"), (long double)ret.toReal()); + qse_printf (QSE_T(" (str) [%s]\n"), ret.toStr(QSE_NULL)); + + // ret = sine (ret); + arg[0] = ret; + if (awk.call (QSE_T("sine"), &ret, arg, 1) <= -1) return -1; // output the result in various types qse_printf (QSE_T("RESULT: (int) [%lld]\n"), (long long)ret.toInt());