From 756a93ff4143c6be6964b8cddcbe467f113c3457 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 12 Mar 2015 06:39:16 +0000 Subject: [PATCH] renamed Awk::uponDemise() to Awk::uponClosing and added Awk::uponClearing() --- qse/include/qse/awk/Awk.hpp | 14 ++++++++--- qse/include/qse/awk/StdAwk.hpp | 2 +- qse/include/qse/awk/awk.h | 7 ++++-- qse/lib/awk/Awk.cpp | 46 +++++++++++++++++++++------------- qse/lib/awk/StdAwk.cpp | 32 ++++++++++++++--------- qse/lib/awk/awk.c | 1 + 6 files changed, 66 insertions(+), 36 deletions(-) diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 7c98a9a5..4d64b527 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -968,11 +968,19 @@ public: void close (); /// - /// The uponClose() function is called back after Awk::close() + /// The uponClosing() function is called back after Awk::close() /// has cleared most of the internal data but before destroying - /// the underlying awk object. + /// the underlying awk object. This maps to the close callback + /// of #qse_awk_ecb_t. /// - virtual void uponDemise () {} + virtual void uponClosing (); + + /// + /// The uponClearing() function is called back when Awk::close() + /// begins clearing internal data. This maps to the clear callback + /// of #qse_awk_ecb_t. + /// + virtual void uponClearing (); /// /// The parse() function parses the source code read from the input diff --git a/qse/include/qse/awk/StdAwk.hpp b/qse/include/qse/awk/StdAwk.hpp index b90e3edb..d23de55b 100644 --- a/qse/include/qse/awk/StdAwk.hpp +++ b/qse/include/qse/awk/StdAwk.hpp @@ -95,7 +95,7 @@ public: int open (); void close (); - void uponDemise (); + void uponClosing (); Run* parse (Source& in, Source& out); diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index fef33601..ecf41032 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -923,7 +923,9 @@ struct qse_awk_mod_sym_t /** * The qse_awk_ecb_close_t type defines the callback function - * called when an awk object is closed. + * called when an awk object is closed. The qse_awk_close() function + * calls this callback function after having called qse_awk_clear() + * but before actual closing. */ typedef void (*qse_awk_ecb_close_t) ( qse_awk_t* awk /**< awk */ @@ -931,7 +933,8 @@ typedef void (*qse_awk_ecb_close_t) ( /** * The qse_awk_ecb_clear_t type defines the callback function - * called when an awk object is cleared. + * called when an awk object is cleared. The qse_awk_clear() function + * calls this calllback function before it performs actual clearing. */ typedef void (*qse_awk_ecb_clear_t) ( qse_awk_t* awk /**< awk */ diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index d03f3cd2..19a89f80 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -1068,7 +1068,7 @@ void Awk::setError (errnum_t code, const cstr_t* args, const loc_t* loc) if (awk != QSE_NULL) { qse_awk_seterror (awk, code, args, loc); - retrieveError (); + this->retrieveError (); } else { @@ -1119,15 +1119,15 @@ void Awk::retrieveError (Run* run) static void fini_xtn (qse_awk_t* awk) { xtn_t* xtn = (xtn_t*)qse_awk_getxtn(awk); - xtn->awk->uponDemise (); + xtn->awk->uponClosing (); } static void clear_xtn (qse_awk_t* awk) { - // do nothing + xtn_t* xtn = (xtn_t*)qse_awk_getxtn(awk); + xtn->awk->uponClearing (); } - int Awk::open () { QSE_ASSERT (this->awk == QSE_NULL); @@ -1142,7 +1142,7 @@ int Awk::open () prm.math.mod = mod; prm.modopen = modopen; prm.modclose = modclose; - prm.modsym = modsym; + prm.modsym = modsym; qse_awk_errnum_t errnum; this->awk = qse_awk_open (this->getMmgr(), QSE_SIZEOF(xtn_t), &prm, &errnum); @@ -1228,13 +1228,23 @@ void Awk::close () this->clearError (); } +void Awk::uponClosing () +{ + // nothing to do +} + +void Awk::uponClearing () +{ + // nothing to do +} + Awk::Run* Awk::parse (Source& in, Source& out) { QSE_ASSERT (awk != QSE_NULL); if (&in == &Source::NONE) { - setError (QSE_AWK_EINVAL); + this->setError (QSE_AWK_EINVAL); return QSE_NULL; } @@ -1250,7 +1260,7 @@ Awk::Run* Awk::parse (Source& in, Source& out) int n = qse_awk_parse (awk, &sio); if (n <= -1) { - retrieveError (); + this->retrieveError (); return QSE_NULL; } @@ -1277,7 +1287,7 @@ int Awk::loop (Value* ret) val_t* rv = qse_awk_rtx_loop (this->runctx.rtx); if (rv == QSE_NULL) { - retrieveError (&this->runctx); + this->retrieveError (&this->runctx); return -1; } @@ -1307,7 +1317,7 @@ int Awk::call ( if (ptr == QSE_NULL) { this->runctx.setError (QSE_AWK_ENOMEM); - retrieveError (&this->runctx); + this->retrieveError (&this->runctx); return -1; } } @@ -1321,7 +1331,7 @@ int Awk::call ( if (rv == QSE_NULL) { - retrieveError (&this->runctx); + this->retrieveError (&this->runctx); return -1; } @@ -1350,7 +1360,7 @@ int Awk::init_runctx () rtx_t* rtx = qse_awk_rtx_open (awk, QSE_SIZEOF(rxtn_t), &rio); if (rtx == QSE_NULL) { - retrieveError(); + this->retrieveError(); return -1; } @@ -1615,7 +1625,7 @@ int Awk::addArgument (const char_t* arg, size_t len) { QSE_ASSERT (awk != QSE_NULL); int n = runarg.add (awk, arg, len); - if (n <= -1) setError (QSE_AWK_ENOMEM); + if (n <= -1) this->setError (QSE_AWK_ENOMEM); return n; } @@ -1633,7 +1643,7 @@ int Awk::addGlobal (const char_t* name) { QSE_ASSERT (awk != QSE_NULL); int n = qse_awk_addgbl (awk, name); - if (n <= -1) retrieveError (); + if (n <= -1) this->retrieveError (); return n; } @@ -1641,7 +1651,7 @@ int Awk::deleteGlobal (const char_t* name) { QSE_ASSERT (awk != QSE_NULL); int n = qse_awk_delgbl (awk, name); - if (n <= -1) retrieveError (); + if (n <= -1) this->retrieveError (); return n; } @@ -1649,7 +1659,7 @@ int Awk::findGlobal (const char_t* name) { QSE_ASSERT (awk != QSE_NULL); int n = qse_awk_findgbl (awk, name); - if (n <= -1) retrieveError (); + if (n <= -1) this->retrieveError (); return n; } @@ -1660,12 +1670,12 @@ int Awk::setGlobal (int id, const Value& v) if (v.run != &runctx) { - setError (QSE_AWK_EINVAL); + this->setError (QSE_AWK_EINVAL); return -1; } int n = runctx.setGlobal (id, v); - if (n <= -1) retrieveError (); + if (n <= -1) this->retrieveError (); return n; } @@ -1675,7 +1685,7 @@ int Awk::getGlobal (int id, Value& v) QSE_ASSERT (runctx.rtx != QSE_NULL); int n = runctx.getGlobal (id, v); - if (n <= -1) retrieveError (); + if (n <= -1) this->retrieveError (); return n; } diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index cc7d6b18..d0622528 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -138,20 +138,27 @@ void StdAwk::close () clearConsoleOutputs (); - // I can't call qse_awk_stdmodshutdown before Awk::close() - // Fini and Unload functions need to be executed when modules - // are unloaded. This should be done in StdAwk::uponDemise(). + // + // StdAwk called qse_awk_stdmodstartup() after Awk::open(). + // It's logical to call qse_awk_stdmodshutdown() Awk::close(). + // but Awk::close() still needs to call some module's fini and + // unload functions. So it must be done in StdAwk::uponClosing() + // which is called after modules have been unloaded but while + // the underlying awk object is still alive. + // + // See StdAwk::uponClosing() below. // //if (this->stdmod_up) //{ // qse_awk_stdmodshutdown (this->awk); // stdmod_up = false; //} + // Awk::close (); } -void StdAwk::uponDemise () +void StdAwk::uponClosing () { if (this->stdmod_up) { @@ -159,7 +166,8 @@ void StdAwk::uponDemise () stdmod_up = false; } - Awk::uponDemise (); + // chain up + Awk::uponClosing (); } StdAwk::Run* StdAwk::parse (Source& in, Source& out) @@ -207,7 +215,7 @@ int StdAwk::build_argcv (Run* run) this->runarg.ptr[i].ptr, this->runarg.ptr[i].len, true) <= -1) return -1; } - + run->setGlobal (this->gbl_argc, (int_t)this->runarg.len); run->setGlobal (this->gbl_argv, argv); return 0; @@ -251,9 +259,9 @@ int StdAwk::__build_environ (Run* run, void* envptr) /* mbstowcsdup() may fail for invalid encoding. * so setting the error code to ENOMEM may not * be really accurate */ - setError (QSE_AWK_ENOMEM); + this->setError (QSE_AWK_ENOMEM); return -1; - } + } *eq = QSE_MT('='); #else @@ -272,9 +280,9 @@ int StdAwk::__build_environ (Run* run, void* envptr) /* mbstowcsdup() may fail for invalid encoding. * so setting the error code to ENOMEM may not * be really accurate */ - setError (QSE_AWK_ENOMEM); + this->setError (QSE_AWK_ENOMEM); return -1; - } + } *eq = QSE_WT('='); #endif @@ -302,7 +310,7 @@ int StdAwk::build_environ (Run* run) if (qse_env_init (&env, ((Awk*)*run)->getMmgr(), 1) <= -1) { - setError (QSE_AWK_ENOMEM); + this->setError (QSE_AWK_ENOMEM); return -1; } @@ -354,7 +362,7 @@ StdAwk::ioattr_t* StdAwk::find_or_make_ioattr (const char_t* ptr, size_t len) QSE_SIZEOF(StdAwk::default_ioattr)); if (pair == QSE_NULL) { - setError (QSE_AWK_ENOMEM); + this->setError (QSE_AWK_ENOMEM); return QSE_NULL; } } diff --git a/qse/lib/awk/awk.c b/qse/lib/awk/awk.c index ed96dc2d..632987d6 100644 --- a/qse/lib/awk/awk.c +++ b/qse/lib/awk/awk.c @@ -325,6 +325,7 @@ void qse_awk_clear (qse_awk_t* awk) clear_token (&awk->ntok); clear_token (&awk->ptok); + /* clear all loaded modules */ qse_rbt_walk (awk->modtab, unload_module, awk); qse_rbt_clear (awk->modtab);