/* * $Id: Awk.cpp,v 1.16 2007/08/18 15:42:04 bacon Exp $ */ #include "stdafx.h" #include "Awk.hpp" #include #include #include #include #include #include using System::Runtime::InteropServices::GCHandle; namespace ASE { class MojoAwk: protected Awk { public: MojoAwk (): wrapper(nullptr) { } ~MojoAwk () { } 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) { return wrapper->DispatchFunction (ret, args, nargs, name, len); } int openSource (Source& io) { ASE::Net::Awk::Source^ nio = gcnew ASE::Net::Awk::Source ( (ASE::Net::Awk::Source::MODE)io.getMode()); GCHandle gh = GCHandle::Alloc (nio); io.setHandle (GCHandle::ToIntPtr(gh).ToPointer()); try { return wrapper->OpenSource (nio); } catch (...) { gh.Free (); io.setHandle (NULL); return -1; } } int closeSource (Source& io) { IntPtr ip ((void*)io.getHandle ()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->CloseSource ( (ASE::Net::Awk::Source^)gh.Target); } catch (...) { return -1; } finally { gh.Free (); } } ssize_t readSource (Source& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); int n = wrapper->ReadSource ( (ASE::Net::Awk::Source^)gh.Target, b, len); for (int i = 0; i < n; i++) buf[i] = b[i]; return n; } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } ssize_t writeSource (Source& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); for (int i = 0; i < len; i++) b[i] = buf[i]; return wrapper->WriteSource ( (ASE::Net::Awk::Source^)gh.Target, b, len); } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } int openPipe (Pipe& io) { ASE::Net::Awk::Pipe^ nio = gcnew ASE::Net::Awk::Pipe ( gcnew System::String (io.getName ()), (ASE::Net::Awk::Pipe::MODE)io.getMode()); GCHandle gh = GCHandle::Alloc (nio); io.setHandle (GCHandle::ToIntPtr(gh).ToPointer()); try { return wrapper->OpenPipe (nio); } catch (...) { gh.Free (); io.setHandle (NULL); return -1; } } int closePipe (Pipe& io) { IntPtr ip ((void*)io.getHandle ()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->ClosePipe ( (ASE::Net::Awk::Pipe^)gh.Target); } catch (...) { return -1; } finally { gh.Free (); } } ssize_t readPipe (Pipe& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); int n = wrapper->ReadPipe ( (ASE::Net::Awk::Pipe^)gh.Target, b, len); for (int i = 0; i < n; i++) buf[i] = b[i]; return n; } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } ssize_t writePipe (Pipe& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); for (int i = 0; i < len; i++) b[i] = buf[i]; return wrapper->WritePipe ( (ASE::Net::Awk::Pipe^)gh.Target, b, len); } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } int flushPipe (Pipe& io) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->FlushPipe ( (ASE::Net::Awk::Pipe^)gh.Target); } catch (...) { return -1; } } int openFile (File& io) { ASE::Net::Awk::File^ nio = gcnew ASE::Net::Awk::File ( gcnew System::String (io.getName ()), (ASE::Net::Awk::File::MODE)io.getMode()); GCHandle gh = GCHandle::Alloc (nio); io.setHandle (GCHandle::ToIntPtr(gh).ToPointer()); try { return wrapper->OpenFile (nio); } catch (...) { gh.Free (); io.setHandle (NULL); return -1; } } int closeFile (File& io) { IntPtr ip ((void*)io.getHandle ()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->CloseFile ( (ASE::Net::Awk::File^)gh.Target); } catch (...) { return -1; } finally { gh.Free (); } } ssize_t readFile (File& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); int n = wrapper->ReadFile ( (ASE::Net::Awk::File^)gh.Target, b, len); for (int i = 0; i < n; i++) buf[i] = b[i]; return n; } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } ssize_t writeFile (File& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); for (int i = 0; i < len; i++) b[i] = buf[i]; return wrapper->WriteFile ( (ASE::Net::Awk::File^)gh.Target, b, len); } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } int flushFile (File& io) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->FlushFile ( (ASE::Net::Awk::File^)gh.Target); } catch (...) { return -1; } } int openConsole (Console& io) { ASE::Net::Awk::Console^ nio = gcnew ASE::Net::Awk::Console ( gcnew System::String (io.getName ()), (ASE::Net::Awk::Console::MODE)io.getMode()); GCHandle gh = GCHandle::Alloc (nio); io.setHandle (GCHandle::ToIntPtr(gh).ToPointer()); try { return wrapper->OpenConsole (nio); } catch (...) { gh.Free (); io.setHandle (NULL); return -1; } } int closeConsole (Console& io) { IntPtr ip ((void*)io.getHandle ()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->CloseConsole ( (ASE::Net::Awk::Console^)gh.Target); } catch (...) { return -1; } finally { gh.Free (); } } ssize_t readConsole (Console& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); int n = wrapper->ReadConsole ( (ASE::Net::Awk::Console^)gh.Target, b, len); for (int i = 0; i < n; i++) buf[i] = b[i]; return n; } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } ssize_t writeConsole (Console& io, char_t* buf, size_t len) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); cli::array^ b = nullptr; try { b = gcnew cli::array (len); for (int i = 0; i < len; i++) b[i] = buf[i]; return wrapper->WriteConsole ( (ASE::Net::Awk::Console^)gh.Target, b, len); } catch (...) { return -1; } finally { if (b != nullptr) delete b; } } int flushConsole (Console& io) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->FlushConsole ( (ASE::Net::Awk::Console^)gh.Target); } catch (...) { return -1; } } int nextConsole (Console& io) { IntPtr ip ((void*)io.getHandle()); GCHandle gh = GCHandle::FromIntPtr (ip); try { return wrapper->NextConsole ( (ASE::Net::Awk::Console^)gh.Target); } catch (...) { return -1; } } // primitive operations void* allocMem (size_t n) { return ::malloc (n); } void* reallocMem (void* ptr, size_t n) { return ::realloc (ptr, n); } void freeMem (void* ptr) { ::free (ptr); } bool_t isUpper (cint_t c) { return ase_isupper (c); } bool_t isLower (cint_t c) { return ase_islower (c); } bool_t isAlpha (cint_t c) { return ase_isalpha (c); } bool_t isDigit (cint_t c) { return ase_isdigit (c); } bool_t isXdigit (cint_t c) { return ase_isxdigit (c); } bool_t isAlnum (cint_t c) { return ase_isalnum (c); } bool_t isSpace (cint_t c) { return ase_isspace (c); } bool_t isPrint (cint_t c) { return ase_isprint (c); } bool_t isGraph (cint_t c) { return ase_isgraph (c); } bool_t isCntrl (cint_t c) { return ase_iscntrl (c); } bool_t isPunct (cint_t c) { return ase_ispunct (c); } cint_t toUpper (cint_t c) { return ase_toupper (c); } cint_t toLower (cint_t c) { return ase_tolower (c); } real_t pow (real_t x, real_t y) { return ::pow (x, y); } int vsprintf (char_t* buf, size_t size, const char_t* fmt, va_list arg) { return ase_vsprintf (buf, size, fmt, arg); } void vdprintf (const char_t* fmt, va_list arg) { ase_vfprintf (stderr, fmt, arg); } protected: //msclr::auto_gcroot wrapper; mutable gcroot wrapper; }; namespace Net { Awk::Awk () { 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 (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 (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 (this); delete awk; awk = NULL; } } Awk::OPTION Awk::Option::get () { 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 (this, (int)this->option); } void Awk::Close () { if (awk != NULL) awk->close (this); } bool Awk::Parse () { if (awk == NULL) return false; return awk->parse (this) == 0; } bool Awk::Run () { 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); 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); int n = awk->deleteFunction (this, nptr); if (n == 0) funcs->Remove (name); return n == 0; } 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; } } }