added the Awk::onDemise() callback

This commit is contained in:
hyung-hwan 2015-03-12 02:08:51 +00:00
parent a212a8ebf2
commit 47a7baeb7d
4 changed files with 62 additions and 6 deletions

View File

@ -967,6 +967,13 @@ public:
/// ///
void close (); 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 /// 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. /// stream \a in and writes the parse tree to the output stream \a out.

View File

@ -88,12 +88,15 @@ public:
const char_t* ptr; 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 (); int open ();
void close (); void close ();
void uponDemise ();
Run* parse (Source& in, Source& out); Run* parse (Source& in, Source& out);
/// The setConsoleCmgr() function sets the encoding type of /// The setConsoleCmgr() function sets the encoding type of
@ -164,6 +167,7 @@ protected:
protected: protected:
qse_htb_t cmgrtab; qse_htb_t cmgrtab;
bool cmgrtab_inited; bool cmgrtab_inited;
bool stdmod_up;
qse_cmgr_t* console_cmgr; qse_cmgr_t* console_cmgr;

View File

@ -40,6 +40,7 @@ QSE_BEGIN_NAMESPACE(QSE)
struct xtn_t struct xtn_t
{ {
Awk* awk; Awk* awk;
qse_awk_ecb_t ecb;
}; };
struct rxtn_t struct rxtn_t
@ -1115,6 +1116,18 @@ void Awk::retrieveError (Run* run)
qse_awk_rtx_geterrinf (run->rtx, &errinf); 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 () int Awk::open ()
{ {
QSE_ASSERT (this->awk == QSE_NULL); QSE_ASSERT (this->awk == QSE_NULL);
@ -1142,6 +1155,8 @@ int Awk::open ()
// associate this Awk object with the underlying awk object // associate this Awk object with the underlying awk object
xtn_t* xtn = (xtn_t*) QSE_XTN (this->awk); xtn_t* xtn = (xtn_t*) QSE_XTN (this->awk);
xtn->awk = this; xtn->awk = this;
xtn->ecb.close = fini_xtn;
xtn->ecb.clear = clear_xtn;
dflerrstr = qse_awk_geterrstr (this->awk); dflerrstr = qse_awk_geterrstr (this->awk);
qse_awk_seterrstr (this->awk, xerrstr); qse_awk_seterrstr (this->awk, xerrstr);
@ -1181,6 +1196,11 @@ int Awk::open ()
#endif #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; return 0;
} }
@ -1218,7 +1238,7 @@ Awk::Run* Awk::parse (Source& in, Source& out)
return QSE_NULL; return QSE_NULL;
} }
fini_runctx (); this->fini_runctx ();
source_reader = ∈ source_reader = ∈
source_writer = (&out == &Source::NONE)? QSE_NULL: &out; source_writer = (&out == &Source::NONE)? QSE_NULL: &out;
@ -1242,8 +1262,8 @@ Awk::Run* Awk::resetRunContext ()
{ {
if (this->runctx.rtx) if (this->runctx.rtx)
{ {
fini_runctx (); this->fini_runctx ();
if (init_runctx() <= -1) return QSE_NULL; if (this->init_runctx() <= -1) return QSE_NULL;
return &this->runctx; return &this->runctx;
} }
else return QSE_NULL; else return QSE_NULL;

View File

@ -114,7 +114,11 @@ int StdAwk::open ()
goto oops; 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; this->cmgrtab_inited = false;
return 0; return 0;
@ -133,10 +137,31 @@ void StdAwk::close ()
} }
clearConsoleOutputs (); 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 (); 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) StdAwk::Run* StdAwk::parse (Source& in, Source& out)
{ {
Run* run = Awk::parse (in, out); Run* run = Awk::parse (in, out);