commit 700dcd0571dfc4a73369c6a32239f6397928f4ae Author: Tomasz Sowa Date: Wed Jan 24 20:01:55 2007 +0000 initial import git-svn-id: svn://ttmath.org/publicrep/cgi/ezc/trunk@4 e52654a7-88a9-db11-a3e9-0013d4bc506e diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..a99db80 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,28 @@ +Copyright (c) 2006-2007, Tomasz Sowa +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name Tomasz Sowa nor the names of contributors to this + project may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/ezc.cpp b/src/ezc.cpp new file mode 100644 index 0000000..767f8f3 --- /dev/null +++ b/src/ezc.cpp @@ -0,0 +1,410 @@ +#include "ezc.h" + + +/* + * + * Ezc + * + * + */ + +bool Ezc::ReadFile(const char * name) +{ + std::ifstream file(name); + + if( !file ) + { + std::ostringstream buffer; + buffer << ""; + input = buffer.str(); + + return false; + } + + std::getline(file, input, '\0'); + +return true; +} + + +void Ezc::Init() +{ +} + +Ezc::Ezc() +{ + Init(); +} + + +void Ezc::CreateTree() +{ + item_root.ClearTable(); + item_root.type = Item::item_container; + + const char * pinput = input.c_str(); + item_root.CreateTree(pinput); +} + + + +std::string Ezc::MakeText() +{ + output.clear(); + + item_root.MakeText(output, user_functions); + +return output; +} + + +void Ezc::Insert(const std::string & key, UserFunction ufunction) +{ + user_functions.insert( std::make_pair(key, ufunction) ); +} + + + +/* + * + * Ezc::Item + * + * + */ + + +Ezc::Item * Ezc::Item::AddItem(const Ezc::Item & porg) +{ + Item * pitem = new Item(porg); + + item_table.push_back(pitem); + +return pitem; +} + + +void Ezc::Item::ClearTable() +{ + std::vector::iterator i = item_table.begin(); + + for( ; i != item_table.end() ; ++i ) + delete *i; + + item_table.clear(); +} + +Ezc::Item::Item() +{ +} + +Ezc::Item::~Item() +{ + ClearTable(); +} + +Ezc::Item::ItemType Ezc::Item::LastItemType() +{ + if( item_table.empty() ) + return item_none; + +return item_table.back()->type; +} + + +bool Ezc::Item::ReadChar(const char * & itext, char & result) +{ + if( *itext==0 || *itext=='[' || *itext==']' ) + return false; + + + if( *itext == '\\' ) + { + if( *(itext+1)=='\\' || *(itext+1)=='[' || *(itext+1)==']' ) + { + result = *(++itext); + ++itext; + return true; + } + } + + result = *itext; + ++itext; + +return true; +} + + +void Ezc::Item::SkipWhiteCharacters(const char * & itext) +{ + while( *itext==' ' || *itext=='\t' ) + ++itext; +} + + +void Ezc::Item::ReadDirective(const char * & itext, std::string & directive) +{ + directive.clear(); + + SkipWhiteCharacters(itext); + + while( (*itext>='a' && *itext<='z') || + (*itext>='A' && *itext<='Z') || + (*itext>='0' && *itext<='9') || + *itext=='_' || *itext=='-' ) + { + directive += *itext; + + ++itext; + } +} + +void Ezc::Item::CreateTreeReadItemDirectiveCheckEnding(const char * & itext) +{ + SkipWhiteCharacters(itext); + + if( *itext != ']' ) + { + type = item_err; + + while( *itext!=0 && *itext!=']' ) + ++itext; + } + + if( *itext == ']' ) + ++itext; +} + + +void Ezc::Item::CreateTreeReadItemDirective(const char * & itext) +{ +std::string directive; + + ++itext; + directives.clear(); + + ReadDirective(itext,directive); + + if( directive == "if-any" ) + { + type = item_ifany; + + while( true ) + { + ReadDirective(itext,directive); + + if( directive.empty() ) + break; + + directives.push_back(directive); + } + } + else + if( directive == "end" ) + { + type = item_end; + } + else + if( directive == "else" ) + { + type = item_else; + } + else + { + directives.push_back(directive); + type = item_normal; + } + + CreateTreeReadItemDirectiveCheckEnding(itext); +} + + +void Ezc::Item::CreateTreeReadItemText(const char * & itext) +{ +char c; + + text.clear(); + + while( ReadChar(itext, c) ) + text += c; + + type = item_text; +} + + +bool Ezc::Item::CreateTreeReadItem(const char * & itext) +{ + + if( *itext == '[' ) + { + CreateTreeReadItemDirective(itext); + return true; + } + else + if( *itext ) + { + CreateTreeReadItemText(itext); + return true; + } + +// the end of the string +return false; +} + + +void Ezc::Item::CreateTreeReadAll(const char * & itext) +{ +Item item; + + while( item.CreateTreeReadItem(itext) ) + { + AddItem(item); + + if( item.type==item_end || item.type==item_else ) + return; + + if( item.type == Item::item_ifany ) + item_table.back()->CreateTreeReadIfany(itext); + } +} + + +void Ezc::Item::CreateTreeReadIfany(const char * & itext) +{ +Item item; + + item.type = item_container; + AddItem(item); + item_table.back()->CreateTree(itext); + + if( item_table.back()->LastItemType() == item_else ) + { + // basically we don't have to erase it + item_table.back()->item_table.erase( + item_table.back()->item_table.begin() + + item_table.back()->item_table.size() - 1 ); + + item.ClearTable(); + AddItem(item); + item_table.back()->CreateTree(itext); + } + + if( item_table.back()->LastItemType() != item_end ) + { + // [end] is missing + // it's probably the end of the input string + } + else + { + // basically we don't have to do it + item_table.back()->item_table.erase( + item_table.back()->item_table.begin() + + item_table.back()->item_table.size() - 1 ); + } +} + +void Ezc::Item::CreateTree(const char * & itext) +{ + if( type == item_container) + CreateTreeReadAll(itext); +} + + +// +void Ezc::Item::MakeTextContainer(std::string & otext, UserFunctions & user_functions) +{ + std::vector::iterator i = item_table.begin(); + + for( ; i != item_table.end() ; ++i ) + (*i)->MakeText(otext, user_functions); +} + + +void Ezc::Item::MakeTextMsgCantFind(std::string & otext, std::string & key) +{ + std::ostringstream msg; + + msg << ""; + otext += msg.str(); +} + + +void Ezc::Item::MakeTextNormal(std::string & otext, UserFunctions & user_functions) +{ + if( directives.empty() ) + return; + + UserFunctions::iterator i = user_functions.find( directives[0] ); + + if( i != user_functions.end() ) + { + EzcInfo info; + (i->second)(info); + + otext += info.text; + } + else + { + MakeTextMsgCantFind(otext, directives[0]); + } +} + +void Ezc::Item::MakeTextIfany(std::string & otext, UserFunctions & user_functions) +{ + std::vector::iterator d = directives.begin(); + int how_many_true = 0; + + for( ; d != directives.end() ; ++d ) + { + UserFunctions::iterator i = user_functions.find( *d ); + + if( i != user_functions.end() ) + { + EzcInfo info; + (i->second)(info); + + if( info.result ) + ++how_many_true; + } + else + { + MakeTextMsgCantFind(otext, *d); + } + } + + if( how_many_true == directives.size() ) + { + if( !item_table.empty() ) + item_table[0]->MakeText(otext, user_functions); + } + else + { + if( item_table.size() > 1 ) + item_table[1]->MakeText(otext, user_functions); + } +} + +void Ezc::Item::MakeText(std::string & otext, UserFunctions & user_functions) +{ + if( type == item_text ) + { + otext += text; + } + else + if( type == item_container ) + { + MakeTextContainer(otext, user_functions); + } + else + if( type == item_normal ) + { + MakeTextNormal(otext, user_functions); + } + else + if( type == item_ifany ) + { + MakeTextIfany(otext, user_functions); + } + + +} + diff --git a/src/ezc.h b/src/ezc.h new file mode 100644 index 0000000..486b3f0 --- /dev/null +++ b/src/ezc.h @@ -0,0 +1,81 @@ +#ifndef headerfileezc +#define headerfileezc + +#include +#include +#include +#include +#include + +struct EzcInfo +{ + std::string text; + bool result; + + EzcInfo() + { + result = false; + } +}; + +class Ezc +{ +public: + typedef void (*UserFunction)(EzcInfo &); + typedef std::map UserFunctions; + + UserFunctions user_functions; + + Ezc(); + void Init(); + bool ReadFile(const char * name); + void CreateTree(); + std::string MakeText(); + void Insert(const std::string & key, UserFunction ufunction); + +private: + struct Item + { + enum ItemType + { + item_none, item_container, item_text, item_ifany, item_for, item_else, + item_end, item_err, item_normal + }; + + ItemType type; + std::string text; + std::vector item_table; + + std::vector directives; + + Item(); + ~Item(); + Item * AddItem(const Item & porg); + void SkipWhiteCharacters(const char * & itext); + void ReadDirective(const char * & itext, std::string & directive); + void ClearTable(); + ItemType LastItemType(); + bool ReadChar(const char * & itext, char & result); + void CreateTreeReadItemDirectiveCheckEnding(const char * & itext); + void CreateTreeReadItemDirective(const char * & itext); + void CreateTreeReadItemText(const char * & itext); + bool CreateTreeReadItem(const char * & itext); + void CreateTreeReadAll(const char * & itext); + void CreateTreeReadIfany(const char * & itext); + void CreateTree(const char * & itext); + + void MakeTextIfany(std::string & otext, UserFunctions & user_functions); + void MakeTextContainer(std::string & otext, UserFunctions & user_functions); + void MakeTextMsgCantFind(std::string & otext, std::string & key); + void MakeTextNormal(std::string & otext, UserFunctions & user_functions); + + void MakeText(std::string & otext,UserFunctions & user_functions); + }; + + Item item_root; + std::string input; + std::string output; +}; + + +#endif