From 9312940dfa385a0a4cdff4ac336200e0ff92a7df Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 25 Sep 2007 00:12:00 +0000 Subject: [PATCH] Recovered from cvs revision 2007-09-24 08:21:00 --- ase/awk/Awk.cpp | 178 ++++++++++++++++++++++++++++++++++------ ase/awk/Awk.hpp | 111 ++++++++++++++++++++++--- ase/awk/Awk.java | 10 +-- ase/awk/StdAwk.cpp | 72 ++++++++-------- ase/awk/StdAwk.hpp | 32 ++++---- ase/awk/awk.c | 14 +++- ase/awk/awk.h | 55 ++++++++++--- ase/awk/awk_i.h | 6 +- ase/awk/err.c | 8 +- ase/awk/func.c | 7 +- ase/awk/jni.c | 14 ++-- ase/awk/jni.def | 4 +- ase/awk/jni.h | 6 +- ase/awk/parse.c | 92 ++++++++++++++++++--- ase/awk/parse.h | 4 +- ase/awk/run.c | 18 ++-- ase/awk/run.h | 6 +- ase/awk/tab.c | 36 ++++---- ase/awk/tab.h | 9 +- ase/awk/tree.h | 4 +- ase/awk/val.c | 12 +-- ase/awk/val.h | 4 +- ase/change.log | 13 ++- ase/com/Awk.cpp | 4 +- ase/net/Awk.cpp | 67 +++++++++++++-- ase/net/Awk.hpp | 10 ++- ase/test/awk/Awk.cpp | 25 ++++-- ase/test/awk/awk.c | 4 +- ase/test/net/AwkForm.cs | Bin 9954 -> 9962 bytes 29 files changed, 620 insertions(+), 205 deletions(-) diff --git a/ase/awk/Awk.cpp b/ase/awk/Awk.cpp index 13102d2b..d17bc1f2 100644 --- a/ase/awk/Awk.cpp +++ b/ase/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.55 2007/09/21 15:29:51 bacon Exp $ + * $Id: Awk.cpp,v 1.56 2007/09/23 16:48:55 bacon Exp $ */ @@ -140,6 +140,11 @@ Awk::Argument::Argument (): run (ASE_NULL), val (ASE_NULL) } Awk::Argument::~Argument () +{ + clear (); +} + +void Awk::Argument::clear () { if (this->str.ptr != ASE_NULL) { @@ -154,6 +159,7 @@ Awk::Argument::~Argument () { ASE_ASSERT (this->run != ASE_NULL); ase_awk_refdownval (this->run, this->val); + this->val = ASE_NULL; } } @@ -289,7 +295,7 @@ const Awk::char_t* Awk::Argument::toStr (size_t* len) const // Awk::Return ////////////////////////////////////////////////////////////////// -Awk::Return::Return (run_t* run): run (run), type (ASE_AWK_VAL_NIL) +Awk::Return::Return (awk_t* awk): awk(awk), type (ASE_AWK_VAL_NIL) { } @@ -298,22 +304,24 @@ Awk::Return::~Return () clear (); } -Awk::val_t* Awk::Return::toVal () const +Awk::val_t* Awk::Return::toVal (run_t* run) const { + ASE_ASSERT (run != ASE_NULL); + switch (this->type) { case ASE_AWK_VAL_NIL: return ase_awk_val_nil; case ASE_AWK_VAL_INT: - return ase_awk_makeintval (this->run, this->v.inum); + return ase_awk_makeintval (run, this->v.inum); case ASE_AWK_VAL_REAL: - return ase_awk_makerealval (this->run, this->v.rnum); + return ase_awk_makerealval (run, this->v.rnum); case ASE_AWK_VAL_STR: return ase_awk_makestrval ( - this->run, this->v.str.ptr, this->v.str.len); + run, this->v.str.ptr, this->v.str.len); } return ASE_NULL; @@ -341,7 +349,6 @@ int Awk::Return::set (real_t v) int Awk::Return::set (const char_t* ptr, size_t len) { - awk_t* awk = ase_awk_getrunawk(this->run); char_t* tmp = ase_awk_strxdup (awk, ptr, len); if (tmp == ASE_NULL) return -1; @@ -359,7 +366,6 @@ void Awk::Return::clear () if (this->type == ASE_AWK_VAL_STR) { ASE_ASSERT (this->v.str.ptr != ASE_NULL); - awk_t* awk = ase_awk_getrunawk(this->run); ase_awk_free (awk, this->v.str.ptr); this->v.str.ptr = ASE_NULL; this->v.str.len = 0; @@ -368,7 +374,6 @@ void Awk::Return::clear () this->type = ASE_AWK_VAL_NIL; } - ////////////////////////////////////////////////////////////////// // Awk::Run ////////////////////////////////////////////////////////////////// @@ -378,6 +383,16 @@ Awk::Run::Run (Awk* awk): { } +Awk::Run::Run (Awk* awk, run_t* run): + awk (awk), run (run), callbackFailed (false) +{ + ASE_ASSERT (this->run != ASE_NULL); +} + +Awk::Run::~Run () +{ +} + int Awk::Run::stop () const { ASE_ASSERT (this->run != ASE_NULL); @@ -402,6 +417,68 @@ const Awk::char_t* Awk::Run::getErrorMessage () const return ase_awk_getrunerrmsg (this->run); } +int Awk::Run::setGlobal (int id, long_t v) +{ + ASE_ASSERT (this->run != ASE_NULL); + + ase_awk_val_t* tmp = ase_awk_makeintval (run, v); + if (tmp == ASE_NULL) + { + ase_awk_setrunerror ( + this->run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0); + return -1; + } + + ase_awk_refupval (run, tmp); + int n = ase_awk_setglobal (this->run, id, tmp); + ase_awk_refdownval (run, tmp); + return n; +} + +int Awk::Run::setGlobal (int id, real_t v) +{ + ASE_ASSERT (this->run != ASE_NULL); + + ase_awk_val_t* tmp = ase_awk_makerealval (run, v); + if (tmp == ASE_NULL) + { + ase_awk_setrunerror ( + this->run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0); + return -1; + } + + ase_awk_refupval (run, tmp); + int n = ase_awk_setglobal (this->run, id, tmp); + ase_awk_refdownval (run, tmp); + return n; +} + +int Awk::Run::setGlobal (int id, const char_t* ptr, size_t len) +{ + ASE_ASSERT (run != ASE_NULL); + + ase_awk_val_t* tmp = ase_awk_makestrval (run, ptr, len); + if (tmp == ASE_NULL) + { + ase_awk_setrunerror ( + this->run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0); + return -1; + } + + ase_awk_refupval (run, tmp); + int n = ase_awk_setglobal (this->run, id, tmp); + ase_awk_refdownval (run, tmp); + return n; +} + +int Awk::Run::getGlobal (int id, Argument& global) const +{ + ASE_ASSERT (run != ASE_NULL); + + global.clear (); + return global.init (run,ase_awk_getglobal (this->run, id)); +} + ////////////////////////////////////////////////////////////////// // Awk ////////////////////////////////////////////////////////////////// @@ -667,7 +744,7 @@ int Awk::run (const char_t* main, const char_t** args, size_t nargs) ase_awk_runios_t runios; ase_awk_runcbs_t runcbs; ase_awk_runarg_t* runarg = ASE_NULL; - Run emptyRun (this); + Run runForCallback (this); runios.pipe = pipeHandler; runios.coproc = ASE_NULL; @@ -681,7 +758,7 @@ int Awk::run (const char_t* main, const char_t** args, size_t nargs) runcbs.on_end = onRunEnd; runcbs.on_return = onRunReturn; runcbs.on_statement = onRunStatement; - runcbs.custom_data = &emptyRun; + runcbs.custom_data = &runForCallback; } if (nargs > 0) @@ -727,8 +804,7 @@ int Awk::run (const char_t* main, const char_t** args, size_t nargs) return n; } -int Awk::dispatchFunction ( - run_t* run, const char_t* name, size_t len) +int Awk::dispatchFunction (run_t* run, const char_t* name, size_t len) { pair_t* pair; awk_t* awk; @@ -736,7 +812,17 @@ int Awk::dispatchFunction ( awk = ase_awk_getrunawk (run); pair = ase_awk_map_get (functionMap, name, len); - if (pair == ASE_NULL) return -1; + if (pair == ASE_NULL) + { + ase_cstr_t errarg; + + errarg.ptr = name; + errarg.len = len; + + ase_awk_setrunerror ( + run, ASE_AWK_EFNNONE, 0, &errarg, 1); + return -1; + } FunctionHandler handler; handler = *(FunctionHandler*)ASE_AWK_PAIR_VAL(pair); @@ -746,32 +832,68 @@ int Awk::dispatchFunction ( //Argument* args = ASE_NULL; //try { args = new Argument [nargs]; } catch (...) {} Argument* args = new(awk) Argument[nargs]; - if (args == ASE_NULL) return -1; + if (args == ASE_NULL) + { + ase_awk_setrunerror ( + run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0); + return -1; + } for (i = 0; i < nargs; i++) { val_t* v = ase_awk_getarg (run, i); if (args[i].init (run, v) == -1) { + ase_awk_setrunerror ( + run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0); delete[] args; return -1; } } - Return ret (run); - int n = (this->*handler) (&ret, args, nargs, name, len); + Run runForFunction (this, run); + Return ret (awk); + + int n = (this->*handler) (runForFunction, ret, args, nargs, name, len); delete[] args; - if (n <= -1) return -1; + if (n <= -1) + { + /* this is really the handler error. the underlying engine + * will take care of the error code. */ + return -1; + } - val_t* r = ret.toVal (); - if (r == ASE_NULL) return -1; + val_t* r = ret.toVal (run); + if (r == ASE_NULL) + { + ase_awk_setrunerror ( + run, ASE_AWK_ENOMEM, 0, ASE_NULL, 0); + return -1; + } ase_awk_setretval (run, r); return 0; } +int Awk::addGlobal (const char_t* name) +{ + ASE_ASSERT (awk != ASE_NULL); + + int n = ase_awk_addglobal (awk, name, ase_strlen(name)); + if (n == -1) retrieveError (); + return n; +} + +int Awk::deleteGlobal (const char_t* name) +{ + ASE_ASSERT (awk != ASE_NULL); + int n = ase_awk_delglobal (awk, name, ase_strlen(name)); + if (n == -1) retrieveError (); + return n; +} + int Awk::addFunction ( const char_t* name, size_t minArgs, size_t maxArgs, FunctionHandler handler) @@ -791,7 +913,7 @@ int Awk::addFunction ( size_t nameLen = ase_strlen(name); - void* p = ase_awk_addbfn (awk, name, nameLen, + void* p = ase_awk_addfunc (awk, name, nameLen, 0, minArgs, maxArgs, ASE_NULL, functionHandler); if (p == ASE_NULL) @@ -804,7 +926,7 @@ int Awk::addFunction ( pair_t* pair = ase_awk_map_put (functionMap, name, nameLen, tmp); if (pair == ASE_NULL) { - ase_awk_delbfn (awk, name, nameLen); + ase_awk_delfunc (awk, name, nameLen); ase_awk_free (awk, tmp); setError (ERR_NOMEM); @@ -820,7 +942,7 @@ int Awk::deleteFunction (const char_t* name) size_t nameLen = ase_strlen(name); - int n = ase_awk_delbfn (awk, name, nameLen); + int n = ase_awk_delfunc (awk, name, nameLen); if (n == 0) ase_awk_map_remove (functionMap, name, nameLen); else retrieveError (); @@ -1000,7 +1122,15 @@ void Awk::freeFunctionMapValue (void* owner, void* value) void Awk::onRunStart (run_t* run, void* custom) { Run* r = (Run*)custom; - r->run = run; + + // the actual run_t value for the run-time callback is set here. + // r here refers to runForCallback declared in Awk::run and is + // different from a Run instance available from intrinsic function + // handlers (runForFunction in dispatchFunction). however, all methods + // of the Run class will still work as intended in all places once + // r->run is set properly here. + // NOTE: I admit this strategy is ugly. + r->run = run; r->callbackFailed = false; r->awk->onRunStart (*r); diff --git a/ase/awk/Awk.hpp b/ase/awk/Awk.hpp index 29a42035..cf8af4ad 100644 --- a/ase/awk/Awk.hpp +++ b/ase/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp,v 1.57 2007/09/22 14:40:44 bacon Exp $ + * $Id: Awk.hpp,v 1.58 2007/09/23 16:48:55 bacon Exp $ */ #ifndef _ASE_AWK_AWK_HPP_ @@ -276,6 +276,8 @@ public: char_t* filename; }; + class Run; + /** * Represents an argument to an intrinsic function */ @@ -283,10 +285,13 @@ public: { protected: friend class Awk; + friend class Awk::Run; Argument (); ~Argument (); + void clear (); + // initialization void* operator new (size_t n, awk_t* awk) throw (); void* operator new[] (size_t n, awk_t* awk) throw (); @@ -335,19 +340,20 @@ public: protected: friend class Awk; - Return (run_t* run); + Return (awk_t* awk); ~Return (); - val_t* toVal () const; + val_t* toVal (run_t* run) const; public: int set (long_t v); int set (real_t v); int set (const char_t* ptr, size_t len); + void clear (); protected: - run_t* run; + awk_t* awk; int type; union @@ -357,13 +363,12 @@ public: struct { - char_t* ptr; - size_t len; + char_t* ptr; + size_t len; } str; } v; }; - // generated by generrcode.awk /** Defines the error code */ enum ErrorCode @@ -534,6 +539,8 @@ public: friend class Awk; Run (Awk* awk); + Run (Awk* awk, run_t* run); + ~Run (); public: int stop () const; @@ -542,9 +549,79 @@ public: size_t getErrorLine () const; const char_t* getErrorMessage () const; + /** + * 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 v + * The value to assign to the global variable. + * + * @return + * On success, 0 is returned. + * On failure, -1 is returned. + */ + int setGlobal (int id, long_t v); + + /** + * 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 v + * The value to assign to the global variable. + * + * @return + * On success, 0 is returned. + * On failure, -1 is returned. + */ + int setGlobal (int id, real_t v); + + /** + * 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 ptr The pointer to a character array + * @param len The number of characters in the array + * + * @return + * On success, 0 is returned. + * On failure, -1 is returned. + */ + int setGlobal (int id, const char_t* ptr, size_t len); + + /** + * Gets the value of a global variable. + * + * @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 of a global variable + * indicated by id. The parameter is set if thie method + * returns 0. + * + * @return + * On success, 0 is returned. + * On failure, -1 is returned. + */ + int getGlobal (int id, Argument& global) const; + protected: Awk* awk; run_t* run; + //mutable Value global; bool callbackFailed; }; @@ -668,23 +745,33 @@ public: const char_t** args = ASE_NULL, size_t nargs = 0); /** - * Represents a user-defined function + * Adds a intrinsic global variable. + */ + virtual int addGlobal (const char_t* name); + + /** + * Deletes a intrinsic global variable. + */ + virtual int deleteGlobal (const char_t* name); + + /** + * Represents a user-defined intrinsic function. */ typedef int (Awk::*FunctionHandler) ( - Return* ret, const Argument* args, size_t nargs, + Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); /** - * Adds a new user-defined function + * Adds a new user-defined intrinsic function. */ virtual int addFunction ( const char_t* name, size_t minArgs, size_t maxArgs, FunctionHandler handler); /** - * Deletes a user-defined function + * Deletes a user-defined intrinsic function */ - virtual int deleteFunction (const char_t* main); + virtual int deleteFunction (const char_t* name); /** * Enables the run-time callback diff --git a/ase/awk/Awk.java b/ase/awk/Awk.java index d1ed9b3d..aaeab00b 100644 --- a/ase/awk/Awk.java +++ b/ase/awk/Awk.java @@ -1,5 +1,5 @@ /* - * $Id: Awk.java,v 1.13 2007/08/26 14:33:38 bacon Exp $ + * $Id: Awk.java,v 1.14 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -77,9 +77,9 @@ public abstract class Awk private native void setword (String ow, String nw); - private native void addbfn ( + private native void addfunc ( String name, int min_args, int max_args) throws Exception; - private native void delbfn (String name) throws Exception; + private native void delfunc (String name) throws Exception; native void setfilename ( long runid, String name) throws Exception; @@ -115,12 +115,12 @@ public abstract class Awk public void addFunction ( String name, int min_args, int max_args) throws Exception { - addbfn (name, min_args, max_args); + addfunc (name, min_args, max_args); } public void deleteFunction (String name) throws Exception { - delbfn (name); + delfunc (name); } protected long builtinFunctionArgumentToLong ( diff --git a/ase/awk/StdAwk.cpp b/ase/awk/StdAwk.cpp index f4aab16d..5bf849be 100644 --- a/ase/awk/StdAwk.cpp +++ b/ase/awk/StdAwk.cpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.cpp,v 1.26 2007/09/07 05:40:16 bacon Exp $ + * $Id: StdAwk.cpp,v 1.27 2007/09/23 16:48:55 bacon Exp $ */ #include @@ -62,73 +62,73 @@ int StdAwk::open () return 0; } -int StdAwk::sin (Return* ret, const Argument* args, size_t nargs, +int StdAwk::sin (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::sin(args[0].toReal())); + return ret.set ((real_t)::sin(args[0].toReal())); } -int StdAwk::cos (Return* ret, const Argument* args, size_t nargs, +int StdAwk::cos (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::cos(args[0].toReal())); + return ret.set ((real_t)::cos(args[0].toReal())); } -int StdAwk::tan (Return* ret, const Argument* args, size_t nargs, +int StdAwk::tan (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::tan(args[0].toReal())); + return ret.set ((real_t)::tan(args[0].toReal())); } -int StdAwk::atan (Return* ret, const Argument* args, size_t nargs, +int StdAwk::atan (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::atan(args[0].toReal())); + return ret.set ((real_t)::atan(args[0].toReal())); } -int StdAwk::atan2 (Return* ret, const Argument* args, size_t nargs, +int StdAwk::atan2 (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::atan2(args[0].toReal(), args[1].toReal())); + return ret.set ((real_t)::atan2(args[0].toReal(), args[1].toReal())); } -int StdAwk::log (Return* ret, const Argument* args, size_t nargs, +int StdAwk::log (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::log(args[0].toReal())); + return ret.set ((real_t)::log(args[0].toReal())); } -int StdAwk::exp (Return* ret, const Argument* args, size_t nargs, +int StdAwk::exp (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::exp(args[0].toReal())); + return ret.set ((real_t)::exp(args[0].toReal())); } -int StdAwk::sqrt (Return* ret, const Argument* args, size_t nargs, +int StdAwk::sqrt (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((real_t)::sqrt(args[0].toReal())); + return ret.set ((real_t)::sqrt(args[0].toReal())); } -int StdAwk::fnint (Return* ret, const Argument* args, size_t nargs, +int StdAwk::fnint (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set (args[0].toInt()); + return ret.set (args[0].toInt()); } -int StdAwk::rand (Return* ret, const Argument* args, size_t nargs, +int StdAwk::rand (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((long_t)::rand()); + return ret.set ((long_t)::rand()); } -int StdAwk::srand (Return* ret, const Argument* args, size_t nargs, +int StdAwk::srand (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { unsigned int prevSeed = seed; seed = (unsigned int)args[0].toInt(); ::srand (seed); - return ret->set ((long_t)prevSeed); + return ret.set ((long_t)prevSeed); } #if defined(_WIN32) && defined(_MSC_VER) && (_MSC_VER>=1400) @@ -138,13 +138,13 @@ int StdAwk::srand (Return* ret, const Argument* args, size_t nargs, #define gmtime _gmtime64 #endif -int StdAwk::systime (Return* ret, const Argument* args, size_t nargs, +int StdAwk::systime (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return ret->set ((long_t)::time(NULL)); + return ret.set ((long_t)::time(NULL)); } -int StdAwk::strftime (Return* ret, const Argument* args, size_t nargs, +int StdAwk::strftime (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { const char_t* fmt; @@ -168,10 +168,10 @@ int StdAwk::strftime (Return* ret, const Argument* args, size_t nargs, size_t l = ::wcsftime (buf, ASE_COUNTOF(buf), fmt, tm); #endif - return ret->set (buf, l); + return ret.set (buf, l); } -int StdAwk::strfgmtime (Return* ret, const Argument* args, size_t nargs, +int StdAwk::strfgmtime (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { const char_t* fmt; @@ -195,27 +195,31 @@ int StdAwk::strfgmtime (Return* ret, const Argument* args, size_t nargs, size_t l = ::wcsftime (buf, ASE_COUNTOF(buf), fmt, tm); #endif - return ret->set (buf, l); + return ret.set (buf, l); } -int StdAwk::system (Return* ret, const Argument* args, size_t nargs, +int StdAwk::system (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { size_t l; const char_t* ptr = args[0].toStr(&l); #ifdef _WIN32 - return ret->set ((long_t)::_tsystem(ptr)); + return ret.set ((long_t)::_tsystem(ptr)); #elif defined(ASE_CHAR_IS_MCHAR) - return ret->set ((long_t)::system(ptr)); + return ret.set ((long_t)::system(ptr)); #else char* mbs = (char*)ase_awk_malloc (awk, l*5+1); if (mbs == ASE_NULL) return -1; ::size_t mbl = ::wcstombs (mbs, ptr, l*5); - if (mbl == (::size_t)-1) return -1; + if (mbl == (::size_t)-1) + { + ase_awk_free (awk, mbs); + return -1; + } mbs[mbl] = '\0'; - int n = ret->set ((long_t)::system(mbs)); + int n = ret.set ((long_t)::system(mbs)); ase_awk_free (awk, mbs); return n; diff --git a/ase/awk/StdAwk.hpp b/ase/awk/StdAwk.hpp index 34231ee7..0e498d96 100644 --- a/ase/awk/StdAwk.hpp +++ b/ase/awk/StdAwk.hpp @@ -1,5 +1,5 @@ /* - * $Id: StdAwk.hpp,v 1.15 2007/09/22 14:40:44 bacon Exp $ + * $Id: StdAwk.hpp,v 1.16 2007/09/23 16:48:55 bacon Exp $ */ #ifndef _ASE_AWK_STDAWK_HPP_ @@ -25,35 +25,35 @@ public: protected: // intrinsic functions - int sin (Return* ret, const Argument* args, size_t nargs, + int sin (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int cos (Return* ret, const Argument* args, size_t nargs, + int cos (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int tan (Return* ret, const Argument* args, size_t nargs, + int tan (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int atan (Return* ret, const Argument* args, size_t nargs, + int atan (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int atan2 (Return* ret, const Argument* args, size_t nargs, + int atan2 (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int log (Return* ret, const Argument* args, size_t nargs, + int log (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int exp (Return* ret, const Argument* args, size_t nargs, + int exp (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int sqrt (Return* ret, const Argument* args, size_t nargs, + int sqrt (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int fnint (Return* ret, const Argument* args, size_t nargs, + int fnint (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int rand (Return* ret, const Argument* args, size_t nargs, + int rand (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int srand (Return* ret, const Argument* args, size_t nargs, + int srand (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int systime (Return* ret, const Argument* args, size_t nargs, + int systime (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int strftime (Return* ret, const Argument* args, size_t nargs, + int strftime (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int strfgmtime (Return* ret, const Argument* args, size_t nargs, + int strfgmtime (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); - int system (Return* ret, const Argument* args, size_t nargs, + int system (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len); // pipe io handlers diff --git a/ase/awk/awk.c b/ase/awk/awk.c index 30e32365..6b06af6d 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.8 2007/07/25 07:00:09 bacon Exp $ + * $Id: awk.c,v 1.9 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -150,6 +150,18 @@ ase_awk_t* ase_awk_open (const ase_awk_prmfns_t* prmfns, void* custom_data) awk->custom_data = custom_data; + if (ase_awk_initglobals (awk) == -1) + { + ase_awk_tab_close (&awk->parse.params); + ase_awk_tab_close (&awk->parse.locals); + ase_awk_tab_close (&awk->parse.globals); + ase_awk_map_close (awk->tree.afns); + ase_awk_map_close (awk->kwtab); + ase_str_close (&awk->token.name); + ASE_AWK_FREE (awk, awk); + return ASE_NULL; + } + return awk; } diff --git a/ase/awk/awk.h b/ase/awk/awk.h index bcc1e960..df597d63 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.11 2007/09/23 04:20:22 bacon Exp $ + * $Id: awk.h,v 1.12 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -260,7 +260,7 @@ enum ase_awk_errnum_t ASE_AWK_EBLKEND, /* END requires an action block */ ASE_AWK_EDUPBEG, /* duplicate BEGIN */ ASE_AWK_EDUPEND, /* duplicate END */ - ASE_AWK_EBFNRED, /* builtin function redefined */ + ASE_AWK_EBFNRED, /* intrinsic function redefined */ ASE_AWK_EAFNRED, /* function redefined */ ASE_AWK_EGBLRED, /* global variable redefined */ ASE_AWK_EPARRED, /* parameter redefined */ @@ -292,7 +292,7 @@ enum ase_awk_errnum_t ASE_AWK_EPOSIDX, /* wrong position index */ ASE_AWK_EARGTF, /* too few arguments */ ASE_AWK_EARGTM, /* too many arguments */ - ASE_AWK_EFNNONE, /* no such function */ + ASE_AWK_EFNNONE, /* "function '%.*s' not found" */ ASE_AWK_ENOTIDX, /* variable not indexable */ ASE_AWK_ENOTDEL, /* variable not deletable */ ASE_AWK_ENOTMAP, /* value not a map */ @@ -311,8 +311,8 @@ enum ase_awk_errnum_t ASE_AWK_ERNEXTEND, /* next called from END */ ASE_AWK_ERNEXTFBEG, /* nextfile called from BEGIN */ ASE_AWK_ERNEXTFEND, /* nextfile called from END */ - ASE_AWK_EBFNUSER, /* wrong builtin function implementation */ - ASE_AWK_EBFNIMPL, /* builtin function handler failed */ + ASE_AWK_EBFNUSER, /* wrong intrinsic function implementation */ + ASE_AWK_EBFNIMPL, /* intrinsic function handler failed */ ASE_AWK_EIOUSER, /* wrong user io handler implementation */ ASE_AWK_EIONONE, /* no such io name found */ ASE_AWK_EIOIMPL, /* i/o callback returned an error */ @@ -425,8 +425,8 @@ int ase_awk_setword (ase_awk_t* awk, int ase_awk_parse (ase_awk_t* awk, ase_awk_srcios_t* srcios); /* - * Adds an intrinsic global variable. It should be called before a call - * to ase_awk_parse. + * Adds an intrinsic global variable. It should be called in + * add_globals_callback. * * @return * On success, the ID of the global variable added is returned. @@ -434,6 +434,15 @@ int ase_awk_parse (ase_awk_t* awk, ase_awk_srcios_t* srcios); */ int ase_awk_addglobal (ase_awk_t* awk, const ase_char_t* name, ase_size_t len); +/* + * Deletes a instrinsic global variable. + * + * @return + * On success, 0 is returned. + * On failure, -1 is returned. + */ +int ase_awk_delglobal (ase_awk_t* awk, const ase_char_t* name, ase_size_t len); + /* * ase_awk_run return 0 on success and -1 on failure, generally speaking. * A runtime context is required for it to start running the program. @@ -458,8 +467,30 @@ int ase_awk_stop (ase_awk_run_t* run); /* functions to access internal stack structure */ ase_size_t ase_awk_getnargs (ase_awk_run_t* run); ase_awk_val_t* ase_awk_getarg (ase_awk_run_t* run, ase_size_t idx); -ase_awk_val_t* ase_awk_getglobal (ase_awk_run_t* run, ase_size_t idx); -int ase_awk_setglobal (ase_awk_run_t* run, ase_size_t idx, ase_awk_val_t* val); + +/** + * Gets the value of a global variable. + * + * @param run A run-time context + * @param id The ID to a global variable. + * This value correspondsto the predefined global variable IDs or + * the value returned by ase_awk_addglobal. + * @return + * The pointer to a value is returned. This function never fails + * so long as id is valid. Otherwise, you may fall into trouble. + */ +ase_awk_val_t* ase_awk_getglobal (ase_awk_run_t* run, int id); +int ase_awk_setglobal (ase_awk_run_t* run, int id, ase_awk_val_t* val); + +/** + * Sets the return value of a function from within a function handler. + * + * @param run A run-time context + * @param val A pointer to the value to set. + * ase_awk_refupval and ase_awk_refdownval are not needed because + * ase_awk_setretval never fails and it updates the reference count + * of the value properly. + */ void ase_awk_setretval (ase_awk_run_t* run, ase_awk_val_t* val); int ase_awk_setfilename ( @@ -487,14 +518,14 @@ void ase_awk_setrunerror ( ase_awk_run_t* run, int errnum, ase_size_t errlin, const ase_cstr_t* errarg, ase_size_t argcnt); -/* functions to manipulate built-in functions */ -void* ase_awk_addbfn ( +/* functions to manipulate intrinsic functions */ +void* ase_awk_addfunc ( ase_awk_t* awk, const ase_char_t* name, ase_size_t name_len, int when_valid, ase_size_t min_args, ase_size_t max_args, const ase_char_t* arg_spec, int (*handler)(ase_awk_run_t*,const ase_char_t*,ase_size_t)); -int ase_awk_delbfn ( +int ase_awk_delfunc ( ase_awk_t* awk, const ase_char_t* name, ase_size_t name_len); void ase_awk_clrbfn (ase_awk_t* awk); diff --git a/ase/awk/awk_i.h b/ase/awk/awk_i.h index b2f193da..e521f180 100644 --- a/ase/awk/awk_i.h +++ b/ase/awk/awk_i.h @@ -1,5 +1,5 @@ /* - * $Id: awk_i.h,v 1.6 2007/06/17 09:29:46 bacon Exp $ + * $Id: awk_i.h,v 1.7 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -55,7 +55,7 @@ typedef struct ase_awk_tree_t ase_awk_tree_t; struct ase_awk_tree_t { ase_size_t nglobals; /* total number of globals */ - ase_size_t nbglobals; /* number of builtin globals */ + ase_size_t nbglobals; /* number of intrinsic globals */ ase_cstr_t cur_afn; ase_awk_map_t* afns; /* awk function map */ ase_awk_nde_t* begin; @@ -156,7 +156,7 @@ struct ase_awk_t ase_size_t column; } token; - /* builtin functions */ + /* intrinsic functions */ struct { ase_awk_bfn_t* sys; diff --git a/ase/awk/err.c b/ase/awk/err.c index cf4cafd7..c55e92ff 100644 --- a/ase/awk/err.c +++ b/ase/awk/err.c @@ -1,5 +1,5 @@ /* - * $Id: err.c,v 1.6 2007/08/24 13:17:59 bacon Exp $ + * $Id: err.c,v 1.7 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -74,7 +74,7 @@ static const ase_char_t* __geterrstr (int errnum) ASE_T("END not followed by a left bracket on the same line"), ASE_T("duplicate BEGIN"), ASE_T("duplicate END"), - ASE_T("built-in function '%.*s' redefined"), + ASE_T("intrinsic function '%.*s' redefined"), ASE_T("function '%.*s' redefined"), ASE_T("global variable '%.*s' redefined"), ASE_T("parameter '%.*s' redefined"), @@ -123,8 +123,8 @@ static const ase_char_t* __geterrstr (int errnum) ASE_T("next statement called from the END block"), ASE_T("nextfile statement called from the BEGIN block"), ASE_T("nextfile statement called from the END block"), - ASE_T("wrong implementation of built-in function handler"), - ASE_T("built-in function handler returned an error"), + ASE_T("wrong implementation of intrinsic function handler"), + ASE_T("intrinsic function handler returned an error"), ASE_T("wrong implementation of user-defined io handler"), ASE_T("no such io name found"), ASE_T("i/o handler returned an error"), diff --git a/ase/awk/func.c b/ase/awk/func.c index 3fce5b11..1ac44fb7 100644 --- a/ase/awk/func.c +++ b/ase/awk/func.c @@ -1,5 +1,5 @@ /* - * $Id: func.c,v 1.8 2007/08/26 14:33:38 bacon Exp $ + * $Id: func.c,v 1.9 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -43,7 +43,7 @@ static ase_awk_bfn_t __sys_bfn[] = { {ASE_NULL, 0}, 0, {0, 0, ASE_NULL}, ASE_NULL} }; -void* ase_awk_addbfn ( +void* ase_awk_addfunc ( ase_awk_t* awk, const ase_char_t* name, ase_size_t name_len, int when_valid, ase_size_t min_args, ase_size_t max_args, const ase_char_t* arg_spec, @@ -103,7 +103,8 @@ void* ase_awk_addbfn ( return p; } -int ase_awk_delbfn (ase_awk_t* awk, const ase_char_t* name, ase_size_t name_len) +int ase_awk_delfunc ( + ase_awk_t* awk, const ase_char_t* name, ase_size_t name_len) { ase_awk_bfn_t* p, * pp = ASE_NULL; ase_cstr_t errarg; diff --git a/ase/awk/jni.c b/ase/awk/jni.c index fa79f650..c77cf278 100644 --- a/ase/awk/jni.c +++ b/ase/awk/jni.c @@ -1,5 +1,5 @@ /* - * $Id: jni.c,v 1.13 2007/08/26 14:33:38 bacon Exp $ + * $Id: jni.c,v 1.14 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -1731,7 +1731,7 @@ static int __handle_bfn ( return 0; } -JNIEXPORT void JNICALL Java_ase_awk_Awk_addbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_addfunc ( JNIEnv* env, jobject obj, jstring name, jint min_args, jint max_args) { jclass class; @@ -1786,13 +1786,13 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_addbfn ( } for (i = 0; i < len; i++) tmp[i] = (ase_char_t)ptr[i]; - n = (ase_awk_addbfn (awk, tmp, len, 0, + n = (ase_awk_addfunc (awk, tmp, len, 0, min_args, max_args, ASE_NULL, __handle_bfn) == NULL)? -1: 0; free (tmp); } else { - n = (ase_awk_addbfn (awk, (ase_char_t*)ptr, len, 0, + n = (ase_awk_addfunc (awk, (ase_char_t*)ptr, len, 0, min_args, max_args, ASE_NULL, __handle_bfn) == NULL)? -1: 0; } @@ -1809,7 +1809,7 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_addbfn ( } } -JNIEXPORT void JNICALL Java_ase_awk_Awk_delbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_delfunc ( JNIEnv* env, jobject obj, jstring name) { jclass class; @@ -1863,12 +1863,12 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_delbfn ( } for (i = 0; i < len; i++) tmp[i] = (ase_char_t)ptr[i]; - n = ase_awk_delbfn (awk, tmp, len); + n = ase_awk_delfunc (awk, tmp, len); free (tmp); } else { - n = ase_awk_delbfn (awk, (ase_char_t*)ptr, len); + n = ase_awk_delfunc (awk, (ase_char_t*)ptr, len); } (*env)->ReleaseStringChars (env, name, ptr); diff --git a/ase/awk/jni.def b/ase/awk/jni.def index d15dd6b9..ccc1224d 100644 --- a/ase/awk/jni.def +++ b/ase/awk/jni.def @@ -15,8 +15,8 @@ EXPORTS Java_ase_awk_Awk_getdebug Java_ase_awk_Awk_setdebug - Java_ase_awk_Awk_addbfn - Java_ase_awk_Awk_delbfn + Java_ase_awk_Awk_addfunc + Java_ase_awk_Awk_delfunc Java_ase_awk_Awk_setfilename Java_ase_awk_Awk_setofilename Java_ase_awk_Awk_strtonum diff --git a/ase/awk/jni.h b/ase/awk/jni.h index de8efdee..4435f443 100644 --- a/ase/awk/jni.h +++ b/ase/awk/jni.h @@ -1,5 +1,5 @@ /* - * $Id: jni.h,v 1.4 2007/06/24 11:14:58 bacon Exp $ + * $Id: jni.h,v 1.5 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -23,9 +23,9 @@ JNIEXPORT void JNICALL Java_ase_awk_Awk_parse (JNIEnv* env, jobject obj); JNIEXPORT void JNICALL Java_ase_awk_Awk_run ( JNIEnv* env, jobject obj, jstring mfn, jobjectArray args); -JNIEXPORT void JNICALL Java_ase_awk_Awk_addbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_addfunc ( JNIEnv* env, jobject obj, jstring name, jint min_args, jint max_args); -JNIEXPORT void JNICALL Java_ase_awk_Awk_delbfn ( +JNIEXPORT void JNICALL Java_ase_awk_Awk_delfunc ( JNIEnv* env, jobject obj, jstring name); JNIEXPORT jint JNICALL Java_ase_awk_Awk_getmaxdepth ( diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 3f99cbf8..e8217b46 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.13 2007/09/23 04:20:22 bacon Exp $ + * $Id: parse.c,v 1.14 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -130,7 +130,8 @@ static int parse (ase_awk_t* awk); static ase_awk_t* parse_progunit (ase_awk_t* awk); static ase_awk_t* collect_globals (ase_awk_t* awk); -static ase_awk_t* add_builtin_globals (ase_awk_t* awk); +static int adjust_static_globals (ase_awk_t* awk); + static int add_global ( ase_awk_t* awk, const ase_char_t* name, ase_size_t len, ase_size_t line, int force); @@ -479,7 +480,7 @@ static int parse (ase_awk_t* awk) return -1; } - if (add_builtin_globals (awk) == ASE_NULL) + if (adjust_static_globals (awk) == -1) { n = -1; goto exit_parse; @@ -1247,7 +1248,39 @@ static ase_awk_nde_t* parse_block_dc ( return nde; } -static ase_awk_t* add_builtin_globals (ase_awk_t* awk) +int ase_awk_initglobals (ase_awk_t* awk) +{ + global_t* p = gtab; + int id; + + /* ase_awk_initglobals is not generic-purpose. call this from + * ase_awk_open only. */ + ASE_ASSERT (awk->tree.nbglobals == 0 && awk->tree.nglobals == 0); + + awk->tree.nbglobals = 0; + while (p->name != ASE_NULL) + { + if (ase_awk_tab_add ( + &awk->parse.globals, p->name, p->name_len) == (ase_size_t)-1) + { + return -1; + } + + awk->tree.nbglobals++; + p++; + } + + return 0; +} + +static int adjust_static_globals (ase_awk_t* awk) +{ + /* TODO: */ + return 0; +} + +#if 0 +static ase_awk_t* add_static_globals (ase_awk_t* awk) { global_t* p = gtab; int id; @@ -1258,11 +1291,14 @@ static ase_awk_t* add_builtin_globals (ase_awk_t* awk) if (p->valid != 0 && (awk->option & p->valid) == 0) { + #if 0 /* an invalid global variable are still added * to the global variable table with an empty name. * this is to prevent the run-time from looking up * the variable */ id = add_global (awk, ASE_T(""), 0, 0, 1); + #endif + id = add_global (awk, p->name, p->name_len, 0, 1); } else { @@ -1276,15 +1312,17 @@ static ase_awk_t* add_builtin_globals (ase_awk_t* awk) return awk; } +#endif static int add_global ( ase_awk_t* awk, const ase_char_t* name, ase_size_t len, - ase_size_t line, int force) + ase_size_t line, int disabled) { ase_size_t nglobals; + /* if (!force) - { + {*/ if (awk->option & ASE_AWK_UNIQUEFN) { /* check if it conflict with a builtin function name */ @@ -1314,7 +1352,7 @@ static int add_global ( SETERRARG (awk, ASE_AWK_EDUPGBL, line, name, len); return -1; } - } + /*}*/ nglobals = ase_awk_tab_getsize (&awk->parse.globals); if (nglobals >= ASE_AWK_MAX_GLOBALS) @@ -1329,6 +1367,10 @@ static int add_global ( return -1; } + /* the disabled item is inserted normally but + * the name length is reset to zero. */ + if (disabled) awk->parse.globals.buf[nglobals].name.len = 0; + /* return the id which is the index to the global table. */ return (int)nglobals; } @@ -1339,6 +1381,30 @@ int ase_awk_addglobal ( return add_global (awk, name, len, 0, 0); } +int ase_awk_delglobal ( + ase_awk_t* awk, const ase_char_t* name, ase_size_t len) +{ + ase_size_t n; + + n = ase_awk_tab_find (&awk->parse.globals, 0, name, len); + if (n == (ase_size_t)-1) + { + SETERRARG (awk, ASE_AWK_ENOENT, 0, name, len); + return -1; + } + + /* clear the name to emulate the action. this approach is + * in align with ase_awk_addglobal adding an ineffective global. + * anyway, this function cannot physically remove the entry + * because the existing global ID's known can all go wrong if + * it does so. the best is not to use this function as a normal + * program has no reason to do so. */ + awk->parse.globals.buf[n].name.ptr[0] = ASE_T('\0');; + awk->parse.globals.buf[n].name.len = 0; + + return 0; +} + static ase_awk_t* collect_globals (ase_awk_t* awk) { while (1) @@ -2794,7 +2860,7 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) return ASE_NULL; } - /* check if name_dup is a built-in function name */ + /* check if name_dup is an intrinsic function name */ bfn = ase_awk_getbfn (awk, name_dup, name_len); if (bfn != ASE_NULL) { @@ -2802,7 +2868,7 @@ static ase_awk_nde_t* parse_primary_ident (ase_awk_t* awk, ase_size_t line) if (!MATCH(awk,TOKEN_LPAREN)) { - /* built-in function should be in the form + /* an intrinsic function should be in the form * of the function call */ ASE_AWK_FREE (awk, name_dup); @@ -4958,8 +5024,8 @@ static int deparse (ase_awk_t* awk) } */ if (ase_awk_putsrcstrx (awk, - awk->parse.globals.buf[i].name, - awk->parse.globals.buf[i].name_len) == -1) + awk->parse.globals.buf[i].name.ptr, + awk->parse.globals.buf[i].name.len) == -1) { EXIT_DEPARSE (); } @@ -4978,8 +5044,8 @@ static int deparse (ase_awk_t* awk) } */ if (ase_awk_putsrcstrx (awk, - awk->parse.globals.buf[i].name, - awk->parse.globals.buf[i].name_len) == -1) + awk->parse.globals.buf[i].name.ptr, + awk->parse.globals.buf[i].name.len) == -1) { EXIT_DEPARSE (); } diff --git a/ase/awk/parse.h b/ase/awk/parse.h index c668ad21..76b1a86c 100644 --- a/ase/awk/parse.h +++ b/ase/awk/parse.h @@ -1,5 +1,5 @@ /* - * $Id: parse.h,v 1.3 2007/04/30 05:47:33 bacon Exp $ + * $Id: parse.h,v 1.4 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -22,6 +22,8 @@ int ase_awk_putsrcstrx ( const ase_char_t* ase_awk_getglobalname ( ase_awk_t* awk, ase_size_t idx, ase_size_t* len); +int ase_awk_initglobals (ase_awk_t* awk); + #ifdef __cplusplus } #endif diff --git a/ase/awk/run.c b/ase/awk/run.c index b09802c1..b3724a1f 100644 --- a/ase/awk/run.c +++ b/ase/awk/run.c @@ -1,5 +1,5 @@ /* - * $Id: run.c,v 1.11 2007/08/26 14:33:38 bacon Exp $ + * $Id: run.c,v 1.12 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -223,14 +223,18 @@ ase_awk_val_t* ase_awk_getarg (ase_awk_run_t* run, ase_size_t idx) return STACK_ARG (run, idx); } -ase_awk_val_t* ase_awk_getglobal (ase_awk_run_t* run, ase_size_t idx) +ase_awk_val_t* ase_awk_getglobal (ase_awk_run_t* run, int id) { - return STACK_GLOBAL (run, idx); + ASE_ASSERTX (id >= 0, + "a global variable ID should be equal to or greater than 0"); + return STACK_GLOBAL (run, id); } -int ase_awk_setglobal (ase_awk_run_t* run, ase_size_t idx, ase_awk_val_t* val) +int ase_awk_setglobal (ase_awk_run_t* run, int id, ase_awk_val_t* val) { - return __set_global (run, idx, ASE_NULL, val); + ASE_ASSERTX (id >= 0, + "a global variable ID should be equal to or greater than 0"); + return __set_global (run, (ase_size_t)id, ASE_NULL, val); } static int __set_global ( @@ -5207,7 +5211,7 @@ static ase_awk_val_t* __eval_bfn (ase_awk_run_t* run, ase_awk_nde_t* nde) { ase_awk_nde_call_t* call = (ase_awk_nde_call_t*)nde; - /* built-in function */ + /* intrinsic function */ if (call->nargs < call->what.bfn.arg.min) { ase_awk_setrunerror ( @@ -5477,7 +5481,7 @@ static ase_awk_val_t* __eval_call ( { n = 0; - /* built-in function */ + /* intrinsic function */ ASE_ASSERT ( call->nargs >= call->what.bfn.arg.min && call->nargs <= call->what.bfn.arg.max); diff --git a/ase/awk/run.h b/ase/awk/run.h index 23ea5ccd..3d43177f 100644 --- a/ase/awk/run.h +++ b/ase/awk/run.h @@ -1,5 +1,5 @@ /* - * $Id: run.h,v 1.4 2007/09/23 04:20:22 bacon Exp $ + * $Id: run.h,v 1.5 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -100,7 +100,9 @@ enum ase_awk_global_id_t ASE_AWK_GLOBAL_RLENGTH, ASE_AWK_GLOBAL_RS, ASE_AWK_GLOBAL_RSTART, - ASE_AWK_GLOBAL_SUBSEP + ASE_AWK_GLOBAL_SUBSEP, + + ASE_AWK_GLOBAL_MAX /* this is not the actual id. used internally */ }; #ifdef __cplusplus diff --git a/ase/awk/tab.c b/ase/awk/tab.c index 65b88ecb..b24f197b 100644 --- a/ase/awk/tab.c +++ b/ase/awk/tab.c @@ -1,5 +1,5 @@ /* - * $Id: tab.c,v 1.3 2007/04/30 05:47:33 bacon Exp $ + * $Id: tab.c,v 1.4 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -100,9 +100,9 @@ void ase_awk_tab_clear (ase_awk_tab_t* tab) for (i = 0; i < tab->size; i++) { - ASE_AWK_FREE (tab->awk, tab->buf[i].name); - tab->buf[i].name = ASE_NULL; - tab->buf[i].name_len = 0; + ASE_AWK_FREE (tab->awk, tab->buf[i].name.ptr); + tab->buf[i].name.ptr = ASE_NULL; + tab->buf[i].name.len = 0; } tab->size = 0; @@ -114,10 +114,10 @@ ase_size_t ase_awk_tab_insert ( const ase_char_t* str, ase_size_t len) { ase_size_t i; - ase_char_t* str_dup; + ase_char_t* dup; - str_dup = ase_strxdup (str, len, &tab->awk->prmfns.mmgr); - if (str_dup == ASE_NULL) return (ase_size_t)-1; + dup = ase_strxdup (str, len, &tab->awk->prmfns.mmgr); + if (dup == ASE_NULL) return (ase_size_t)-1; if (index >= tab->capa) { @@ -131,14 +131,14 @@ ase_size_t ase_awk_tab_insert ( if (ase_awk_tab_setcapa(tab,capa) == ASE_NULL) { - ASE_AWK_FREE (tab->awk, str_dup); + ASE_AWK_FREE (tab->awk, dup); return (ase_size_t)-1; } } for (i = tab->size; i > index; i--) tab->buf[i] = tab->buf[i-1]; - tab->buf[index].name = str_dup; - tab->buf[index].name_len = len; + tab->buf[index].name.ptr = dup; + tab->buf[index].name.len = len; if (index > tab->size) tab->size = index + 1; else tab->size++; @@ -160,18 +160,18 @@ ase_size_t ase_awk_tab_remove ( while (i < k) { - ASE_AWK_FREE (tab->awk, tab->buf[i].name); + ASE_AWK_FREE (tab->awk, tab->buf[i].name.ptr); if (j >= tab->size) { - tab->buf[i].name = ASE_NULL; - tab->buf[i].name_len = 0; + tab->buf[i].name.ptr = ASE_NULL; + tab->buf[i].name.len = 0; i++; } else { - tab->buf[i].name = tab->buf[j].name; - tab->buf[i].name_len = tab->buf[j].name_len; + tab->buf[i].name.ptr = tab->buf[j].name.ptr; + tab->buf[i].name.len = tab->buf[j].name.len; i++; j++; } } @@ -195,7 +195,7 @@ ase_size_t ase_awk_tab_find ( for (i = index; i < tab->size; i++) { if (ase_strxncmp ( - tab->buf[i].name, tab->buf[i].name_len, + tab->buf[i].name.ptr, tab->buf[i].name.len, str, len) == 0) return i; } @@ -213,7 +213,7 @@ ase_size_t ase_awk_tab_rfind ( for (i = index + 1; i-- > 0; ) { if (ase_strxncmp ( - tab->buf[i].name, tab->buf[i].name_len, + tab->buf[i].name.ptr, tab->buf[i].name.len, str, len) == 0) return i; } @@ -231,7 +231,7 @@ ase_size_t ase_awk_tab_rrfind ( for (i = tab->size - index; i-- > 0; ) { if (ase_strxncmp ( - tab->buf[i].name, tab->buf[i].name_len, + tab->buf[i].name.ptr, tab->buf[i].name.len, str, len) == 0) return i; } diff --git a/ase/awk/tab.h b/ase/awk/tab.h index bb669605..bf4cbe92 100644 --- a/ase/awk/tab.h +++ b/ase/awk/tab.h @@ -1,5 +1,5 @@ /* - * $Id: tab.h,v 1.3 2007/04/30 05:47:33 bacon Exp $ + * $Id: tab.h,v 1.4 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -20,8 +20,11 @@ struct ase_awk_tab_t { struct { - ase_char_t* name; - ase_size_t name_len; + struct + { + ase_char_t* ptr; + ase_size_t len; + } name; }* buf; ase_size_t size; ase_size_t capa; diff --git a/ase/awk/tree.h b/ase/awk/tree.h index 15918120..6808c542 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -1,5 +1,5 @@ /* - * $Id: tree.h,v 1.3 2007/04/30 05:47:33 bacon Exp $ + * $Id: tree.h,v 1.4 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -263,7 +263,7 @@ struct ase_awk_nde_call_t } name; } afn; - /* minimum information of a built-in function + /* minimum information of a intrinsic function * needed during run-time. */ struct { diff --git a/ase/awk/val.c b/ase/awk/val.c index f9d582aa..24ee13a0 100644 --- a/ase/awk/val.c +++ b/ase/awk/val.c @@ -1,5 +1,5 @@ /* - * $Id: val.c,v 1.7 2007/07/25 07:00:09 bacon Exp $ + * $Id: val.c,v 1.8 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -275,7 +275,7 @@ ase_awk_val_t* ase_awk_makerefval (ase_awk_run_t* run, int id, ase_awk_val_t** a return (ase_awk_val_t*)val; } -ase_bool_t ase_awk_isbuiltinval (ase_awk_val_t* val) +ase_bool_t ase_awk_isstaticval (ase_awk_val_t* val) { return val == ASE_NULL || val == ase_awk_val_nil || @@ -288,7 +288,7 @@ ase_bool_t ase_awk_isbuiltinval (ase_awk_val_t* val) void ase_awk_freeval (ase_awk_run_t* run, ase_awk_val_t* val, ase_bool_t cache) { - if (ase_awk_isbuiltinval(val)) return; + if (ase_awk_isstaticval(val)) return; #ifdef DEBUG_VAL ase_dprintf (ASE_T("freeing [cache=%d] ... "), cache); @@ -356,7 +356,7 @@ void ase_awk_freeval (ase_awk_run_t* run, ase_awk_val_t* val, ase_bool_t cache) void ase_awk_refupval (ase_awk_run_t* run, ase_awk_val_t* val) { - if (ase_awk_isbuiltinval(val)) return; + if (ase_awk_isstaticval(val)) return; #ifdef DEBUG_VAL ase_dprintf (ASE_T("ref up [ptr=%p] [count=%d] "), val, (int)val->ref); @@ -369,7 +369,7 @@ void ase_awk_refupval (ase_awk_run_t* run, ase_awk_val_t* val) void ase_awk_refdownval (ase_awk_run_t* run, ase_awk_val_t* val) { - if (ase_awk_isbuiltinval(val)) return; + if (ase_awk_isstaticval(val)) return; #ifdef DEBUG_VAL ase_dprintf (ASE_T("ref down [ptr=%p] [count=%d]\n"), val, (int)val->ref); @@ -389,7 +389,7 @@ void ase_awk_refdownval (ase_awk_run_t* run, ase_awk_val_t* val) void ase_awk_refdownval_nofree (ase_awk_run_t* run, ase_awk_val_t* val) { - if (ase_awk_isbuiltinval(val)) return; + if (ase_awk_isstaticval(val)) return; ASE_ASSERTX (val->ref > 0, "the reference count of a value should be greater than zero for it to be decremented. check the source code for any bugs"); diff --git a/ase/awk/val.h b/ase/awk/val.h index 240c3e43..74be85c9 100644 --- a/ase/awk/val.h +++ b/ase/awk/val.h @@ -1,5 +1,5 @@ /* - * $Id: val.h,v 1.5 2007/05/10 16:08:37 bacon Exp $ + * $Id: val.h,v 1.6 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -177,7 +177,7 @@ ase_awk_val_t* ase_awk_makemapval (ase_awk_run_t* run); ase_awk_val_t* ase_awk_makerefval ( ase_awk_run_t* run, int id, ase_awk_val_t** adr); -ase_bool_t ase_awk_isbuiltinval (ase_awk_val_t* val); +ase_bool_t ase_awk_isstaticval (ase_awk_val_t* val); void ase_awk_freeval (ase_awk_run_t* run, ase_awk_val_t* val, ase_bool_t cache); void ase_awk_refupval (ase_awk_run_t* run, ase_awk_val_t* val); diff --git a/ase/change.log b/ase/change.log index a4e731fe..bd16962f 100644 --- a/ase/change.log +++ b/ase/change.log @@ -2,9 +2,16 @@ * changed the access modifier for the Awk::Source::Source from public to protected. -* added source code documentation of ase/Awk/Awk.hpp. -* added ase_awk_addglobal to support the addition of a user-defined - global variable (awk/parse.c) +* started adding the source code documentation of awk/Awk.hpp. + +* added to the awk interpreter the capibility to add a global variable. + - ase_awk_addglobal (awk/parse.c) + - Awk::addGlobal (awk/Awk.cpp) + +* enhanced Awk::dispatchFunction to set more specific error code (awk/Awk.cpp) + +* renamed ase_awk_addbfn & ase_awk_delbfn to ase_awk_addfunc & ase_awk_delfunc + respectively. [0.3.0] diff --git a/ase/com/Awk.cpp b/ase/com/Awk.cpp index 8b0d6413..fb401298 100644 --- a/ase/com/Awk.cpp +++ b/ase/com/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.7 2007/08/26 14:33:38 bacon Exp $ + * $Id: Awk.cpp,v 1.8 2007/09/23 16:48:55 bacon Exp $ * * {License} */ @@ -555,7 +555,7 @@ HRESULT CAwk::Parse (VARIANT_BOOL* ret) for (bfn_t* bfn = bfn_list; bfn != NULL; bfn = bfn->next) { - if (ase_awk_addbfn ( + if (ase_awk_addfunc ( handle, bfn->name.ptr, bfn->name.len, 0, bfn->min_args, bfn->max_args, NULL, __handle_bfn) == NULL) diff --git a/ase/net/Awk.cpp b/ase/net/Awk.cpp index 5059c733..613e6dd6 100644 --- a/ase/net/Awk.cpp +++ b/ase/net/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.23 2007/09/06 08:44:42 bacon Exp $ + * $Id: Awk.cpp,v 1.24 2007/09/23 16:48:55 bacon Exp $ */ #include "stdafx.h" @@ -214,6 +214,22 @@ namespace ASE } } + int addGlobal (ASE::Net::Awk^ wrapper, const char_t* name) + { + this->wrapper = wrapper; + int n = Awk::addGlobal (name); + this->wrapper = nullptr; + return n; + } + + int deleteGlobal (ASE::Net::Awk^ wrapper, const char_t* name) + { + this->wrapper = wrapper; + int n = Awk::deleteGlobal (name); + this->wrapper = nullptr; + return n; + } + int addFunction ( ASE::Net::Awk^ wrapper, const char_t* name, size_t minArgs, size_t maxArgs, FunctionHandler handler) @@ -233,11 +249,11 @@ namespace ASE } int mojoFunctionHandler ( - Return* ret, const Argument* args, size_t nargs, + Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - return wrapper->DispatchFunction (ret, args, nargs, name, len)? 0: -1; + return wrapper->DispatchFunction (run, ret, args, nargs, name, len)? 0: -1; } int openSource (Source& io) @@ -833,6 +849,40 @@ namespace ASE stopRequested = true; } + bool Awk::AddGlobal (System::String^ name, [System::Runtime::InteropServices::Out] int% id) + { + if (awk == NULL) + { + setError (ERROR::NOPER); + return -1; + } + + cli::pin_ptr nptr = PtrToStringChars(name); + int n = awk->addGlobal (this, nptr); + if (n == -1) + { + retrieveError (); + return false; + } + + id = n; + return true; + } + + bool Awk::DeleteGlobal (System::String^ name) + { + if (awk == NULL) + { + setError (ERROR::NOPER); + return false; + } + + cli::pin_ptr nptr = PtrToStringChars(name); + int n = awk->deleteGlobal (this, nptr); + if (n == -1) retrieveError (); + return n == 0; + } + bool Awk::AddFunction ( System::String^ name, int minArgs, int maxArgs, FunctionHandler^ handler) @@ -864,7 +914,8 @@ namespace ASE return n == 0; } - bool Awk::DispatchFunction (ASE::Awk::Return* ret, + bool Awk::DispatchFunction ( + ASE::Awk::Run& run, ASE::Awk::Return& ret, const ASE::Awk::Argument* args, size_t nargs, const char_t* name, size_t len) { @@ -878,10 +929,12 @@ namespace ASE } cli::array^ arg_arr = gcnew cli::array (nargs); - for (size_t i = 0; i < nargs; i++) arg_arr[i] = gcnew Argument(args[i]); + for (size_t i = 0; i < nargs; i++) + arg_arr[i] = gcnew Argument(args[i]); - Return^ r = gcnew Return (*ret); - return fh(nm, arg_arr, r); + Return^ r = gcnew Return (ret); + + return fh (nm, arg_arr, r); } bool Awk::SetWord (System::String^ ow, System::String^ nw) diff --git a/ase/net/Awk.hpp b/ase/net/Awk.hpp index e3dcab2c..62708451 100644 --- a/ase/net/Awk.hpp +++ b/ase/net/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp,v 1.21 2007/09/06 08:44:42 bacon Exp $ + * $Id: Awk.hpp,v 1.22 2007/09/23 16:48:55 bacon Exp $ */ #pragma once @@ -485,10 +485,13 @@ namespace ASE /*event*/ RunReturnHandler^ OnRunReturn; /*event*/ RunStatementHandler^ OnRunStatement; + virtual bool AddGlobal (System::String^ name, [System::Runtime::InteropServices::Out] int% id); + virtual bool DeleteGlobal (System::String^ name); + delegate bool FunctionHandler (System::String^ name, cli::array^ args, Return^ ret); virtual bool AddFunction (System::String^ name, int minArgs, int maxArgs, FunctionHandler^ handler); virtual bool DeleteFunction (System::String^ name); - + virtual bool SetWord (System::String^ ow, System::String^ nw); virtual bool UnsetWord (System::String^ ow); virtual bool UnsetAllWords (); @@ -562,7 +565,8 @@ namespace ASE virtual int NextConsole (Console^ console) = 0; public protected: - bool Awk::DispatchFunction (ASE::Awk::Return* ret, + bool Awk::DispatchFunction ( + ASE::Awk::Run& run, ASE::Awk::Return& ret, const ASE::Awk::Argument* args, size_t nargs, const char_t* name, size_t len); diff --git a/ase/test/awk/Awk.cpp b/ase/test/awk/Awk.cpp index 902311ae..89f55ea8 100644 --- a/ase/test/awk/Awk.cpp +++ b/ase/test/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.32 2007/08/26 14:33:38 bacon Exp $ + * $Id: Awk.cpp,v 1.33 2007/09/23 16:48:55 bacon Exp $ */ #include @@ -46,8 +46,10 @@ public: int n = ASE::StdAwk::open (); #endif - if (addFunction (ASE_T("sleep"), 1, 1, - (FunctionHandler)&TestAwk::sleep) == -1) + idLastSleep = addGlobal (ASE_T("LAST_SLEEP")); + if (idLastSleep == -1 || + addFunction (ASE_T("sleep"), 1, 1, + (FunctionHandler)&TestAwk::sleep) == -1) { #if defined(_MSC_VER) && (_MSC_VER<1400) StdAwk::close (); @@ -85,14 +87,16 @@ public: #endif } - int sleep (Return* ret, const Argument* args, size_t nargs, + int sleep (Run& run, Return& ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { + long_t x = args[0].toInt(); + run.setGlobal (idLastSleep, x); #ifdef _WIN32 - ::Sleep (args[0].toInt() * 1000); - return ret->set ((long_t)0); + ::Sleep (x * 1000); + return ret.set ((long_t)0); #else - return ret->set ((long_t)::sleep (args[0].toInt())); + return ret.set ((long_t)::sleep (x)); #endif } @@ -467,6 +471,8 @@ private: size_t numConOutFiles; const char_t* conOutFile[128]; + int idLastSleep; + #ifdef _WIN32 void* heap; #endif @@ -567,6 +573,10 @@ int awk_main (int argc, ase_char_t* argv[]) { awk.setOption (awk.getOption () & ~TestAwk::OPT_STRIPSPACES); } + else if (ase_strcmp(argv[i], ASE_T("-noimplicit")) == 0) + { + awk.setOption (awk.getOption () & ~TestAwk::OPT_IMPLICIT); + } else { print_usage (argv[0]); @@ -712,7 +722,6 @@ extern "C" int ase_main (int argc, ase_achar_t* argv[]) _CrtSetDbgFlag (_CRTDBG_LEAK_CHECK_DF | _CRTDBG_ALLOC_MEM_DF); #endif - n = ase_runmain (argc,argv,awk_main); #if defined(__linux) && defined(_DEBUG) diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 78415e1b..d14bad8f 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.14 2007/09/05 14:42:06 bacon Exp $ + * $Id: awk.c,v 1.15 2007/09/23 16:48:55 bacon Exp $ */ #include @@ -1058,7 +1058,7 @@ static int awk_main (int argc, ase_char_t* argv[]) app_awk = awk; - if (ase_awk_addbfn (awk, + if (ase_awk_addfunc (awk, ASE_T("sleep"), 5, 0, 1, 1, ASE_NULL, bfn_sleep) == ASE_NULL) { diff --git a/ase/test/net/AwkForm.cs b/ase/test/net/AwkForm.cs index 3c344337499bec735a9ec819d4c26e0851fb6536..a06b88878daacaddc93ef3957717b171db04c99b 100644 GIT binary patch delta 24 gcmaFl`^tC243WtTlsP6li1SQ-B_gzWn~07O0EeszbpQYW delta 20 ccmaFm`^b0043Wu?#3UyF6JguDPeexu0BY?B)Bpeg