diff --git a/ase/awk/Awk.cpp b/ase/awk/Awk.cpp index e5db7d3d..4eb95116 100644 --- a/ase/awk/Awk.cpp +++ b/ase/awk/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.47 2007/07/25 07:00:09 bacon Exp $ + * $Id: Awk.cpp,v 1.48 2007/08/18 15:41:46 bacon Exp $ */ #include @@ -327,7 +327,7 @@ namespace ASE return 0; } - int Awk::Return::set (char_t* ptr, size_t len) + 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); diff --git a/ase/awk/Awk.hpp b/ase/awk/Awk.hpp index 1e888d26..b7f0e71d 100644 --- a/ase/awk/Awk.hpp +++ b/ase/awk/Awk.hpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.hpp,v 1.45 2007/07/15 16:31:59 bacon Exp $ + * $Id: Awk.hpp,v 1.46 2007/08/18 15:41:46 bacon Exp $ */ #ifndef _ASE_AWK_AWK_HPP_ @@ -185,7 +185,7 @@ namespace ASE public: int set (long_t v); int set (real_t v); - int set (char_t* ptr, size_t len); + int set (const char_t* ptr, size_t len); void clear (); protected: diff --git a/ase/net/Awk.cpp b/ase/net/Awk.cpp index bcac9380..6345bbab 100644 --- a/ase/net/Awk.cpp +++ b/ase/net/Awk.cpp @@ -1,5 +1,5 @@ /* - * $Id: Awk.cpp,v 1.14 2007/08/16 15:19:37 bacon Exp $ + * $Id: Awk.cpp,v 1.16 2007/08/18 15:42:04 bacon Exp $ */ #include "stdafx.h" @@ -17,24 +17,89 @@ using System::Runtime::InteropServices::GCHandle; namespace ASE { - class StubAwk: public Awk + + class MojoAwk: protected Awk { public: - StubAwk (Net::Awk^ wrapper): wrapper(wrapper) - { + MojoAwk (): wrapper(nullptr) + { } - ~StubAwk () + ~MojoAwk () { - wrapper = nullptr; } - int stubFunctionHandler ( + int open (ASE::Net::Awk^ wrapper) + { + this->wrapper = wrapper; + int n = Awk::open (); + this->wrapper = nullptr; + return n; + } + + void close (ASE::Net::Awk^ wrapper) + { + this->wrapper = wrapper; + Awk::close (); + this->wrapper = nullptr; + } + + int getOption (ASE::Net::Awk^ wrapper) const + { + this->wrapper = wrapper; + int n = Awk::getOption (); + this->wrapper = nullptr; + return n; + } + + void setOption (ASE::Net::Awk^ wrapper, int opt) + { + this->wrapper = wrapper; + Awk::setOption (opt); + this->wrapper = nullptr; + } + + int parse (ASE::Net::Awk^ wrapper) + { + this->wrapper = wrapper; + int n = Awk::parse (); + this->wrapper = nullptr; + return n; + } + + int run (ASE::Net::Awk^ wrapper, const char_t* main = ASE_NULL, + const char_t** args = ASE_NULL, size_t nargs = 0) + { + this->wrapper = wrapper; + int n = Awk::run (main, args, nargs); + this->wrapper = nullptr; + return n; + } + + int addFunction ( + ASE::Net::Awk^ wrapper, const char_t* name, + size_t minArgs, size_t maxArgs, FunctionHandler handler) + { + this->wrapper = wrapper; + int n = Awk::addFunction (name, minArgs, maxArgs, handler); + this->wrapper = nullptr; + return n; + } + + int deleteFunction (ASE::Net::Awk^ wrapper, const char_t* main) + { + this->wrapper = wrapper; + int n = Awk::deleteFunction (main); + this->wrapper = nullptr; + return n; + } + + int mojoFunctionHandler ( Return* ret, const Argument* args, size_t nargs, const char_t* name, size_t len) { - System::String^ nm = gcnew System::String (name, 0, len); - return wrapper->DispatchFunction (nm); + + return wrapper->DispatchFunction (ret, args, nargs, name, len); } int openSource (Source& io) @@ -118,8 +183,7 @@ namespace ASE { gh.Free (); io.setHandle (NULL); - return -1; - + return -1; } } @@ -393,58 +457,54 @@ namespace ASE ase_vfprintf (stderr, fmt, arg); } - public: + protected: //msclr::auto_gcroot wrapper; - gcroot wrapper; + mutable gcroot wrapper; }; namespace Net { Awk::Awk () { - awk = new ASE::StubAwk (this); - if (awk->open () == -1) + funcs = gcnew System::Collections::Hashtable(); + + awk = new ASE::MojoAwk (); + if (awk->open (this) == -1) { // TODO:... //throw new AwkException ("cannot open awk"); } - option = (OPTION)(awk->getOption () | awk->OPT_CRLF); - awk->setOption ((int)option); + //option = (OPTION)(awk->getOption (this) | MojoAwk::OPT_CRLF); + option = (OPTION)(awk->getOption (this) | ASE::Awk::OPT_CRLF); + awk->setOption (this, (int)option); } Awk::~Awk () { System::Diagnostics::Debug::Print ("Awk::~Awk"); - /*if (awk != NULL) - { - awk->close (); - ASE::Awk* tmp = awk; - awk = NULL; - delete tmp; - }*/ + if (awk != NULL) { - awk->close (); + awk->close (this); delete awk; awk = NULL; } + + if (funcs != nullptr) + { + funcs->Clear (); + delete funcs; + funcs = nullptr; + } } Awk::!Awk () { System::Diagnostics::Debug::Print ("Awk::!Awk"); - /* if (awk != NULL) { - awk->close (); - ASE::Awk* tmp = awk; - awk = NULL; - delete tmp; - }*/ - if (awk != NULL) - { - awk->close (); + awk->close (this); delete awk; awk = NULL; } @@ -452,55 +512,120 @@ System::Diagnostics::Debug::Print ("Awk::!Awk"); Awk::OPTION Awk::Option::get () { - if (awk != NULL) this->option = (OPTION)awk->getOption (); + if (awk != NULL) this->option = (OPTION)awk->getOption (this); return this->option; } void Awk::Option::set (Awk::OPTION opt) { this->option = opt; - if (awk != NULL) awk->setOption ((int)this->option); + if (awk != NULL) awk->setOption (this, (int)this->option); } void Awk::Close () { - System::Diagnostics::Debug::Print ("Awk::Close"); - if (awk != NULL) - { - awk->close (); - - // TODO: .... - ((StubAwk*)awk)->wrapper =nullptr; - } + if (awk != NULL) awk->close (this); } bool Awk::Parse () { - return awk->parse () == 0; + if (awk == NULL) return false; + return awk->parse (this) == 0; } bool Awk::Run () { - return awk->run () == 0; + if (awk == NULL) return false; + return awk->run (this) == 0; } bool Awk::AddFunction ( System::String^ name, int minArgs, int maxArgs, FunctionHandler^ handler) { - cli::pin_ptr nptr = PtrToStringChars(name); - return awk->addFunction (nptr, minArgs, maxArgs, - (ASE::Awk::FunctionHandler)&StubAwk::stubFunctionHandler) == 0; + cli::pin_ptr nptr = PtrToStringChars(name); + int n = awk->addFunction (this, nptr, minArgs, maxArgs, + (ASE::Awk::FunctionHandler)&MojoAwk::mojoFunctionHandler); + if (n == 0) funcs->Add(name, handler); + return n == 0; } bool Awk::DeleteFunction (System::String^ name) { - cli::pin_ptr nptr = PtrToStringChars(name); - return awk->deleteFunction (nptr) == 0; + cli::pin_ptr nptr = PtrToStringChars(name); + int n = awk->deleteFunction (this, nptr); + if (n == 0) funcs->Remove (name); + return n == 0; } - int Awk::DispatchFunction (System::String^ name) + int Awk::DispatchFunction (ASE::Awk::Return* ret, + const ASE::Awk::Argument* args, size_t nargs, + const char_t* name, size_t len) { + System::String^ nm = gcnew System::String (name, 0, len); + + FunctionHandler^ fh = (FunctionHandler^)funcs[nm]; + if (fh == nullptr) return -1; + + cli::array^ arg_arr = gcnew cli::array (nargs); + for (size_t i = 0; i < nargs; i++) arg_arr[i] = gcnew Argument(args[i]); + System::Object^ r = fh (nm, arg_arr); + if (r == nullptr) return -1; + + System::Type^ type = r->GetType(); + if (System::String::typeid == type) + { + System::String^ str = (System::String^)r; + cli::pin_ptr nptr = PtrToStringChars(str); + ret->set (nptr, str->Length); + } + else if (System::SByte::typeid == type) + { + ret->set ((ASE::Awk::long_t)(__int8)r); + } + else if (System::Int16::typeid == type) + { + ret->set ((ASE::Awk::long_t)(__int16)r); + } + else if (System::Int32::typeid == type) + { + ret->set ((ASE::Awk::long_t)(__int32)r); + } + else if (System::Int64::typeid == type) + { + ret->set ((ASE::Awk::long_t)(__int64)r); + } + else if (System::Byte::typeid == type) + { + ret->set ((ASE::Awk::long_t)(unsigned __int8)r); + } + else if (System::UInt16::typeid == type) + { + ret->set ((ASE::Awk::long_t)(unsigned __int16)r); + } + else if (System::UInt32::typeid == type) + { + ret->set ((ASE::Awk::long_t)(unsigned __int32)r); + } + else if (System::UInt64::typeid == type) + { + ret->set ((ASE::Awk::long_t)(unsigned __int64)r); + } + else if (System::Single::typeid == type) + { + ret->set ((ASE::Awk::real_t)(float)r); + } + else if (System::Double::typeid == type) + { + ret->set ((ASE::Awk::real_t)(double)r); + } + else + { + System::String^ str = r->ToString(); + cli::pin_ptr nptr = PtrToStringChars(str); + ret->set (nptr, str->Length); + } + return 0; } diff --git a/ase/net/Awk.hpp b/ase/net/Awk.hpp index cc1c0763..a061e70d 100644 --- a/ase/net/Awk.hpp +++ b/ase/net/Awk.hpp @@ -1,21 +1,81 @@ /* - * $Id: Awk.hpp,v 1.11 2007/08/15 15:25:06 bacon Exp $ + * $Id: Awk.hpp,v 1.13 2007/08/18 15:42:04 bacon Exp $ */ #pragma once #include +#include using namespace System; namespace ASE { + class MojoAwk; + namespace Net { - public ref class Awk abstract { public: + typedef ASE::Awk::long_t long_t; + typedef ASE::Awk::real_t real_t; + typedef ASE::Awk::char_t char_t; + typedef ASE::Awk::size_t size_t; + + ref class Argument + { + public protected: + Argument (const ASE::Awk::Argument& arg) + { + size_t len; + const char_t* s = arg.toStr(&len); + + str = gcnew System::String (s, 0, len); + inum = arg.toInt (); + rnum = arg.toReal (); + } + + public: + long_t ToInt () { return inum; } + real_t ToReal () { return rnum; } + System::String^ ToStr () { return str; } + + protected: + long_t inum; + real_t rnum; + System::String^ str; + }; + + ref class Return + { + public protected: + Return (ASE::Awk::Return& ret): ret (ret) + { + } + + property System::Object^ Value + { + void set (System::String^ v) + { + cli::pin_ptr nptr = PtrToStringChars(v); + ret.set (nptr, v->Length); + } + void set (System::Single^ v) + { + ret.set ((real_t)(float)v); + } + void set (System::Double^ v) + { + ret.set ((real_t)(double)v); + } + } + + + public: + ASE::Awk::Return& ret; + }; + ref class Source { public: @@ -140,7 +200,7 @@ namespace ASE MODE^ mode; }; - + [Flags] enum class OPTION: int { NONE = 0, @@ -173,7 +233,7 @@ namespace ASE bool Parse (); bool Run (); - delegate System::Object^ FunctionHandler (array^ args); + delegate System::Object^ FunctionHandler (System::String^ name, array^ args); bool AddFunction (System::String^ name, int minArgs, int maxArgs, FunctionHandler^ handler); bool DeleteFunction (System::String^ name); @@ -185,8 +245,9 @@ namespace ASE } protected: - ASE::Awk* awk; + MojoAwk* awk; OPTION option; + System::Collections::Hashtable^ funcs; public protected: // Source @@ -226,7 +287,9 @@ namespace ASE virtual int NextConsole (Console^ console) = 0; public protected: - int DispatchFunction (System::String^ name); + int Awk::DispatchFunction (ASE::Awk::Return* ret, + const ASE::Awk::Argument* args, size_t nargs, + const char_t* name, size_t len); }; } diff --git a/ase/test/net/AwkForm.Designer.cs b/ase/test/net/AwkForm.Designer.cs index ec6eb0af..bc26ef01 100644 --- a/ase/test/net/AwkForm.Designer.cs +++ b/ase/test/net/AwkForm.Designer.cs @@ -335,7 +335,7 @@ namespace asetestnet this.Controls.Add(this.panel2); this.Controls.Add(this.statusStrip1); this.Name = "AwkForm"; - this.Text = "ASE.CNT.AWK"; + this.Text = "ASE.NET.AWK"; this.tableLayoutPanel1.ResumeLayout(false); this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); diff --git a/ase/test/net/AwkForm.cs b/ase/test/net/AwkForm.cs index 3dd2a8b6..e5d74bf5 100644 --- a/ase/test/net/AwkForm.cs +++ b/ase/test/net/AwkForm.cs @@ -16,16 +16,22 @@ namespace asetestnet InitializeComponent(); } + object sin(string name, ASE.Net.Awk.Argument[] args) + { + return System.Math.Sin(args[0].ToReal()); + } + private void btnRun_Click(object sender, EventArgs e) { //using (Awk awk = new Awk()) - for (int i = 0; i < 10000; i++) + //for (int i = 0; i < 100; i++) { Awk awk = new Awk(); tbxSourceOutput.Text = ""; tbxConsoleOutput.Text = ""; + awk.AddFunction("sin", 1, 1, sin); if (!awk.Parse(tbxSourceInput, tbxSourceOutput)) { MessageBox.Show("Parse error");