From f16f239688b632fc54684c3e0e1430fd89a67db5 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 3 Jun 2011 07:18:23 +0000 Subject: I added basic support for "opaque" type variables. I think there's one more tweak to it that I would like to make, but it's fine for now. I also added open, close, read, and write functions. They work just fine, but I'll also add a readLine function, and maybe even a readToken function later. --- src/filemgr.cpp | 46 ++++++++++++++++++++++++++++++ src/filemgr.h | 26 +++++++++++++++++ src/functionclose.cpp | 26 +++++++++++++++++ src/functionclose.h | 17 +++++++++++ src/functionopen.cpp | 42 +++++++++++++++++++++++++++ src/functionopen.h | 17 +++++++++++ src/functionplugger.cpp | 9 +++++- src/functionread.cpp | 40 ++++++++++++++++++++++++++ src/functionread.h | 17 +++++++++++ src/functionwrite.cpp | 34 ++++++++++++++++++++++ src/functionwrite.h | 17 +++++++++++ src/variable.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++ src/variable.h | 7 ++++- support/vim/syntax/build.vim | 2 +- 14 files changed, 364 insertions(+), 3 deletions(-) create mode 100644 src/filemgr.cpp create mode 100644 src/filemgr.h create mode 100644 src/functionclose.cpp create mode 100644 src/functionclose.h create mode 100644 src/functionopen.cpp create mode 100644 src/functionopen.h create mode 100644 src/functionread.cpp create mode 100644 src/functionread.h create mode 100644 src/functionwrite.cpp create mode 100644 src/functionwrite.h diff --git a/src/filemgr.cpp b/src/filemgr.cpp new file mode 100644 index 0000000..00f0410 --- /dev/null +++ b/src/filemgr.cpp @@ -0,0 +1,46 @@ +#include "filemgr.h" + +FileMgr::FileMgr() : + iNextId( 1 ) +{ +} + +FileMgr::~FileMgr() +{ + for( FileHash::iterator i = hFile.begin(); i; i++ ) + { + delete *i; + } +} + +int FileMgr::open( const Bu::String &sPath, int iMode ) +{ + hFile.insert( iNextId, new Bu::File( sPath, iMode ) ); + return iNextId++; +} + +Bu::File &FileMgr::get( int iId ) +{ + try + { + return *hFile.get( iId ); + } + catch(...) + { + throw Bu::ExceptionBase("Invalid file handle accessed."); + } +} + +void FileMgr::close( int iId ) +{ + try + { + delete hFile.get( iId ); + hFile.erase( iId ); + } + catch(...) + { + throw Bu::ExceptionBase("Invalid file handle accessed."); + } +} + diff --git a/src/filemgr.h b/src/filemgr.h new file mode 100644 index 0000000..517e784 --- /dev/null +++ b/src/filemgr.h @@ -0,0 +1,26 @@ +#ifndef FILE_MGR_H +#define FILE_MGR_H + +#include +#include +#include + +class FileMgr : public Bu::Singleton +{ +friend class Bu::Singleton; +private: + FileMgr(); + virtual ~FileMgr(); + +public: + int open( const Bu::String &sPath, int iMode ); + Bu::File &get( int iId ); + void close( int iId ); + +private: + typedef Bu::Hash FileHash; + FileHash hFile; + int iNextId; +}; + +#endif diff --git a/src/functionclose.cpp b/src/functionclose.cpp new file mode 100644 index 0000000..ac9c6f6 --- /dev/null +++ b/src/functionclose.cpp @@ -0,0 +1,26 @@ +#include "functionclose.h" +#include "filemgr.h" + +#include +PluginInterface3( pluginFunctionClose, close, FunctionClose, Function, + "Mike Buland", 0, 1 ); + +FunctionClose::FunctionClose() +{ +} + +FunctionClose::~FunctionClose() +{ +} + +Bu::String FunctionClose::getName() const +{ + return "close"; +} + +Variable FunctionClose::call( Variable &input, VarList ) +{ + FileMgr::getInstance().close( (int)input.getOpaque() ); + return Variable(); +} + diff --git a/src/functionclose.h b/src/functionclose.h new file mode 100644 index 0000000..0a30427 --- /dev/null +++ b/src/functionclose.h @@ -0,0 +1,17 @@ +#ifndef FUNCTION_CLOSE_H +#define FUNCTION_CLOSE_H + +#include "function.h" + +class FunctionClose : public Function +{ +public: + FunctionClose(); + virtual ~FunctionClose(); + + virtual Bu::String getName() const; + virtual Variable call( Variable &input, VarList lParams ); + +}; + +#endif diff --git a/src/functionopen.cpp b/src/functionopen.cpp new file mode 100644 index 0000000..4026a8c --- /dev/null +++ b/src/functionopen.cpp @@ -0,0 +1,42 @@ +#include "functionopen.h" +#include "filemgr.h" + +#include +PluginInterface3( pluginFunctionOpen, open, FunctionOpen, Function, + "Mike Buland", 0, 1 ); + +FunctionOpen::FunctionOpen() +{ +} + +FunctionOpen::~FunctionOpen() +{ +} + +Bu::String FunctionOpen::getName() const +{ + return "open"; +} + +Variable FunctionOpen::call( Variable &input, VarList lParams ) +{ + if( lParams.getSize() != 2 ) + { + throw Bu::ExceptionBase( + "open takes two parameters, filename and mode." + ); + } + Bu::String sMode = lParams.last().toString().toLower(); + int iMode = Bu::File::Create; + if( sMode.find('w') ) + iMode |= Bu::File::Write; + if( sMode.find('r') ) + iMode |= Bu::File::Read; + Variable vRet( + (void *)FileMgr::getInstance().open( + lParams.first().toString(), iMode + ) + ); + return vRet; +} + diff --git a/src/functionopen.h b/src/functionopen.h new file mode 100644 index 0000000..5ab3cab --- /dev/null +++ b/src/functionopen.h @@ -0,0 +1,17 @@ +#ifndef FUNCTION_OPEN_H +#define FUNCTION_OPEN_H + +#include "function.h" + +class FunctionOpen : public Function +{ +public: + FunctionOpen(); + virtual ~FunctionOpen(); + + virtual Bu::String getName() const; + virtual Variable call( Variable &input, VarList lParams ); + +}; + +#endif diff --git a/src/functionplugger.cpp b/src/functionplugger.cpp index c7b270c..a7b4cf5 100644 --- a/src/functionplugger.cpp +++ b/src/functionplugger.cpp @@ -17,6 +17,10 @@ extern Bu::PluginInfo pluginFunctionToString; extern Bu::PluginInfo pluginFunctionUnlink; extern Bu::PluginInfo pluginFunctionRegEx; extern Bu::PluginInfo pluginFunctionRange; +extern Bu::PluginInfo pluginFunctionOpen; +extern Bu::PluginInfo pluginFunctionClose; +extern Bu::PluginInfo pluginFunctionRead; +extern Bu::PluginInfo pluginFunctionWrite; FunctionPlugger::FunctionPlugger() { @@ -33,7 +37,10 @@ FunctionPlugger::FunctionPlugger() registerBuiltinPlugin( &pluginFunctionToString ); registerBuiltinPlugin( &pluginFunctionUnlink ); registerBuiltinPlugin( &pluginFunctionRegEx ); - registerBuiltinPlugin( &pluginFunctionRange ); + registerBuiltinPlugin( &pluginFunctionOpen ); + registerBuiltinPlugin( &pluginFunctionClose ); + registerBuiltinPlugin( &pluginFunctionRead ); + registerBuiltinPlugin( &pluginFunctionWrite ); DIR *dir = opendir("/usr/lib/build"); if( !dir ) diff --git a/src/functionread.cpp b/src/functionread.cpp new file mode 100644 index 0000000..789e9e1 --- /dev/null +++ b/src/functionread.cpp @@ -0,0 +1,40 @@ +#include "functionread.h" +#include "filemgr.h" + +#include +PluginInterface3( pluginFunctionRead, read, FunctionRead, Function, + "Mike Buland", 0, 1 ); + +FunctionRead::FunctionRead() +{ +} + +FunctionRead::~FunctionRead() +{ +} + +Bu::String FunctionRead::getName() const +{ + return "read"; +} + +Variable FunctionRead::call( Variable &input, VarList lParams ) +{ + Variable vRet; + if( lParams.getSize() == 1 ) + { + int iSize = lParams.first().toInt(); + Bu::String sBuf( iSize ); + sBuf.resize( + FileMgr::getInstance().get( (int)input.getOpaque() ).read( + sBuf.getStr(), iSize + ) + ); + vRet = sBuf; + return vRet; + } + throw Bu::ExceptionBase( + "read takes zero or one parameters." + ); +} + diff --git a/src/functionread.h b/src/functionread.h new file mode 100644 index 0000000..39bf32e --- /dev/null +++ b/src/functionread.h @@ -0,0 +1,17 @@ +#ifndef FUNCTION_READ_H +#define FUNCTION_READ_H + +#include "function.h" + +class FunctionRead : public Function +{ +public: + FunctionRead(); + virtual ~FunctionRead(); + + virtual Bu::String getName() const; + virtual Variable call( Variable &input, VarList lParams ); + +}; + +#endif diff --git a/src/functionwrite.cpp b/src/functionwrite.cpp new file mode 100644 index 0000000..7abb661 --- /dev/null +++ b/src/functionwrite.cpp @@ -0,0 +1,34 @@ +#include "functionwrite.h" +#include "filemgr.h" + +#include +PluginInterface3( pluginFunctionWrite, write, FunctionWrite, Function, + "Mike Buland", 0, 1 ); + +FunctionWrite::FunctionWrite() +{ +} + +FunctionWrite::~FunctionWrite() +{ +} + +Bu::String FunctionWrite::getName() const +{ + return "write"; +} + +Variable FunctionWrite::call( Variable &input, VarList lParams ) +{ + if( lParams.getSize() != 1 ) + { + throw Bu::ExceptionBase( + "write takes one parameter, the string to write." + ); + } + FileMgr::getInstance().get( (int)input.getOpaque() ).write( + lParams.first().toString() + ); + return Variable(); +} + diff --git a/src/functionwrite.h b/src/functionwrite.h new file mode 100644 index 0000000..75b2283 --- /dev/null +++ b/src/functionwrite.h @@ -0,0 +1,17 @@ +#ifndef FUNCTION_WRITE_H +#define FUNCTION_WRITE_H + +#include "function.h" + +class FunctionWrite : public Function +{ +public: + FunctionWrite(); + virtual ~FunctionWrite(); + + virtual Bu::String getName() const; + virtual Variable call( Variable &input, VarList lParams ); + +}; + +#endif diff --git a/src/variable.cpp b/src/variable.cpp index 6c9529c..f638dc9 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -137,6 +137,13 @@ Variable::Variable( const VarList &lst ) uVal.lVal = new VarList( lst ); } +Variable::Variable( void *oVal ) : + eType( typeOpaque ) +{ + memset( &uVal, 0, sizeof(uVal) ); + uVal.oVal = oVal; +} + Variable::~Variable() { if( eType == typeString || eType == typeRef ) @@ -191,6 +198,12 @@ const VarList &Variable::getList() const return *uVal.lVal; } +const void *Variable::getOpaque() const +{ + if( eType != typeOpaque ) throw Bu::ExceptionBase("Wrong variable type."); + return uVal.oVal; +} + int Variable::toInt() const { switch( eType ) @@ -302,6 +315,10 @@ Bu::String Variable::toString() const case typeVersion: break; + + case typeOpaque: + sRet = Bu::String("").arg( uVal.oVal ); + break; } return sRet; @@ -341,6 +358,9 @@ Variable Variable::toType( Type eNewType ) const case typeRef: return Variable::mkRef( toString() ); + + case typeOpaque: + throw Bu::ExceptionBase("Cannot convert opaque types."); } throw Bu::ExceptionBase("Unhandled case in Variable toType"); } @@ -402,6 +422,9 @@ void Variable::doNegate() case typeRef: throw Bu::ExceptionBase("You cannot negate reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot negate opaque values."); } } @@ -463,6 +486,14 @@ const Variable &Variable::operator=( const Bu::String &rhs ) return *this; } +const Variable &Variable::operator=( void *rhs ) +{ + reset( typeOpaque ); + uVal.oVal = rhs; + + return *this; +} + const Variable &Variable::operator+=( const Variable &rhs ) { switch( eType ) @@ -575,6 +606,9 @@ bool Variable::operator==( const Variable &rhs ) const case typeVersion: return false; + + case typeOpaque: + return uVal.oVal == rhs.uVal.oVal; } return false; @@ -613,6 +647,9 @@ bool Variable::operator<( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot < compare reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot < compare opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable < compare"); } @@ -645,6 +682,9 @@ bool Variable::operator>( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot > compare reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot > compare opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable > compare"); } @@ -677,6 +717,9 @@ bool Variable::operator<=( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot <= compare reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot <= compare opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable <= compare"); } @@ -709,6 +752,9 @@ bool Variable::operator>=( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot >= compare reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot >= compare opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable >= compare"); } @@ -741,6 +787,9 @@ Variable Variable::operator+( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot add reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot add opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable add"); } @@ -773,6 +822,9 @@ Variable Variable::operator-( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot subtract reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot subtract opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable subtract"); } @@ -805,6 +857,9 @@ Variable Variable::operator*( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot multiply reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot multiply opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable multiply"); } @@ -837,6 +892,9 @@ Variable Variable::operator/( const Variable &rhs ) const case typeRef: throw Bu::ExceptionBase("You cannot divide reference values."); + + case typeOpaque: + throw Bu::ExceptionBase("You cannot divide opaque values."); } throw Bu::ExceptionBase("Unhandled case in Variable divide"); } @@ -868,6 +926,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, const Variable::Type &t ) case Variable::typeList: f << "list"; break; case Variable::typeVersion: f << "version"; break; case Variable::typeRef: f << "ref"; break; + case Variable::typeOpaque: f << "opaque"; break; } return f; } @@ -885,6 +944,8 @@ Bu::Formatter &operator<<( Bu::Formatter &f, const Variable &v ) case Variable::typeList: f << v.getList(); break; case Variable::typeVersion:/*f << v.getVersion();*/ break; case Variable::typeRef: f << v.getString(); break; + case Variable::typeOpaque: f << ""; + break; } return f; @@ -924,6 +985,9 @@ Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Variable &v ) case Variable::typeRef: ar << *v.uVal.sVal; break; + + case Variable::typeOpaque: + break; } return ar; @@ -966,6 +1030,9 @@ Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Variable &v ) case Variable::typeRef: ar >> *v.uVal.sVal; break; + + case Variable::typeOpaque: + break; } return ar; diff --git a/src/variable.h b/src/variable.h index 260c96a..241393e 100644 --- a/src/variable.h +++ b/src/variable.h @@ -21,7 +21,8 @@ public: typeVersion, typeString, typeList, - typeRef /**< Reference by name, it's just a string. */ + typeRef, /**< Reference by name, it's just a string. */ + typeOpaque /**< Only useful to functions. */ }; public: @@ -41,6 +42,7 @@ public: */ Variable( const StrList &lst ); Variable( const VarList &lst ); + Variable( void *oVal ); virtual ~Variable(); static Variable mkRef( const Bu::String &sVal ); @@ -54,6 +56,7 @@ public: bool getBool() const; const Bu::String &getString() const; const VarList &getList() const; + const void *getOpaque() const; // Conversion functions, they'll return the requested type, maybe an error // if the source data is really bad @@ -77,6 +80,7 @@ public: const Variable &operator=( const double &rhs ); const Variable &operator=( const bool &rhs ); const Variable &operator=( const Bu::String &rhs ); + const Variable &operator=( void *rhs ); const Variable &operator+=( const Variable &rhs ); const Variable &operator<<( const Variable &rhs ); @@ -102,6 +106,7 @@ private: bool bVal; Bu::String *sVal; VarList *lVal; + void *oVal; } uVal; void reset( Type eType ); diff --git a/support/vim/syntax/build.vim b/support/vim/syntax/build.vim index a867092..721cfd4 100644 --- a/support/vim/syntax/build.vim +++ b/support/vim/syntax/build.vim @@ -15,7 +15,7 @@ endif syn keyword Conditional if then else syn keyword Loop for do in syn keyword Logic not and or -syn keyword Statement include set unset function target input condition requires rule profile auto config display type default cache global value return output allow action warning error notice local continue break all export tag range +syn keyword Statement include set unset function target input condition requires rule profile auto config display type default cache global value return output allow action warning error notice local continue break all export tag range open close read write syn keyword Todo TODO FIXME XXX syn keyword Type int string bool float version syn keyword Constant null true false file never always important normal hidden autogenerated filetime -- cgit v1.2.3