diff --git a/ase/awk/Awk.cpp b/ase/awk/Awk.cpp index 8191dd86..4b707d35 100644 --- a/ase/awk/Awk.cpp +++ b/ase/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.67 2007/10/05 15:11:30 bacon Exp $ + * $Id: Awk.cpp,v 1.68 2007/10/07 15:27:39 bacon Exp $ * * {License} */ @@ -135,6 +135,24 @@ Awk::Console::Mode Awk::Console::getMode () const // Awk::Argument ////////////////////////////////////////////////////////////////// +Awk::Argument::Argument (Run& run): run (&run), val (ASE_NULL) +{ + this->inum = 0; + this->rnum = 0.0; + + this->str.ptr = ASE_NULL; + this->str.len = 0; +} + +Awk::Argument::Argument (Run* run): run (run), val (ASE_NULL) +{ + this->inum = 0; + this->rnum = 0.0; + + this->str.ptr = ASE_NULL; + this->str.len = 0; +} + Awk::Argument::Argument (): run (ASE_NULL), val (ASE_NULL) { this->inum = 0; @@ -196,7 +214,6 @@ void Awk::Argument::clear () this->rnum = 0.0; this->inum = 0; - this->run = ASE_NULL; } void* Awk::Argument::operator new (size_t n, awk_t* awk) throw () @@ -241,21 +258,20 @@ void Awk::Argument::operator delete[] (void* ptr) ase_awk_free (*(awk_t**)p, p); } -int Awk::Argument::init (Run* run, val_t* v) +int Awk::Argument::init (val_t* v) { // this method is used internally only // and should never be called more than once - ASE_ASSERT (this->run == ASE_NULL && this->val == ASE_NULL); - ASE_ASSERT (run != ASE_NULL && v != ASE_NULL); + ASE_ASSERT (this->val == ASE_NULL); + ASE_ASSERT (v != ASE_NULL); - ase_awk_refupval (run->run, v); - this->run = run; + ase_awk_refupval (this->run->run, v); this->val = v; if (v->type == ASE_AWK_VAL_STR) { int n = ase_awk_valtonum ( - run->run, v, &this->inum, &this->rnum); + this->run->run, v, &this->inum, &this->rnum); if (n == 0) { this->rnum = (ase_real_t)this->inum; @@ -276,7 +292,7 @@ int Awk::Argument::init (Run* run, val_t* v) this->rnum = (ase_real_t)((ase_awk_val_int_t*)v)->val; this->str.ptr = ase_awk_valtostr ( - run->run, v, 0, ASE_NULL, &this->str.len); + this->run->run, v, 0, ASE_NULL, &this->str.len); if (this->str.ptr != ASE_NULL) return 0; } else if (v->type == ASE_AWK_VAL_REAL) @@ -285,7 +301,7 @@ int Awk::Argument::init (Run* run, val_t* v) this->rnum = ((ase_awk_val_real_t*)v)->val; this->str.ptr = ase_awk_valtostr ( - run->run, v, 0, ASE_NULL, &this->str.len); + this->run->run, v, 0, ASE_NULL, &this->str.len); if (this->str.ptr != ASE_NULL) return 0; } else if (v->type == ASE_AWK_VAL_NIL) @@ -294,7 +310,7 @@ int Awk::Argument::init (Run* run, val_t* v) this->rnum = 0.0; this->str.ptr = ase_awk_valtostr ( - run->run, v, 0, ASE_NULL, &this->str.len); + this->run->run, v, 0, ASE_NULL, &this->str.len); if (this->str.ptr != ASE_NULL) return 0; } else if (v->type == ASE_AWK_VAL_MAP) @@ -307,21 +323,20 @@ int Awk::Argument::init (Run* run, val_t* v) } // an error has occurred - ase_awk_refdownval (run->run, v); - this->run = ASE_NULL; + ase_awk_refdownval (this->run->run, v); this->val = ASE_NULL; return -1; } -int Awk::Argument::init (Run* run, const char_t* str, size_t len) +int Awk::Argument::init (const char_t* str, size_t len) { - ASE_ASSERT (this->run == ASE_NULL && this->val == ASE_NULL); + ASE_ASSERT (this->val == ASE_NULL); - this->run = run; this->str.ptr = (char_t*)str; this->str.len = len; - if (ase_awk_strtonum (run->run, str, len, &this->inum, &this->rnum) == 0) + if (ase_awk_strtonum (this->run->run, + str, len, &this->inum, &this->rnum) == 0) { this->rnum = (real_t)this->inum; } @@ -393,7 +408,7 @@ int Awk::Argument::getIndexed ( if (pair == ASE_NULL) return 0; // if val.init fails, it should return an error - return val.init (this->run, (val_t*)pair->val); + return val.init ((val_t*)pair->val); } int Awk::Argument::getIndexed (long_t idx, Argument& val) const @@ -437,7 +452,7 @@ int Awk::Argument::getIndexed (long_t idx, Argument& val) const if (pair == ASE_NULL) return 0; // if val.init fails, it should return an error - return val.init (this->run, (val_t*)pair->val); + return val.init ((val_t*)pair->val); } int Awk::Argument::getFirstIndex (Awk::Argument& val) const @@ -452,7 +467,7 @@ int Awk::Argument::getFirstIndex (Awk::Argument& val) const ase_awk_pair_t* pair = ase_awk_map_getfirstpair (m->map, &buckno); if (pair == ASE_NULL) return 0; // no more key - if (val.init (this->run, pair->key.ptr, pair->key.len) == -1) return -1; + if (val.init (pair->key.ptr, pair->key.len) == -1) return -1; // reuse the string field as an interator. this->str.ptr = (char_t*)pair; @@ -476,7 +491,7 @@ int Awk::Argument::getNextIndex (Awk::Argument& val) const pair = ase_awk_map_getnextpair (m->map, pair, &buckno); if (pair == ASE_NULL) return 0; - if (val.init (this->run, pair->key.ptr, pair->key.len) == -1) return -1; + if (val.init (pair->key.ptr, pair->key.len) == -1) return -1; // reuse the string field as an interator. this->str.ptr = (char_t*)pair; @@ -488,6 +503,10 @@ int Awk::Argument::getNextIndex (Awk::Argument& val) const // Awk::Return ////////////////////////////////////////////////////////////////// +Awk::Return::Return (Run& run): run(&run), val(ase_awk_val_nil) +{ +} + Awk::Return::Return (Run* run): run(run), val(ase_awk_val_nil) { } @@ -873,7 +892,7 @@ Awk::Run::Run (Awk* awk): } Awk::Run::Run (Awk* awk, run_t* run): - awk (awk), run (run), callbackFailed (false) + awk (awk), run (run), callbackFailed (false), custom (ASE_NULL) { ASE_ASSERT (this->run != ASE_NULL); } @@ -973,12 +992,29 @@ int Awk::Run::setGlobal (int id, const char_t* ptr, size_t len) return n; } +int Awk::Run::setGlobal (int id, const Return& global) +{ + ASE_ASSERT (this->run != ASE_NULL); + + return ase_awk_setglobal (this->run, id, global.toVal()); +} + int Awk::Run::getGlobal (int id, Argument& global) const { - ASE_ASSERT (run != ASE_NULL); + ASE_ASSERT (this->run != ASE_NULL); global.clear (); - return global.init ((Run*)this, ase_awk_getglobal(this->run,id)); + return global.init (ase_awk_getglobal(this->run,id)); +} + +void Awk::Run::setCustom (void* custom) +{ + this->custom = custom; +} + +void* Awk::Run::getCustom () const +{ + return this->custom; } ////////////////////////////////////////////////////////////////// @@ -1332,8 +1368,11 @@ int Awk::dispatchFunction (Run* run, const char_t* name, size_t len) for (i = 0; i < nargs; i++) { + args[i].run = run; // dirty late initialization + // due to c++ array creation limitation. + val_t* v = ase_awk_getarg (run->run, i); - if (args[i].init (run, v) == -1) + if (args[i].init (v) == -1) { run->setError (ERR_NOMEM, 0, ASE_NULL, 0); delete[] args; @@ -1440,19 +1479,19 @@ void Awk::disableRunCallback () runCallback = false; } -void Awk::onRunStart (const Run& run) +void Awk::onRunStart (Run& run) { } -void Awk::onRunEnd (const Run& run) +void Awk::onRunEnd (Run& run) { } -void Awk::onRunReturn (const Run& run, const Argument& ret) +void Awk::onRunReturn (Run& run, const Argument& ret) { } -void Awk::onRunStatement (const Run& run, size_t line) +void Awk::onRunStatement (Run& run, size_t line) { } @@ -1635,8 +1674,8 @@ void Awk::onRunReturn (run_t* run, val_t* ret, void* custom) Run* r = (Run*)custom; if (r->callbackFailed) return; - Argument x; - if (x.init (r, ret) == -1) + Argument x (r); + if (x.init (ret) == -1) { r->callbackFailed = true; } diff --git a/ase/awk/Awk.hpp b/ase/awk/Awk.hpp index 39bc850d..9eb144dc 100644 --- a/ase/awk/Awk.hpp +++ b/ase/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp,v 1.68 2007/10/05 15:11:30 bacon Exp $ + * $Id: Awk.hpp,v 1.69 2007/10/07 15:27:39 bacon Exp $ * * {License} */ @@ -289,10 +289,12 @@ public: friend class Awk; friend class Awk::Run; - Argument (); + Argument (Run& run); + Argument (Run* run); ~Argument (); protected: + Argument (); void clear (); public: @@ -315,8 +317,8 @@ public: Argument& operator= (const Argument&); protected: - int init (Run* run, val_t* v); - int init (Run* run, const char_t* str, size_t len); + int init (val_t* v); + int init (const char_t* str, size_t len); public: long_t toInt () const; @@ -350,10 +352,11 @@ public: */ class Return { - protected: + public: friend class Awk; friend class Awk::Run; + Return (Run& run); Return (Run* run); ~Return (); @@ -627,6 +630,24 @@ public: */ int setGlobal (int id, const char_t* ptr, size_t len); + + /** + * Sets the value of a global variable. The global variable + * is indicated by the first parameter. + * + * @param id + * The ID to a global variable. This value corresponds + * to the predefined global variable IDs or the value + * returned by Awk::addGlobal. + * @param global + * The reference to the value holder + * + * @return + * On success, 0 is returned. + * On failure, -1 is returned. + */ + int setGlobal (int id, const Return& global); + /** * Gets the value of a global variable. * @@ -636,7 +657,7 @@ public: * returned by Awk::addGlobal. * @param global * The reference to the value holder of a global variable - * indicated by id. The parameter is set if thie method + * indicated by id. The parameter is set if this method * returns 0. * * @return @@ -645,11 +666,22 @@ public: */ int getGlobal (int id, Argument& global) const; + + /** + * Sets a value into the custom data area + */ + void setCustom (void* custom); + + /** + * Gets the value stored in the custom data area + */ + void* getCustom () const; + protected: Awk* awk; run_t* run; - //mutable Value global; bool callbackFailed; + void* custom; }; /** Constructor */ @@ -921,10 +953,10 @@ protected: /*@}*/ // run-time callbacks - virtual void onRunStart (const Run& run); - virtual void onRunEnd (const Run& run); - virtual void onRunReturn (const Run& run, const Argument& ret); - virtual void onRunStatement (const Run& run, size_t line); + virtual void onRunStart (Run& run); + virtual void onRunEnd (Run& run); + virtual void onRunReturn (Run& run, const Argument& ret); + virtual void onRunStatement (Run& run, size_t line); // primitive handlers virtual void* allocMem (size_t n) = 0; diff --git a/ase/net/Awk.cpp b/ase/net/Awk.cpp index a6bcd214..61dceadf 100644 --- a/ase/net/Awk.cpp +++ b/ase/net/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.29 2007/10/05 15:11:30 bacon Exp $ + * $Id: Awk.cpp,v 1.30 2007/10/07 15:27:39 bacon Exp $ * * {License} */ @@ -172,19 +172,28 @@ namespace ASE this->wrapper = nullptr; } - void onRunStart (const Run& run) + void onRunStart (Run& run) { wrapper->runErrorReported = false; + Net::Awk::Context^ ctx = gcnew Net::Awk::Context (wrapper, run); + GCHandle gh = GCHandle::Alloc (ctx); + run.setCustom ((void*)GCHandle::ToIntPtr(gh)); + if (wrapper->OnRunStart != nullptr) { //wrapper->OnRunStart (wrapper); - wrapper->OnRunStart ( - gcnew Context(wrapper, run)); + wrapper->OnRunStart (ctx); } + + // TODO: exception handling when OnRunStart throws an exception. + // may need to destroy gh. or what??? } - void onRunEnd (const Run& run) + void onRunEnd (Run& run) { + System::IntPtr ip ((void*)run.getCustom ()); + GCHandle gh = GCHandle::FromIntPtr (ip); + ErrorCode code = run.getErrorCode(); if (code != ERR_NOERR) { @@ -197,29 +206,35 @@ namespace ASE if (wrapper->OnRunEnd != nullptr) { //wrapper->OnRunEnd (wrapper); - wrapper->OnRunEnd ( - gcnew Context(wrapper, run)); + wrapper->OnRunEnd ((ASE::Net::Awk::Context^)gh.Target); } + + gh.Free (); } - void onRunReturn (const Run& run, const Argument& ret) + + void onRunReturn (Run& run, const Argument& ret) { if (wrapper->OnRunReturn != nullptr) { + System::IntPtr ip ((void*)run.getCustom ()); + GCHandle gh = GCHandle::FromIntPtr (ip); + //wrapper->OnRunReturn (wrapper); - wrapper->OnRunReturn ( - gcnew Context(wrapper, run)); + wrapper->OnRunReturn ((ASE::Net::Awk::Context^)gh.Target); } } - void onRunStatement (const Run& run, size_t line) + void onRunStatement (Run& run, size_t line) { - if (wrapper->stopRequested) run.stop (); + //if (wrapper->stopRequested) run.stop (); if (wrapper->OnRunStatement != nullptr) { + System::IntPtr ip ((void*)run.getCustom ()); + GCHandle gh = GCHandle::FromIntPtr (ip); + //wrapper->OnRunStatement (wrapper); - wrapper->OnRunStatement ( - gcnew Context(wrapper, run)); + wrapper->OnRunStatement ((ASE::Net::Awk::Context^)gh.Target); } } @@ -737,7 +752,7 @@ namespace ASE bool Awk::Run (System::String^ entryPoint, cli::array^ args) { runErrorReported = false; - stopRequested = false; + //stopRequested = false; if (awk == NULL) { @@ -745,11 +760,11 @@ namespace ASE return false; } - if (OnRunStart != nullptr || OnRunEnd != nullptr || - OnRunReturn != nullptr || OnRunStatement != nullptr) - { + //if (OnRunStart != nullptr || OnRunEnd != nullptr || + // OnRunReturn != nullptr || OnRunStatement != nullptr) + //{ awk->enableRunCallback (this); - } + //} if (args == nullptr || args->Length <= 0) { @@ -854,7 +869,8 @@ namespace ASE void Awk::Stop () { - stopRequested = true; + //stopRequested = true; + // TODO: implement it... } bool Awk::AddGlobal (System::String^ name, [System::Runtime::InteropServices::Out] int% id) diff --git a/ase/net/Awk.hpp b/ase/net/Awk.hpp index 5a7c6da8..057a95e9 100644 --- a/ase/net/Awk.hpp +++ b/ase/net/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp,v 1.33 2007/10/05 15:11:30 bacon Exp $ + * $Id: Awk.hpp,v 1.34 2007/10/07 15:27:39 bacon Exp $ * * {License} */ @@ -54,6 +54,7 @@ namespace ASE } } + /* bool GetIndexedLong (System::String^ idx, [System::Runtime::InteropServices::Out] long_t% v) { @@ -85,7 +86,7 @@ namespace ASE const char_t* s = arg.toStr(&len); v = gcnew System::String (s, 0, len); return true; - } + }*/ protected: const ASE::Awk::Argument& arg; @@ -256,7 +257,7 @@ namespace ASE ref class Context { public protected: - Context (Awk^ owner, ASE::Awk::Run& run): owner (owner), run (run) + Context (Awk^ owner, const ASE::Awk::Run& run): owner (owner), run ((ASE::Awk::Run&)run) { } @@ -642,6 +643,7 @@ namespace ASE virtual bool Parse (); virtual bool Run (); virtual bool Run (System::String^ entryPoint, cli::array^ args); + virtual void Stop (); delegate void RunStartHandler (Context^ ctx); delegate void RunEndHandler (Context^ ctx); diff --git a/ase/test/awk/Awk.cpp b/ase/test/awk/Awk.cpp index 5a24ce75..8618622d 100644 --- a/ase/test/awk/Awk.cpp +++ b/ase/test/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.40 2007/10/04 04:48:27 bacon Exp $ + * $Id: Awk.cpp,v 1.41 2007/10/07 15:27:39 bacon Exp $ */ #include @@ -133,7 +133,7 @@ public: if (args[0].isIndexed()) { - Argument idx, val; + Argument idx(run), val(run); int n = args[0].getFirstIndex (idx); while (n > 0) @@ -158,7 +158,7 @@ public: { if (!args[0].isIndexed()) return 0; - Argument idx; + Argument idx (run); long_t i; int n = args[0].getFirstIndex (idx); diff --git a/ase/test/awk/aseawk.vcproj b/ase/test/awk/aseawk.vcproj index 8e4b9293..9f543ed1 100644 --- a/ase/test/awk/aseawk.vcproj +++ b/ase/test/awk/aseawk.vcproj @@ -282,38 +282,10 @@ - - - - - - - - -