diff --git a/src/ezc.cpp b/src/ezc.cpp index 767f8f3..628c300 100644 --- a/src/ezc.cpp +++ b/src/ezc.cpp @@ -52,7 +52,7 @@ std::string Ezc::MakeText() { output.clear(); - item_root.MakeText(output, user_functions); + item_root.MakeText(output, user_info_table); return output; } @@ -60,7 +60,10 @@ return output; void Ezc::Insert(const std::string & key, UserFunction ufunction) { - user_functions.insert( std::make_pair(key, ufunction) ); + UserInfo ui; + ui.user_function = ufunction; + + user_info_table.insert( std::make_pair(key, ui) ); } @@ -209,6 +212,16 @@ std::string directive; type = item_else; } else + if( directive == "for" ) + { + type = item_for; + + ReadDirective(itext,directive); + + if( !directive.empty() ) + directives.push_back(directive); + } + else { directives.push_back(directive); type = item_normal; @@ -264,9 +277,28 @@ Item item; if( item.type == Item::item_ifany ) item_table.back()->CreateTreeReadIfany(itext); + + if( item.type == Item::item_for ) + item_table.back()->CreateTreeReadFor(itext); } } +bool Ezc::Item::CreateTreeReadDeleteLastEndItem() +{ + if( item_table.empty() ) + return false; + + if( item_table.back()->LastItemType() == item_end ) + { + item_table.back()->item_table.erase( + item_table.back()->item_table.begin() + + item_table.back()->item_table.size() - 1 ); + + return true; + } + +return false; +} void Ezc::Item::CreateTreeReadIfany(const char * & itext) { @@ -279,29 +311,37 @@ Item item; 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 ); + CreateTreeReadDeleteLastEndItem(); item.ClearTable(); AddItem(item); item_table.back()->CreateTree(itext); } - if( item_table.back()->LastItemType() != item_end ) + if( !CreateTreeReadDeleteLastEndItem() ) { // [end] is missing // it's probably the end of the input string } - else +} + + +void Ezc::Item::CreateTreeReadFor(const char * & itext) +{ +Item item; + + item.type = item_container; + AddItem(item); + item_table.back()->CreateTree(itext); + + if( !CreateTreeReadDeleteLastEndItem() ) { - // 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 ); + // [end] is missing + // it's probably the end of the input string } } + void Ezc::Item::CreateTree(const char * & itext) { if( type == item_container) @@ -310,12 +350,12 @@ void Ezc::Item::CreateTree(const char * & itext) // -void Ezc::Item::MakeTextContainer(std::string & otext, UserFunctions & user_functions) +void Ezc::Item::MakeTextContainer(std::string & otext, UserInfoTable & user_info_table) { std::vector::iterator i = item_table.begin(); for( ; i != item_table.end() ; ++i ) - (*i)->MakeText(otext, user_functions); + (*i)->MakeText(otext, user_info_table); } @@ -328,17 +368,19 @@ void Ezc::Item::MakeTextMsgCantFind(std::string & otext, std::string & key) } -void Ezc::Item::MakeTextNormal(std::string & otext, UserFunctions & user_functions) +void Ezc::Item::MakeTextNormal(std::string & otext, UserInfoTable & user_info_table) { if( directives.empty() ) return; - UserFunctions::iterator i = user_functions.find( directives[0] ); + UserInfoTable::iterator i = user_info_table.find( directives[0] ); - if( i != user_functions.end() ) + if( i != user_info_table.end() ) { - EzcInfo info; - (i->second)(info); + Info info; + info.result = false; + info.iter = 0; + (i->second.user_function)(info); otext += info.text; } @@ -348,21 +390,23 @@ void Ezc::Item::MakeTextNormal(std::string & otext, UserFunctions & user_functio } } -void Ezc::Item::MakeTextIfany(std::string & otext, UserFunctions & user_functions) +void Ezc::Item::MakeTextIfany(std::string & otext, UserInfoTable & user_info_table) { std::vector::iterator d = directives.begin(); int how_many_true = 0; for( ; d != directives.end() ; ++d ) { - UserFunctions::iterator i = user_functions.find( *d ); + UserInfoTable::iterator i = user_info_table.find( *d ); - if( i != user_functions.end() ) + if( i != user_info_table.end() ) { - EzcInfo info; - (i->second)(info); + Info info; + info.result = false; + info.iter = 0; + (i->second.user_function)(info); - if( info.result ) + if( !info.text.empty() || info.result ) ++how_many_true; } else @@ -373,17 +417,56 @@ void Ezc::Item::MakeTextIfany(std::string & otext, UserFunctions & user_function if( how_many_true == directives.size() ) { - if( !item_table.empty() ) - item_table[0]->MakeText(otext, user_functions); + // one element should be in the table (but we're testing) + if( item_table.size() > 0 ) + item_table[0]->MakeText(otext, user_info_table); } else { + // second element can be (or not -- it's from [else]) if( item_table.size() > 1 ) - item_table[1]->MakeText(otext, user_functions); + item_table[1]->MakeText(otext, user_info_table); } } -void Ezc::Item::MakeText(std::string & otext, UserFunctions & user_functions) + +void Ezc::Item::MakeTextFor(std::string & otext, UserInfoTable & user_info_table) +{ + if( directives.empty() ) + return; + + + UserInfoTable::iterator i = user_info_table.find( directives[0] ); + + if( i != user_info_table.end() ) + { + Info info; + info.result = false; + info.iter = 0; + + i->second.iter = info.iter; + + while( true ) + { + (i->second.user_function)(info); + ++info.iter; + i->second.iter = info.iter; + + if( info.text.empty() && !info.result ) + break; + + if( item_table.size() > 0 ) + item_table[0]->MakeText(otext, user_info_table); + } + } + else + { + MakeTextMsgCantFind(otext, directives[0]); + } +} + + +void Ezc::Item::MakeText(std::string & otext, UserInfoTable & user_info_table) { if( type == item_text ) { @@ -392,17 +475,27 @@ void Ezc::Item::MakeText(std::string & otext, UserFunctions & user_functions) else if( type == item_container ) { - MakeTextContainer(otext, user_functions); + MakeTextContainer(otext, user_info_table); } else if( type == item_normal ) { - MakeTextNormal(otext, user_functions); + MakeTextNormal(otext, user_info_table); } else if( type == item_ifany ) { - MakeTextIfany(otext, user_functions); + MakeTextIfany(otext, user_info_table); + } + else + if( type == item_for ) + { + MakeTextFor(otext, user_info_table); + } + else + if( type == item_err ) + { + otext += ""; } diff --git a/src/ezc.h b/src/ezc.h index 486b3f0..acf8690 100644 --- a/src/ezc.h +++ b/src/ezc.h @@ -7,24 +7,28 @@ #include #include -struct EzcInfo -{ - std::string text; - bool result; - - EzcInfo() - { - result = false; - } -}; class Ezc { public: - typedef void (*UserFunction)(EzcInfo &); - typedef std::map UserFunctions; + struct Info + { + std::string text; + bool result; + int iter; + }; - UserFunctions user_functions; + typedef void (*UserFunction)(Info &); + + struct UserInfo + { + UserFunction user_function; + int iter; + }; + + typedef std::map UserInfoTable; + + UserInfoTable user_info_table; Ezc(); void Init(); @@ -62,14 +66,17 @@ private: bool CreateTreeReadItem(const char * & itext); void CreateTreeReadAll(const char * & itext); void CreateTreeReadIfany(const char * & itext); + void CreateTreeReadFor(const char * & itext); + bool CreateTreeReadDeleteLastEndItem(); void CreateTree(const char * & itext); - void MakeTextIfany(std::string & otext, UserFunctions & user_functions); - void MakeTextContainer(std::string & otext, UserFunctions & user_functions); + void MakeTextIfany(std::string & otext, UserInfoTable & user_info_table); + void MakeTextFor(std::string & otext, UserInfoTable & user_info_table); + void MakeTextContainer(std::string & otext, UserInfoTable & user_info_table); void MakeTextMsgCantFind(std::string & otext, std::string & key); - void MakeTextNormal(std::string & otext, UserFunctions & user_functions); + void MakeTextNormal(std::string & otext, UserInfoTable & user_info_table); - void MakeText(std::string & otext,UserFunctions & user_functions); + void MakeText(std::string & otext,UserInfoTable & user_info_table); }; Item item_root;