added the Awk::onDemise() callback
This commit is contained in:
		| @ -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. | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user