diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index f16ef5c8..ce0039ea 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ + * $Id: Awk.hpp 225 2009-07-08 13:01:45Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -87,7 +87,7 @@ public: * and Source::WRITE respectively when called from * Awk::readSource and Awk::writeSource. * - *
+ * @code * int openSource (Source& io) * { * if (io.getMode() == Source::READ) @@ -117,7 +117,7 @@ public: * } * return -1; * } - *+ * @endcode * * @return Awk::Source::READ or Awk::Source::WRITE */ @@ -131,7 +131,7 @@ public: * Awk::closeSource to get the value set in Awk::openSource * as shown in the example below. * - *
+ * @code * int closeSource (Source& io) * { * if (io.getMode() == Source::READ) @@ -146,10 +146,10 @@ public: * } * return -1; * } - *+ * @endcode * * @return an arbitrary value of type void* set with - * Source::setHandle or QSE_NULL + * Source::setHandle() or QSE_NULL */ const void* getHandle () const; @@ -526,7 +526,6 @@ public: }; // end of enum ErrorNumber - // generated by genoptcode.awk /** Defines options */ enum Option @@ -708,23 +707,12 @@ public: */ int getGlobal (int id, Argument& global) const; - /** - * Sets a value into the data field - */ - void setData (void* data); - - /** - * Gets the value stored in the data field - */ - void* getData () const; - void* alloc (size_t size); void free (void* ptr); protected: Awk* awk; rtx_t* rtx; - void* data; }; /** Constructor */ @@ -829,9 +817,9 @@ public: * override Awk::openSource, Awk::closeSource, Awk::readSource, * Awk::writeSource to implement the source code stream. * - * @return 0 on success, -1 on failure + * @return a Run object on success, QSE_NULL on failure */ - virtual int parse (); + virtual Awk::Run* parse (); /** * Executes the BEGIN block, pattern-action blocks, and the END block. @@ -839,6 +827,15 @@ public: */ virtual int loop (); + /** + * Calls a function + */ + virtual int call ( + const char_t* name, + const Return* args, + size_t nargs + ); + /** * Makes request to abort execution */ @@ -1077,6 +1074,11 @@ protected: xstrs_t runarg; private: + Run runctx; + + int init_runctx (); + void fini_runctx (); + static const char_t* xerrstr (awk_t* a, errnum_t num) throw (); private: diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index 2e5f61e6..f234960c 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ + * $Id: Awk.cpp 225 2009-07-08 13:01:45Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -226,8 +226,8 @@ void Awk::Argument::clear () { /* case 1. not initialized. * case 2. initialized with the second init. - * none of the cases creates a new string so the sttring - * that str.ptr is pointing at doesn't have to be freed */ + * none of the cases. create a new string so the sttring + * that str.ptr is pointing to doesn't have to be freed */ this->str.ptr = QSE_NULL; this->str.len = 0; } @@ -918,7 +918,7 @@ Awk::Run::Run (Awk* awk): awk (awk), rtx (QSE_NULL) { } -Awk::Run::Run (Awk* awk, rtx_t* rtx): awk (awk), rtx (rtx), data (QSE_NULL) +Awk::Run::Run (Awk* awk, rtx_t* rtx): awk (awk), rtx (rtx) { QSE_ASSERT (this->rtx != QSE_NULL); } @@ -1062,23 +1062,14 @@ int Awk::Run::getGlobal (int id, Argument& gbl) const return gbl.init (qse_awk_rtx_getgbl (this->rtx, id)); } -void Awk::Run::setData (void* data) -{ - this->data = data; -} - -void* Awk::Run::getData () const -{ - return this->data; -} - ////////////////////////////////////////////////////////////////// // Awk ////////////////////////////////////////////////////////////////// Awk::Awk () throw (): awk (QSE_NULL), functionMap (QSE_NULL), sourceIn (Source::READ), sourceOut (Source::WRITE), - errnum (ERR_NOERR), errlin (0), runCallback (false) + errnum (ERR_NOERR), errlin (0), runCallback (false), + runctx (this) { this->errmsg[0] = QSE_T('\0'); @@ -1238,6 +1229,7 @@ int Awk::open () void Awk::close () { + fini_runctx (); clearArguments (); if (functionMap != QSE_NULL) @@ -1337,31 +1329,34 @@ int Awk::unsetAllWords () return qse_awk_setword (awk, QSE_NULL, 0, QSE_NULL, 0); } -int Awk::parse () +Awk::Run* Awk::parse () { QSE_ASSERT (awk != QSE_NULL); - qse_awk_sio_t sio; + fini_runctx (); + qse_awk_sio_t sio; sio.in = sourceReader; sio.out = sourceWriter; int n = qse_awk_parse (awk, &sio); - if (n == -1) retrieveError (); - return n; + if (n <= -1) + { + retrieveError (); + return QSE_NULL; + } + + if (init_runctx () <= -1) return QSE_NULL; + return &runctx; } -int Awk::loop () +int Awk::init_runctx () { - QSE_ASSERT (awk != QSE_NULL); + if (runctx.rtx != QSE_NULL) return 0; qse_awk_rio_t rio; qse_awk_rcb_t rcb; - // note that the run field is set below after qse_awk_rtx_open() is - // executed. - Run runctx (this); - rio.pipe = pipeHandler; rio.file = fileHandler; rio.console = consoleHandler; @@ -1374,29 +1369,75 @@ int Awk::loop () rcb.on_statement = onStatement; rcb.udd = &runctx; } - - int n = 0; + rtx_t* rtx = qse_awk_rtx_open ( awk, QSE_SIZEOF(rxtn_t), &rio, (qse_cstr_t*)runarg.ptr); if (rtx == QSE_NULL) { retrieveError(); - n = -1; + return -1; } - else + + runctx.rtx = rtx; + + rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); + rxtn->run = &runctx; + + if (runCallback) qse_awk_rtx_setrcb (rtx, &rcb); + return 0; +} + +void Awk::fini_runctx () +{ + if (runctx.rtx != QSE_NULL) { - runctx.rtx = rtx; + qse_awk_rtx_close (runctx.rtx); + runctx.rtx = QSE_NULL; + } +} - rxtn_t* rxtn = (rxtn_t*) QSE_XTN (rtx); - rxtn->run = &runctx; +int Awk::loop () +{ + QSE_ASSERT (awk != QSE_NULL); + QSE_ASSERT (runctx.rtx != QSE_NULL); - if (runCallback) qse_awk_rtx_setrcb (rtx, &rcb); - n = qse_awk_rtx_loop (rtx); - if (n == -1) retrieveError (rtx); - qse_awk_rtx_close (rtx); + int n = qse_awk_rtx_loop (runctx.rtx); + if (n <= -1) retrieveError (runctx.rtx); + return n; +} + +int Awk::call (const char_t* name, const Return* args, size_t nargs) +{ + QSE_ASSERT (awk != QSE_NULL); + QSE_ASSERT (runctx.rtx != QSE_NULL); + + val_t** ptr = QSE_NULL; + + if (args != QSE_NULL) + { + ptr = (val_t**) qse_awk_alloc (awk, QSE_SIZEOF(val_t*) * nargs); + if (ptr == QSE_NULL) + { + runctx.setError (ERR_NOMEM); + return -1; + } + + for (size_t i = 0; i < nargs; i++) ptr[i] = args[i].val; } - return n; + val_t* ret = qse_awk_rtx_call (runctx.rtx, name, ptr, nargs); + + if (ptr != QSE_NULL) qse_awk_free (awk, ptr); + + if (ret == QSE_NULL) + { + retrieveError (runctx.rtx); + return -1; + } + +// TODO: how can i store it??? + qse_awk_rtx_refdownval (runctx.rtx, ret); + return 0; } void Awk::stop () @@ -1410,8 +1451,6 @@ int Awk::dispatchFunction (Run* run, const char_t* name, size_t len) pair_t* pair; awk_t* awk = run->awk->awk; - //awk = qse_awk_rtx_getawk (run); - pair = qse_map_search (functionMap, name, len); if (pair == QSE_NULL) { @@ -1495,9 +1534,11 @@ void Awk::xstrs_t::clear (awk_t* awk) { if (this->ptr != QSE_NULL) { + while (this->len > 0) + qse_awk_free (awk, this->ptr[--this->len].ptr); + qse_awk_free (awk, this->ptr); this->ptr = QSE_NULL; - this->len = 0; this->capa = 0; } } diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index 3cf9f4eb..5e6638ea 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.cpp 224 2009-07-07 13:05:10Z hyunghwan.chung $ + * $Id: StdAwk.cpp 225 2009-07-08 13:01:45Z hyunghwan.chung $ * Copyright 2006-2009 Chung, Hyung-Hwan. @@ -480,8 +480,10 @@ int StdAwk::open_console_in (Console& io) map = ((qse_awk_val_map_t*)argv)->map; QSE_ASSERT (map != QSE_NULL); + // ok to find ARGV[runarg_index] as ARGV[0] + // has been skipped. ibuflen = qse_awk_longtostr ( - rtx->awk, runarg_index + 1, + rtx->awk, runarg_index, 10, QSE_NULL, ibuf, QSE_COUNTOF(ibuf) ); @@ -622,6 +624,11 @@ int StdAwk::openConsole (Console& io) { runarg_count = 0; runarg_index = 0; + if (runarg.len > 0) + { + // skip ARGV[0] + runarg_index++; + } return open_console_in (io); } else diff --git a/qse/samples/awk/awk05.cpp b/qse/samples/awk/awk05.cpp index 2abec132..c6421646 100644 --- a/qse/samples/awk/awk05.cpp +++ b/qse/samples/awk/awk05.cpp @@ -32,7 +32,7 @@ # include