added [for]

EzcInfo pushed into Ezc::
added info about a wrong directive


git-svn-id: svn://ttmath.org/publicrep/cgi/ezc/trunk@5 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2007-01-25 08:25:40 +00:00
parent 700dcd0571
commit ac632987f3
2 changed files with 148 additions and 48 deletions

View File

@ -52,7 +52,7 @@ std::string Ezc::MakeText()
{ {
output.clear(); output.clear();
item_root.MakeText(output, user_functions); item_root.MakeText(output, user_info_table);
return output; return output;
} }
@ -60,7 +60,10 @@ return output;
void Ezc::Insert(const std::string & key, UserFunction ufunction) 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; type = item_else;
} }
else else
if( directive == "for" )
{
type = item_for;
ReadDirective(itext,directive);
if( !directive.empty() )
directives.push_back(directive);
}
else
{ {
directives.push_back(directive); directives.push_back(directive);
type = item_normal; type = item_normal;
@ -264,9 +277,28 @@ Item item;
if( item.type == Item::item_ifany ) if( item.type == Item::item_ifany )
item_table.back()->CreateTreeReadIfany(itext); 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) void Ezc::Item::CreateTreeReadIfany(const char * & itext)
{ {
@ -279,29 +311,37 @@ Item item;
if( item_table.back()->LastItemType() == item_else ) if( item_table.back()->LastItemType() == item_else )
{ {
// basically we don't have to erase it // basically we don't have to erase it
item_table.back()->item_table.erase( CreateTreeReadDeleteLastEndItem();
item_table.back()->item_table.begin() +
item_table.back()->item_table.size() - 1 );
item.ClearTable(); item.ClearTable();
AddItem(item); AddItem(item);
item_table.back()->CreateTree(itext); item_table.back()->CreateTree(itext);
} }
if( item_table.back()->LastItemType() != item_end ) if( !CreateTreeReadDeleteLastEndItem() )
{ {
// [end] is missing // [end] is missing
// it's probably the end of the input string // 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 // [end] is missing
item_table.back()->item_table.erase( // it's probably the end of the input string
item_table.back()->item_table.begin() +
item_table.back()->item_table.size() - 1 );
} }
} }
void Ezc::Item::CreateTree(const char * & itext) void Ezc::Item::CreateTree(const char * & itext)
{ {
if( type == item_container) 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<Item*>::iterator i = item_table.begin(); std::vector<Item*>::iterator i = item_table.begin();
for( ; i != item_table.end() ; ++i ) 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() ) if( directives.empty() )
return; 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; Info info;
(i->second)(info); info.result = false;
info.iter = 0;
(i->second.user_function)(info);
otext += info.text; 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<std::string>::iterator d = directives.begin(); std::vector<std::string>::iterator d = directives.begin();
int how_many_true = 0; int how_many_true = 0;
for( ; d != directives.end() ; ++d ) 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; Info info;
(i->second)(info); info.result = false;
info.iter = 0;
(i->second.user_function)(info);
if( info.result ) if( !info.text.empty() || info.result )
++how_many_true; ++how_many_true;
} }
else else
@ -373,17 +417,56 @@ void Ezc::Item::MakeTextIfany(std::string & otext, UserFunctions & user_function
if( how_many_true == directives.size() ) if( how_many_true == directives.size() )
{ {
if( !item_table.empty() ) // one element should be in the table (but we're testing)
item_table[0]->MakeText(otext, user_functions); if( item_table.size() > 0 )
item_table[0]->MakeText(otext, user_info_table);
} }
else else
{ {
// second element can be (or not -- it's from [else])
if( item_table.size() > 1 ) 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 ) if( type == item_text )
{ {
@ -392,17 +475,27 @@ void Ezc::Item::MakeText(std::string & otext, UserFunctions & user_functions)
else else
if( type == item_container ) if( type == item_container )
{ {
MakeTextContainer(otext, user_functions); MakeTextContainer(otext, user_info_table);
} }
else else
if( type == item_normal ) if( type == item_normal )
{ {
MakeTextNormal(otext, user_functions); MakeTextNormal(otext, user_info_table);
} }
else else
if( type == item_ifany ) 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 += "<!-- ezc: wrong directive -->";
} }

View File

@ -7,24 +7,28 @@
#include <vector> #include <vector>
#include <map> #include <map>
struct EzcInfo
{
std::string text;
bool result;
EzcInfo()
{
result = false;
}
};
class Ezc class Ezc
{ {
public: public:
typedef void (*UserFunction)(EzcInfo &); struct Info
typedef std::map<std::string, UserFunction> UserFunctions; {
std::string text;
bool result;
int iter;
};
UserFunctions user_functions; typedef void (*UserFunction)(Info &);
struct UserInfo
{
UserFunction user_function;
int iter;
};
typedef std::map<std::string, UserInfo> UserInfoTable;
UserInfoTable user_info_table;
Ezc(); Ezc();
void Init(); void Init();
@ -62,14 +66,17 @@ private:
bool CreateTreeReadItem(const char * & itext); bool CreateTreeReadItem(const char * & itext);
void CreateTreeReadAll(const char * & itext); void CreateTreeReadAll(const char * & itext);
void CreateTreeReadIfany(const char * & itext); void CreateTreeReadIfany(const char * & itext);
void CreateTreeReadFor(const char * & itext);
bool CreateTreeReadDeleteLastEndItem();
void CreateTree(const char * & itext); void CreateTree(const char * & itext);
void MakeTextIfany(std::string & otext, UserFunctions & user_functions); void MakeTextIfany(std::string & otext, UserInfoTable & user_info_table);
void MakeTextContainer(std::string & otext, UserFunctions & user_functions); 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 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; Item item_root;