diff --git a/src/ezc.cpp b/src/ezc.cpp index 628c300..5c8bacb 100644 --- a/src/ezc.cpp +++ b/src/ezc.cpp @@ -8,23 +8,6 @@ * */ -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() @@ -37,13 +20,14 @@ Ezc::Ezc() } -void Ezc::CreateTree() +void Ezc::CreateTree(const char * file) { - item_root.ClearTable(); - item_root.type = Item::item_container; + std::string file_name = "\""; + file_name += file; - const char * pinput = input.c_str(); - item_root.CreateTree(pinput); + item_root.directives.clear(); + item_root.directives.push_back( file_name ); + item_root.CreateTreeReadInclude(); } @@ -62,6 +46,7 @@ void Ezc::Insert(const std::string & key, UserFunction ufunction) { UserInfo ui; ui.user_function = ufunction; + ui.iter = 0; user_info_table.insert( std::make_pair(key, ui) ); } @@ -105,6 +90,23 @@ Ezc::Item::~Item() ClearTable(); } +void Ezc::Item::ReadFile(const char * name, std::string & result) +{ + std::ifstream file(name); + + if( !file ) + { + std::ostringstream buffer; + buffer << ""; + result = buffer.str(); + + return; + } + + std::getline(file, result, '\0'); +} + + Ezc::Item::ItemType Ezc::Item::LastItemType() { if( item_table.empty() ) @@ -153,7 +155,7 @@ void Ezc::Item::ReadDirective(const char * & itext, std::string & directive) while( (*itext>='a' && *itext<='z') || (*itext>='A' && *itext<='Z') || (*itext>='0' && *itext<='9') || - *itext=='_' || *itext=='-' ) + *itext=='_' || *itext=='-' || *itext=='.' ) { directive += *itext; @@ -161,6 +163,60 @@ void Ezc::Item::ReadDirective(const char * & itext, std::string & directive) } } +void Ezc::Item::ReadString(const char * & itext, std::string & directive) +{ + directive.clear(); + + SkipWhiteCharacters(itext); + + if( *itext != '\"' ) + return; + + // string is signed by its first character equal (") + directive += *itext; + ++itext; + + while( (*itext>='a' && *itext<='z') || + (*itext>='A' && *itext<='Z') || + (*itext>='0' && *itext<='9') || + *itext=='_' || *itext=='-' || *itext=='.' || *itext==' ' + || *itext==':' || *itext=='\\' )// tymczasowo + { + directive += *itext; + + ++itext; + } + + if( *itext != '\"' ) + { + // the second quotation mark (") is missing + directive.clear(); + } + else + { + ++itext; + } + + // the second quotation mark (") we don't add into the 'directive' +} + + +void Ezc::Item::ReadDirectiveOrString(const char * & itext, std::string & directive) +{ + SkipWhiteCharacters(itext); + + if( *itext == '\"' ) + { + // we've got string + return ReadString(itext, directive); + } + else + { + return ReadDirective(itext, directive); + } +} + + void Ezc::Item::CreateTreeReadItemDirectiveCheckEnding(const char * & itext) { SkipWhiteCharacters(itext); @@ -200,6 +256,49 @@ std::string directive; directives.push_back(directive); } + + if( directives.empty() ) + type = item_err; + } + else + if( directive == "is" ) + { + type = item_is; + + ReadDirective(itext,directive); + + if( !directive.empty() ) + { + directives.push_back(directive); + + ReadDirectiveOrString(itext,directive); + + if( !directive.empty() ) + directives.push_back(directive); + } + + if( directives.size() != 2 ) + type = item_err; + } + else + if( directive == "if-index" ) + { + type = item_ifindex; + + ReadDirective(itext,directive); + + if( !directive.empty() ) + { + directives.push_back(directive); + + ReadDirective(itext,directive); + + if( !directive.empty() ) + directives.push_back(directive); + } + + if( directives.size() != 2 ) + type = item_err; } else if( directive == "end" ) @@ -220,6 +319,20 @@ std::string directive; if( !directive.empty() ) directives.push_back(directive); + else + type = item_err; + } + else + if( directive == "include" ) + { + type = item_include; + + ReadString(itext,directive); + + if( !directive.empty() ) + directives.push_back(directive); + else + type = item_err; } else { @@ -264,24 +377,6 @@ 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); - - if( item.type == Item::item_for ) - item_table.back()->CreateTreeReadFor(itext); - } -} bool Ezc::Item::CreateTreeReadDeleteLastEndItem() { @@ -300,7 +395,25 @@ bool Ezc::Item::CreateTreeReadDeleteLastEndItem() return false; } -void Ezc::Item::CreateTreeReadIfany(const char * & itext) +void Ezc::Item::CreateTreeReadInclude() +{ + if( directives.empty() || directives[0].empty() || directives[0][0]!='\"' ) + return; + + ClearTable(); + type = item_container; + + std::string file_text; + + ReadFile(directives[0].c_str()+1, file_text); + + const char * pinput = file_text.c_str(); + CreateTree(pinput); + +} + + +void Ezc::Item::CreateTreeReadIf(const char * & itext) { Item item; @@ -344,8 +457,29 @@ Item item; void Ezc::Item::CreateTree(const char * & itext) { - if( type == item_container) - CreateTreeReadAll(itext); + if( type != item_container) + return; + + 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.type == Item::item_ifindex || + item.type == Item::item_is ) + item_table.back()->CreateTreeReadIf(itext); + + if( item.type == Item::item_for ) + item_table.back()->CreateTreeReadFor(itext); + + if( item.type == item_include ) + item_table.back()->CreateTreeReadInclude(); + } } @@ -430,6 +564,132 @@ void Ezc::Item::MakeTextIfany(std::string & otext, UserInfoTable & user_info_tab } +void Ezc::Item::MakeTextIs(std::string & otext, UserInfoTable & user_info_table) +{ + if( directives.size() != 2 ) + return; + + bool result = false; + UserInfoTable::iterator i = user_info_table.find( directives[0] ); + + if( i != user_info_table.end() ) + { + Info info1, info2; + info1.result = info2.result = false; + info1.iter = info2.iter = 0; + (i->second.user_function)(info1); + + if( !directives[1].empty() && directives[1][0]=='\"' ) + { + if( std::strcmp(info1.text.c_str(), directives[1].c_str()+1) == 0 ) + result = true; + } + else + { + i = user_info_table.find( directives[1] ); + + if( i != user_info_table.end() ) + { + (i->second.user_function)(info2); + + if( info1.result==info2.result && info1.text==info2.text ) + result = true; + } + else + { + MakeTextMsgCantFind(otext, directives[1]); + } + } + } + else + { + MakeTextMsgCantFind(otext, directives[0]); + } + + + + if( result ) + { + // 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_info_table); + } +} + + + +void Ezc::Item::MakeTextIfindex(std::string & otext, UserInfoTable & user_info_table) +{ + if( directives.size() != 2 ) + return; + + UserInfoTable::iterator i = user_info_table.find( directives[0] ); + + if( i == user_info_table.end() ) + { + MakeTextMsgCantFind(otext, directives[0]); + } + + bool result = false; + + if( directives[1] == "odd" ) + { + if( ( i->second.iter & 1) == 1 ) + result = true; + } + else + if( directives[1] == "even" ) + { + if( ( i->second.iter & 1) == 0 ) + result = true; + } + else + if( directives[1] == "first" ) + { + if( i->second.iter == 0 ) + result = true; + } + else + { + const char * number_text = directives[1].c_str(); + char * last_char; + + int number = (int)strtol(number_text, &last_char, 10); + + if( *last_char == '\0' ) + { + if( i->second.iter == number ) + result = true; + } + else + { + otext += ""; + } + + } + + + if( result ) + { + // 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_info_table); + } +} + + void Ezc::Item::MakeTextFor(std::string & otext, UserInfoTable & user_info_table) { if( directives.empty() ) @@ -449,14 +709,15 @@ void Ezc::Item::MakeTextFor(std::string & otext, UserInfoTable & user_info_table 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); + + ++info.iter; + i->second.iter = info.iter; } } else @@ -488,6 +749,16 @@ void Ezc::Item::MakeText(std::string & otext, UserInfoTable & user_info_table) MakeTextIfany(otext, user_info_table); } else + if( type == item_ifindex ) + { + MakeTextIfindex(otext, user_info_table); + } + else + if( type == item_is ) + { + MakeTextIs(otext, user_info_table); + } + else if( type == item_for ) { MakeTextFor(otext, user_info_table); diff --git a/src/ezc.h b/src/ezc.h index acf8690..75b71d2 100644 --- a/src/ezc.h +++ b/src/ezc.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include class Ezc @@ -32,8 +34,7 @@ public: Ezc(); void Init(); - bool ReadFile(const char * name); - void CreateTree(); + void CreateTree(const char * file); std::string MakeText(); void Insert(const std::string & key, UserFunction ufunction); @@ -43,7 +44,7 @@ private: enum ItemType { item_none, item_container, item_text, item_ifany, item_for, item_else, - item_end, item_err, item_normal + item_end, item_err, item_normal, item_ifindex, item_include, item_is }; ItemType type; @@ -55,8 +56,11 @@ private: Item(); ~Item(); Item * AddItem(const Item & porg); + void ReadFile(const char * name, std::string & result); void SkipWhiteCharacters(const char * & itext); void ReadDirective(const char * & itext, std::string & directive); + void ReadString(const char * & itext, std::string & directive); + void ReadDirectiveOrString(const char * & itext, std::string & directive); void ClearTable(); ItemType LastItemType(); bool ReadChar(const char * & itext, char & result); @@ -64,18 +68,19 @@ private: 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 CreateTreeReadIf(const char * & itext); void CreateTreeReadFor(const char * & itext); bool CreateTreeReadDeleteLastEndItem(); + void CreateTreeReadInclude(); void CreateTree(const char * & itext); void MakeTextIfany(std::string & otext, UserInfoTable & user_info_table); + void MakeTextIfindex(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, UserInfoTable & user_info_table); - + void MakeTextIs(std::string & otext, UserInfoTable & user_info_table); void MakeText(std::string & otext,UserInfoTable & user_info_table); };