diff --git a/qse/include/qse/awk/Awk.hpp b/qse/include/qse/awk/Awk.hpp index 7f1536b4..7c98a9a5 100644 --- a/qse/include/qse/awk/Awk.hpp +++ b/qse/include/qse/awk/Awk.hpp @@ -967,6 +967,13 @@ public: /// void close (); + /// + /// The uponClose() function is called back after Awk::close() + /// has cleared most of the internal data but before destroying + /// the underlying awk object. + /// + virtual void uponDemise () {} + /// /// The parse() function parses the source code read from the input /// stream \a in and writes the parse tree to the output stream \a out. diff --git a/qse/include/qse/awk/StdAwk.hpp b/qse/include/qse/awk/StdAwk.hpp index 49f887ad..b90e3edb 100644 --- a/qse/include/qse/awk/StdAwk.hpp +++ b/qse/include/qse/awk/StdAwk.hpp @@ -88,12 +88,15 @@ public: const char_t* ptr; }; - StdAwk (Mmgr* mmgr = QSE_NULL): Awk(mmgr), console_cmgr(QSE_NULL) + StdAwk (Mmgr* mmgr = QSE_NULL): Awk(mmgr), stdmod_up(false), console_cmgr(QSE_NULL) { } int open (); void close (); + + void uponDemise (); + Run* parse (Source& in, Source& out); /// The setConsoleCmgr() function sets the encoding type of @@ -164,6 +167,7 @@ protected: protected: qse_htb_t cmgrtab; bool cmgrtab_inited; + bool stdmod_up; qse_cmgr_t* console_cmgr; diff --git a/qse/lib/awk/Awk.cpp b/qse/lib/awk/Awk.cpp index b29b91f1..7a2be378 100644 --- a/qse/lib/awk/Awk.cpp +++ b/qse/lib/awk/Awk.cpp @@ -40,6 +40,7 @@ QSE_BEGIN_NAMESPACE(QSE) struct xtn_t { Awk* awk; + qse_awk_ecb_t ecb; }; struct rxtn_t @@ -1115,6 +1116,18 @@ void Awk::retrieveError (Run* run) qse_awk_rtx_geterrinf (run->rtx, &errinf); } +static void fini_xtn (qse_awk_t* awk) +{ + xtn_t* xtn = (xtn_t*)qse_awk_getxtn(awk); + xtn->awk->uponDemise (); +} + +static void clear_xtn (qse_awk_t* awk) +{ + // do nothing +} + + int Awk::open () { QSE_ASSERT (this->awk == QSE_NULL); @@ -1142,6 +1155,8 @@ int Awk::open () // associate this Awk object with the underlying awk object xtn_t* xtn = (xtn_t*) QSE_XTN (this->awk); xtn->awk = this; + xtn->ecb.close = fini_xtn; + xtn->ecb.clear = clear_xtn; dflerrstr = qse_awk_geterrstr (this->awk); qse_awk_seterrstr (this->awk, xerrstr); @@ -1181,6 +1196,11 @@ int Awk::open () #endif + // push the call back after everything else is ok. + // the uponDemise() is called only if Awk::open() is fully successful. + // it won't be called when qse_awk_close() is called for functionMap + // opening failure above. + qse_awk_pushecb (this->awk, &xtn->ecb); return 0; } @@ -1218,7 +1238,7 @@ Awk::Run* Awk::parse (Source& in, Source& out) return QSE_NULL; } - fini_runctx (); + this->fini_runctx (); source_reader = ∈ source_writer = (&out == &Source::NONE)? QSE_NULL: &out; @@ -1242,8 +1262,8 @@ Awk::Run* Awk::resetRunContext () { if (this->runctx.rtx) { - fini_runctx (); - if (init_runctx() <= -1) return QSE_NULL; + this->fini_runctx (); + if (this->init_runctx() <= -1) return QSE_NULL; return &this->runctx; } else return QSE_NULL; diff --git a/qse/lib/awk/StdAwk.cpp b/qse/lib/awk/StdAwk.cpp index c83d62e8..cc7d6b18 100644 --- a/qse/lib/awk/StdAwk.cpp +++ b/qse/lib/awk/StdAwk.cpp @@ -114,7 +114,11 @@ int StdAwk::open () goto oops; } - if (qse_awk_stdmodstartup (this->awk) <= -1) goto oops; + if (!this->stdmod_up) + { + if (qse_awk_stdmodstartup (this->awk) <= -1) goto oops; + this->stdmod_up = true; + } this->cmgrtab_inited = false; return 0; @@ -133,10 +137,31 @@ void StdAwk::close () } clearConsoleOutputs (); - qse_awk_stdmodshutdown (this->awk); + + // 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(). + // + //if (this->stdmod_up) + //{ + // qse_awk_stdmodshutdown (this->awk); + // stdmod_up = false; + //} + Awk::close (); } +void StdAwk::uponDemise () +{ + if (this->stdmod_up) + { + qse_awk_stdmodshutdown (this->awk); + stdmod_up = false; + } + + Awk::uponDemise (); +} + StdAwk::Run* StdAwk::parse (Source& in, Source& out) { Run* run = Awk::parse (in, out);