From 96ca22c7a1f9c5990e136a6ccddc8a33319b9043 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 3 Dec 2007 19:51:09 +0000 Subject: Hey, Bu::MiniMacro works, that's a funny name. There's still some more to add, but it does everything I need it to at the moment. --- src/minimacro.cpp | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/minimacro.h | 68 ++++++++++++++++++++++++++++++- 2 files changed, 183 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/minimacro.cpp b/src/minimacro.cpp index 274c13b..374b7de 100644 --- a/src/minimacro.cpp +++ b/src/minimacro.cpp @@ -6,12 +6,129 @@ */ #include "bu/minimacro.h" +#include "bu/exceptions.h" Bu::MiniMacro::MiniMacro() { + hFuncs.insert("toupper", new FuncToUpper() ); + hFuncs.insert("tolower", new FuncToLower() ); } Bu::MiniMacro::~MiniMacro() { } +Bu::FString Bu::MiniMacro::parse( const Bu::FString &sIn ) +{ + Bu::FString sOut; + for( sCur = sIn.getStr(); *sCur; sCur++ ) + { + if( *sCur == '{' ) + { + switch( sCur[1] ) + { + case '=': + sCur += 2; + sOut += parseRepl(); + break; + + case '?': + sCur += 2; + sOut += parseCond(); + break; + + case ':': + sCur += 2; + sOut += parseCmd(); + break; + + default: + sOut += *sCur; + continue; + } + } + else + { + sOut += *sCur; + } + } + + return sOut; +} + +Bu::FString Bu::MiniMacro::parseRepl() +{ + Bu::FString sOut; + bool bIsFirst = true; + for( const char *sNext = sCur;;) + { + for(; *sNext != ':' && *sNext != '}' && *sNext != '\0'; sNext++ ); + if( *sNext == '\0' ) + break; + Bu::FString sName( sCur, (int)sNext-(int)sCur ); + if( bIsFirst ) + { + sOut = hVars[sName]; + bIsFirst = false; + printf("Variable: \"%s\"\n", sName.getStr() ); + } + else + { + sOut = callFunc( sOut, sName ); + printf("Filter: \"%s\"\n", sName.getStr() ); + } + if( *sNext == '}' ) + { + sCur = sNext; + break; + } + else if( *sNext == ':' ) + { + } + sNext++; + sCur = sNext; + } + return sOut; +} + +Bu::FString Bu::MiniMacro::parseCond() +{ + Bu::FString sOut; + printf("%20s\n", sCur ); + return sOut; +} + +Bu::FString Bu::MiniMacro::parseCmd() +{ + Bu::FString sOut; + printf("%20s\n", sCur ); + return sOut; +} + +Bu::FString Bu::MiniMacro::callFunc( + const Bu::FString &sIn, const Bu::FString &sFunc ) +{ + int i = sFunc.find('('); + if( i < 0 ) + throw Bu::ExceptionBase("That doesn't look like a function call"); + Bu::FString sName( sFunc.getStr(), i ); + StrList lsParams; + for( const char *s = sFunc.getStr()+i+1; *s && *s != ')'; s++ ) + { + for(; *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n'; s++ ); + const char *sNext; + for( sNext = s; *sNext && *sNext != ')' && *sNext != ','; sNext++ ); + Bu::FString p( s, (int)sNext-(int)s ); + lsParams.append( p ); + sNext++; + s = sNext; + } + return hFuncs.get( sName )->call( sIn, lsParams ); +} + +void Bu::MiniMacro::addVar( + const Bu::FString &sName, const Bu::FString &sValue ) +{ + hVars.insert( sName, sValue ); +} + diff --git a/src/minimacro.h b/src/minimacro.h index e136015..105a117 100644 --- a/src/minimacro.h +++ b/src/minimacro.h @@ -8,6 +8,9 @@ #ifndef BU_MINI_MACRO_H #define BU_MINI_MACRO_H +#include "bu/hash.h" +#include "bu/fstring.h" + namespace Bu { /** @@ -32,14 +35,20 @@ namespace Bu * and a string to compare to. This is then followed by a text segment * that will be used if the test is true, and an optional text segment * to be used if the test is false. + * - ':': command. The ':' is immediately followed by a command string, + * of which there's only one right now, but that's ok. These are not + * put into the output stream, but instead mark something for the + * parser. Currently supported: + * - {:end}: end of parsing, stop here, also make note of how many input + * characters were used. * - Segments: * - Each segment is seperated by a colon. * - Filter segments give the name of the filter, followed by * parenthesies. Parameters may be provided within the parenthesies. * - Text segments should always be quoted, but may contain any characters * within the quotes, backslash is used as per C/ANSI/ISO standard. - * You can also quote any text using [" "] instead of quotes, which - * allows for nested strings. The [" token is only recognised within + * You can also quote any text using [' '] instead of quotes, which + * allows for nested strings. The [' token is only recognised within * a macro. * *@verbatim @@ -50,13 +59,68 @@ namespace Bu {?name="bob":"You're named bob!":"Who are you? I only know bob..."} @endverbatim */ + typedef Bu::Hash StrHash; class MiniMacro { public: MiniMacro(); virtual ~MiniMacro(); + Bu::FString parse( const Bu::FString &sIn ); + void addVar( const Bu::FString &sName, const Bu::FString &sValue ); + + private: + const char *sCur; + Bu::FString parseRepl(); + Bu::FString parseCond(); + Bu::FString parseCmd(); + Bu::FString callFunc( + const Bu::FString &sIn, const Bu::FString &sFunc ); + + StrHash hVars; + + public: + typedef Bu::List StrList; + class Func + { + public: + Func(){} + virtual ~Func(){} + virtual Bu::FString call( + const Bu::FString &sIn, StrList &lsParam )=0; + }; + + class FuncToUpper : public Func + { + public: + FuncToUpper(){} + virtual ~FuncToUpper(){} + virtual Bu::FString call( + const Bu::FString &sIn, StrList &lsParam ) + { + Bu::FString sOut( sIn ); + sOut.toUpper(); + return sOut; + } + }; + + class FuncToLower : public Func + { + public: + FuncToLower(){} + virtual ~FuncToLower(){} + virtual Bu::FString call( + const Bu::FString &sIn, StrList &lsParam ) + { + Bu::FString sOut( sIn ); + sOut.toLower(); + return sOut; + } + }; + private: + typedef Bu::Hash FuncHash; + FuncHash hFuncs; }; }; -- cgit v1.2.3