changed: [is ...] command
struct Info doesn't have out_string now git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@281 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
dbe91a6d91
commit
b2aacc2da3
307
src/ezc.cpp
307
src/ezc.cpp
|
@ -134,14 +134,14 @@ void Pattern::ParseFile(const std::string & file_name)
|
||||||
|
|
||||||
void Pattern::ParseFile(const char * file_name)
|
void Pattern::ParseFile(const char * file_name)
|
||||||
{
|
{
|
||||||
std::string file;
|
Item::Directive file;
|
||||||
|
|
||||||
|
file.is_text = true;
|
||||||
|
|
||||||
if( directory.empty() )
|
if( directory.empty() )
|
||||||
SplitUnixDirectory(file_name, directory, file);
|
SplitUnixDirectory(file_name, directory, file.name);
|
||||||
else
|
else
|
||||||
file = file_name;
|
file.name = file_name;
|
||||||
|
|
||||||
file.insert(file.begin(), '\"');
|
|
||||||
|
|
||||||
item_root.directives.clear();
|
item_root.directives.clear();
|
||||||
item_root.directives.push_back( file );
|
item_root.directives.push_back( file );
|
||||||
|
@ -191,6 +191,15 @@ return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
'name' must be a relative path
|
||||||
|
*/
|
||||||
|
std::string Pattern::ReadFile(const std::string & name)
|
||||||
|
{
|
||||||
|
return ReadFile(name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
'name' must be a relative path
|
'name' must be a relative path
|
||||||
*/
|
*/
|
||||||
|
@ -272,10 +281,11 @@ std::string::size_type i;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string Pattern::ReadDirective()
|
Pattern::Item::Directive Pattern::ReadDirective()
|
||||||
{
|
{
|
||||||
std::string directive;
|
Item::Directive directive;
|
||||||
|
|
||||||
|
directive.is_text = false;
|
||||||
SkipWhiteCharacters();
|
SkipWhiteCharacters();
|
||||||
|
|
||||||
while( (*itext>='a' && *itext<='z') ||
|
while( (*itext>='a' && *itext<='z') ||
|
||||||
|
@ -283,8 +293,7 @@ std::string directive;
|
||||||
(*itext>='0' && *itext<='9') ||
|
(*itext>='0' && *itext<='9') ||
|
||||||
*itext=='_' || *itext=='-' || *itext=='.' || *itext=='#' )
|
*itext=='_' || *itext=='-' || *itext=='.' || *itext=='#' )
|
||||||
{
|
{
|
||||||
directive += *itext;
|
directive.name += *itext;
|
||||||
|
|
||||||
++itext;
|
++itext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,36 +303,52 @@ return directive;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// string can have a quote character (escaped with a backslash) e.g. "sample text \"with quotes\""
|
||||||
std::string Pattern::ReadString(bool skip_first_quote)
|
// use \\ to insert one backslash
|
||||||
|
Pattern::Item::Directive Pattern::ReadString()
|
||||||
{
|
{
|
||||||
std::string directive;
|
Item::Directive directive;
|
||||||
|
|
||||||
|
directive.is_text = true;
|
||||||
SkipWhiteCharacters();
|
SkipWhiteCharacters();
|
||||||
|
|
||||||
|
// string is signed by its first character equal (")
|
||||||
if( *itext != '\"' )
|
if( *itext != '\"' )
|
||||||
return directive;
|
return directive;
|
||||||
|
|
||||||
// string is signed by its first character equal (")
|
// skipping the first quote character
|
||||||
if( !skip_first_quote )
|
++itext;
|
||||||
directive += '\"';
|
|
||||||
|
|
||||||
for( ++itext ; *itext && *itext!='\"' && *itext!='\n' ; ++itext )
|
for( ; *itext && *itext!='\"' && *itext!='\n' ; ++itext )
|
||||||
directive += *itext;
|
{
|
||||||
|
if( itext[0]=='\\' && itext[1]=='\"' )
|
||||||
|
{
|
||||||
|
directive.name += '\"';
|
||||||
|
++itext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( itext[0]=='\\' && itext[1]=='\\' )
|
||||||
|
{
|
||||||
|
directive.name += '\\';
|
||||||
|
++itext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directive.name += *itext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( *itext != '\"' )
|
if( *itext != '\"' )
|
||||||
// the second quotation mark (") is missing
|
// the second quotation mark (") is missing
|
||||||
directive.clear();
|
directive.name.clear();
|
||||||
else
|
else
|
||||||
++itext;
|
++itext;
|
||||||
|
|
||||||
// the second quotation mark (") we don't add into the 'directive'
|
|
||||||
|
|
||||||
return directive;
|
return directive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string Pattern::ReadDirectiveOrString()
|
Pattern::Item::Directive Pattern::ReadDirectiveOrString()
|
||||||
{
|
{
|
||||||
SkipWhiteCharacters();
|
SkipWhiteCharacters();
|
||||||
|
|
||||||
|
@ -362,9 +387,9 @@ void Pattern::ReadDirectiveIfany(Item & item)
|
||||||
|
|
||||||
while( true )
|
while( true )
|
||||||
{
|
{
|
||||||
std::string directive = ReadDirective();
|
Item::Directive directive = ReadDirective();
|
||||||
|
|
||||||
if( directive.empty() )
|
if( directive.name.empty() )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
|
@ -397,15 +422,15 @@ void Pattern::ReadDirectiveIfone(Item & item)
|
||||||
void Pattern::ReadDirectiveIs(Item & item)
|
void Pattern::ReadDirectiveIs(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_is;
|
item.type = Item::item_is;
|
||||||
std::string directive = ReadDirective();
|
Item::Directive directive = ReadDirectiveOrString();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( directive.is_text || !directive.name.empty() )
|
||||||
{
|
{
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
|
|
||||||
directive = ReadDirectiveOrString();
|
directive = ReadDirectiveOrString();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( directive.is_text || !directive.name.empty() )
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,15 +442,15 @@ void Pattern::ReadDirectiveIs(Item & item)
|
||||||
void Pattern::ReadDirectiveIfindex(Item & item)
|
void Pattern::ReadDirectiveIfindex(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_ifindex;
|
item.type = Item::item_ifindex;
|
||||||
std::string directive = ReadDirective();
|
Item::Directive directive = ReadDirective();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( !directive.name.empty() )
|
||||||
{
|
{
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
|
|
||||||
directive = ReadDirective();
|
directive = ReadDirective();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( !directive.name.empty() )
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,9 +462,9 @@ void Pattern::ReadDirectiveIfindex(Item & item)
|
||||||
void Pattern::ReadDirectiveFor(Item & item)
|
void Pattern::ReadDirectiveFor(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_for;
|
item.type = Item::item_for;
|
||||||
std::string directive = ReadDirective();
|
Item::Directive directive = ReadDirective();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( !directive.name.empty() )
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
else
|
else
|
||||||
item.type = Item::item_err;
|
item.type = Item::item_err;
|
||||||
|
@ -459,28 +484,27 @@ void Pattern::ReadDirectiveComment(Item & item)
|
||||||
void Pattern::ReadDirectiveInclude(Item & item)
|
void Pattern::ReadDirectiveInclude(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_include;
|
item.type = Item::item_include;
|
||||||
std::string directive = ReadString();
|
Item::Directive directive = ReadString();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( !directive.name.empty() )
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
else
|
else
|
||||||
item.type = Item::item_err;
|
item.type = Item::item_err;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveDef(Item & item)
|
void Pattern::ReadDirectiveDef(Item & item)
|
||||||
{
|
{
|
||||||
item.type = Item::item_def;
|
item.type = Item::item_def;
|
||||||
std::string directive = ReadDirective();
|
Item::Directive directive = ReadDirective();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( !directive.name.empty() )
|
||||||
{
|
{
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
|
|
||||||
directive = ReadDirectiveOrString();
|
directive = ReadDirectiveOrString();
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( directive.is_text || !directive.name.empty() )
|
||||||
item.directives.push_back(directive);
|
item.directives.push_back(directive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,39 +518,39 @@ void Pattern::CreateTreeReadItemDirective(Item & item)
|
||||||
{
|
{
|
||||||
++itext;
|
++itext;
|
||||||
|
|
||||||
std::string directive = ReadDirective();
|
Item::Directive directive = ReadDirective();
|
||||||
|
|
||||||
if( directive == "if-any" )
|
if( directive.name == "if-any" )
|
||||||
ReadDirectiveIfany(item);
|
ReadDirectiveIfany(item);
|
||||||
else
|
else
|
||||||
if( directive == "if-no" )
|
if( directive.name == "if-no" )
|
||||||
ReadDirectiveIfno(item);
|
ReadDirectiveIfno(item);
|
||||||
else
|
else
|
||||||
if( directive == "if-one" )
|
if( directive.name == "if-one" )
|
||||||
ReadDirectiveIfone(item);
|
ReadDirectiveIfone(item);
|
||||||
else
|
else
|
||||||
if( directive == "is" )
|
if( directive.name == "is" )
|
||||||
ReadDirectiveIs(item);
|
ReadDirectiveIs(item);
|
||||||
else
|
else
|
||||||
if( directive == "if-index" )
|
if( directive.name == "if-index" )
|
||||||
ReadDirectiveIfindex(item);
|
ReadDirectiveIfindex(item);
|
||||||
else
|
else
|
||||||
if( directive == "end" )
|
if( directive.name == "end" )
|
||||||
item.type = Item::item_end;
|
item.type = Item::item_end;
|
||||||
else
|
else
|
||||||
if( directive == "else" )
|
if( directive.name == "else" )
|
||||||
item.type = Item::item_else;
|
item.type = Item::item_else;
|
||||||
else
|
else
|
||||||
if( directive == "for" )
|
if( directive.name == "for" )
|
||||||
ReadDirectiveFor(item);
|
ReadDirectiveFor(item);
|
||||||
else
|
else
|
||||||
if( directive == "include" )
|
if( directive.name == "include" )
|
||||||
ReadDirectiveInclude(item);
|
ReadDirectiveInclude(item);
|
||||||
else
|
else
|
||||||
if( directive == "def" )
|
if( directive.name == "def" )
|
||||||
ReadDirectiveDef(item);
|
ReadDirectiveDef(item);
|
||||||
else
|
else
|
||||||
if( directive == "#" )
|
if( directive.name == "#" )
|
||||||
ReadDirectiveComment(item);
|
ReadDirectiveComment(item);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -578,15 +602,15 @@ return false;
|
||||||
|
|
||||||
void Pattern::CreateTreeReadInclude(Item & item)
|
void Pattern::CreateTreeReadInclude(Item & item)
|
||||||
{
|
{
|
||||||
if( !allow_include || item.directives.empty() || item.directives[0].empty() || item.directives[0][0]!='\"' )
|
if( !allow_include || item.directives.empty() || !item.directives[0].is_text || item.directives[0].name.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::string file_text = ReadFile( item.directives[0].c_str()+1 );
|
std::string file_text = ReadFile( item.directives[0].name );
|
||||||
|
|
||||||
const char * itext_copy = itext;
|
const char * itext_old = itext;
|
||||||
itext = file_text.c_str();
|
itext = file_text.c_str();
|
||||||
CreateTree(item);
|
CreateTree(item);
|
||||||
itext = itext_copy;
|
itext = itext_old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -765,9 +789,8 @@ void Info::Clear()
|
||||||
{
|
{
|
||||||
// default settings indicate 'false'
|
// default settings indicate 'false'
|
||||||
result = false;
|
result = false;
|
||||||
out_string.clear();
|
is = 0;
|
||||||
|
iter = 0;
|
||||||
iter = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -776,20 +799,6 @@ Info::Info(std::ostringstream & o) : out(o)
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Info::IsTrue() const
|
|
||||||
{
|
|
||||||
if( result || !out_string.empty() )
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Info::IsFalse() const
|
|
||||||
{
|
|
||||||
return !IsTrue();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -887,7 +896,6 @@ return true;
|
||||||
|
|
||||||
void Generator::CallUserFunction(Functions::Function * function, Info & info)
|
void Generator::CallUserFunction(Functions::Function * function, Info & info)
|
||||||
{
|
{
|
||||||
// przetestowac to jeszcze !!!! (wczesniej sprawdzenie bylo w Find) !!
|
|
||||||
if( function->is_running )
|
if( function->is_running )
|
||||||
{
|
{
|
||||||
// recurrences are not allowed
|
// recurrences are not allowed
|
||||||
|
@ -903,16 +911,20 @@ void Generator::CallUserFunction(Functions::Function * function, Info & info)
|
||||||
|
|
||||||
void Generator::CallVariable(Functions::Function * function, Info & info)
|
void Generator::CallVariable(Functions::Function * function, Info & info)
|
||||||
{
|
{
|
||||||
info.out_string = function->variable;
|
if( info.is || function->is_for )
|
||||||
|
return;
|
||||||
|
|
||||||
|
info.out << function->variable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::Call(Functions::Function * function, Info & info)
|
void Generator::Call(Functions::Function * function, Info & info, const std::string * is)
|
||||||
{
|
{
|
||||||
info.Clear();
|
info.Clear();
|
||||||
info.iter = function->iter;
|
info.iter = function->iter;
|
||||||
|
info.is = is;
|
||||||
|
|
||||||
if( function->type == Functions::function )
|
if( function->type == Functions::function )
|
||||||
CallUserFunction(function, info);
|
CallUserFunction(function, info);
|
||||||
else
|
else
|
||||||
|
@ -921,13 +933,13 @@ void Generator::Call(Functions::Function * function, Info & info)
|
||||||
|
|
||||||
|
|
||||||
// return: true if a function or variable was found and called
|
// return: true if a function or variable was found and called
|
||||||
bool Generator::Call(const std::string & name, Info & info, Functions::Function ** pfun)
|
bool Generator::Call(const std::string & name, Info & info, Functions::Function ** pfun, const std::string * is)
|
||||||
{
|
{
|
||||||
Functions::Function * function;
|
Functions::Function * function;
|
||||||
|
|
||||||
if( Find(name, &function) )
|
if( Find(name, &function) )
|
||||||
{
|
{
|
||||||
Call(function, info);
|
Call(function, info, is);
|
||||||
|
|
||||||
if( pfun )
|
if( pfun )
|
||||||
*pfun = function;
|
*pfun = function;
|
||||||
|
@ -976,10 +988,7 @@ void Generator::MakeTextNormal(Pattern::Item & item)
|
||||||
if( item.directives.size() != 1 )
|
if( item.directives.size() != 1 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Call(item.directives[0], info1);
|
Call(item.directives[0].name, info1);
|
||||||
|
|
||||||
if( !info1.out_string.empty() )
|
|
||||||
output_stream << info1.out_string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1001,16 +1010,16 @@ void Generator::MakeTextIf_go(Pattern::Item & item, bool result)
|
||||||
|
|
||||||
void Generator::MakeTextIfany(Pattern::Item & item)
|
void Generator::MakeTextIfany(Pattern::Item & item)
|
||||||
{
|
{
|
||||||
std::vector<std::string>::iterator d = item.directives.begin();
|
std::vector<Pattern::Item::Directive>::iterator d = item.directives.begin();
|
||||||
unsigned how_many_true = 0;
|
unsigned how_many_true = 0;
|
||||||
|
|
||||||
for( ; d != item.directives.end() ; ++d )
|
for( ; d != item.directives.end() ; ++d )
|
||||||
{
|
{
|
||||||
if( !Call(*d, info1) )
|
if( !Call(d->name, info1) )
|
||||||
// maybe it should only be treated as a false? (when there is no such a function/variable)
|
// maybe it should only be treated as a false? (when there is no such a function/variable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( info1.IsTrue() )
|
if( info1.result )
|
||||||
++how_many_true;
|
++how_many_true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,12 +1029,12 @@ void Generator::MakeTextIfany(Pattern::Item & item)
|
||||||
|
|
||||||
void Generator::MakeTextIfno(Pattern::Item & item)
|
void Generator::MakeTextIfno(Pattern::Item & item)
|
||||||
{
|
{
|
||||||
std::vector<std::string>::iterator d = item.directives.begin();
|
std::vector<Pattern::Item::Directive>::iterator d = item.directives.begin();
|
||||||
unsigned how_many_true = 0;
|
unsigned how_many_true = 0;
|
||||||
|
|
||||||
for( ; d != item.directives.end() ; ++d )
|
for( ; d != item.directives.end() ; ++d )
|
||||||
{
|
{
|
||||||
if( Call(*d, info1) && info1.IsTrue() )
|
if( Call(d->name, info1) && info1.result )
|
||||||
{
|
{
|
||||||
// there is no sense to go through all functions
|
// there is no sense to go through all functions
|
||||||
++how_many_true;
|
++how_many_true;
|
||||||
|
@ -1040,12 +1049,12 @@ void Generator::MakeTextIfno(Pattern::Item & item)
|
||||||
|
|
||||||
void Generator::MakeTextIfone(Pattern::Item & item)
|
void Generator::MakeTextIfone(Pattern::Item & item)
|
||||||
{
|
{
|
||||||
std::vector<std::string>::iterator d = item.directives.begin();
|
std::vector<Pattern::Item::Directive>::iterator d = item.directives.begin();
|
||||||
int how_many_true = 0;
|
int how_many_true = 0;
|
||||||
|
|
||||||
for( ; d != item.directives.end() ; ++d )
|
for( ; d != item.directives.end() ; ++d )
|
||||||
{
|
{
|
||||||
if( Call(*d, info1) && info1.IsTrue() )
|
if( Call(d->name, info1) && info1.result )
|
||||||
{
|
{
|
||||||
// there is no sense to go through all functions
|
// there is no sense to go through all functions
|
||||||
++how_many_true;
|
++how_many_true;
|
||||||
|
@ -1057,30 +1066,97 @@ void Generator::MakeTextIfone(Pattern::Item & item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Generator::MakeTextIsFunText(const std::string & fun_name, const std::string & text, bool & res)
|
||||||
|
{
|
||||||
|
Functions::Function * function;
|
||||||
|
|
||||||
|
if( !Find(fun_name, &function) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
if( function->type == Functions::function )
|
||||||
|
{
|
||||||
|
Call(function, info1, &text);
|
||||||
|
res = info1.result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this is a variable
|
||||||
|
res = (function->variable == text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Generator::MakeTextIsFunFun(const std::string & fun_name1, const std::string & fun_name2, bool & res)
|
||||||
|
{
|
||||||
|
Functions::Function * function1, * function2;
|
||||||
|
|
||||||
|
if( !Find(fun_name1, &function1) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !Find(fun_name2, &function2) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
if( function1->type == Functions::function && function2->type == Functions::function )
|
||||||
|
{
|
||||||
|
Call(function1, info1);
|
||||||
|
Call(function2, info2);
|
||||||
|
res = (info1.result == info2.result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( function1->type == Functions::function )
|
||||||
|
{
|
||||||
|
Call(function1, info1, &fun_name2); // only the former is a function
|
||||||
|
res = info1.result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( function2->type == Functions::function )
|
||||||
|
{
|
||||||
|
Call(function2, info2, &fun_name1); // only the latter is a function
|
||||||
|
res = info2.result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res = (function1->variable == function2->variable); // both are variables
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextIs(Pattern::Item & item)
|
void Generator::MakeTextIs(Pattern::Item & item)
|
||||||
{
|
{
|
||||||
if( item.directives.size() != 2 )
|
if( item.directives.size() != 2 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( !Call(item.directives[0], info1) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if( !item.directives[1].empty() && item.directives[1][0]=='\"' )
|
if( item.directives[0].is_text && item.directives[1].is_text )
|
||||||
{
|
{
|
||||||
// second directive is a string
|
// both directives are text
|
||||||
if( std::strcmp(info1.out_string.c_str(), item.directives[1].c_str()+1) == 0 )
|
result = (item.directives[0].name == item.directives[1].name);
|
||||||
result = true;
|
}
|
||||||
|
else
|
||||||
|
if( item.directives[0].is_text )
|
||||||
|
{
|
||||||
|
// first directive is text, second not
|
||||||
|
if( !MakeTextIsFunText(item.directives[1].name, item.directives[0].name, result) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( item.directives[1].is_text )
|
||||||
|
{
|
||||||
|
// second directive is text, first not
|
||||||
|
if( !MakeTextIsFunText(item.directives[0].name, item.directives[1].name, result) )
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( Call(item.directives[1], info2) )
|
// both directive are not text
|
||||||
{
|
MakeTextIsFunFun(item.directives[0].name, item.directives[1].name, result);
|
||||||
if( info1.result==info2.result && info1.out_string==info2.out_string )
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeTextIf_go(item, result);
|
MakeTextIf_go(item, result);
|
||||||
|
@ -1092,7 +1168,7 @@ bool Generator::MakeTextIfindexnumber(Pattern::Item & item, Functions::Function
|
||||||
if( item.directives.size() != 2 )
|
if( item.directives.size() != 2 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char * number_text = item.directives[1].c_str();
|
const char * number_text = item.directives[1].name.c_str();
|
||||||
char * last_char;
|
char * last_char;
|
||||||
|
|
||||||
int number = (int)strtol(number_text, &last_char, 10);
|
int number = (int)strtol(number_text, &last_char, 10);
|
||||||
|
@ -1125,25 +1201,25 @@ void Generator::MakeTextIfindex(Pattern::Item & item)
|
||||||
|
|
||||||
Functions::Function * function;
|
Functions::Function * function;
|
||||||
|
|
||||||
if( !Find(item.directives[0], &function) )
|
if( !Find(item.directives[0].name, &function) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
|
||||||
if( item.directives[1] == "odd" )
|
if( item.directives[1].name == "odd" )
|
||||||
{
|
{
|
||||||
if( (function->iter & 1) == 1 )
|
if( (function->iter & 1) == 1 )
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( item.directives[1] == "even" )
|
if( item.directives[1].name == "even" )
|
||||||
{
|
{
|
||||||
if( (function->iter & 1) == 0 )
|
if( (function->iter & 1) == 0 )
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( item.directives[1] == "first" )
|
if( item.directives[1].name == "first" )
|
||||||
{
|
{
|
||||||
if( function->iter == 0 )
|
if( function->iter == 0 )
|
||||||
result = true;
|
result = true;
|
||||||
|
@ -1168,12 +1244,12 @@ void Generator::MakeTextFor(Pattern::Item & item)
|
||||||
|
|
||||||
Functions::Function * function;
|
Functions::Function * function;
|
||||||
|
|
||||||
if( !Find(item.directives[0], &function) )
|
if( !Find(item.directives[0].name, &function) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( function->is_for )
|
if( function->is_for )
|
||||||
{
|
{
|
||||||
CreateMsg(output_stream, item.directives[0].c_str(), "this function is already used in a [for] statement");
|
CreateMsg(output_stream, item.directives[0].name.c_str(), "this function is already used in a [for] statement");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1181,13 +1257,13 @@ void Generator::MakeTextFor(Pattern::Item & item)
|
||||||
{
|
{
|
||||||
if( function->iter >= max_loop )
|
if( function->iter >= max_loop )
|
||||||
{
|
{
|
||||||
CreateMsg(output_stream, item.directives[0].c_str(), "function exceeded a limit for a [for] statement");
|
CreateMsg(output_stream, item.directives[0].name.c_str(), "function exceeded a limit for a [for] statement");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Call(function, info1);
|
Call(function, info1);
|
||||||
|
|
||||||
if( info1.IsFalse() )
|
if( !info1.result )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( item.item_table.size() > 0 )
|
if( item.item_table.size() > 0 )
|
||||||
|
@ -1205,21 +1281,20 @@ void Generator::MakeTextDefine(Pattern::Item & item)
|
||||||
if( item.directives.size() != 2 )
|
if( item.directives.size() != 2 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( !item.directives[1].empty() && item.directives[1][0]=='\"' )
|
if( item.directives[1].is_text )
|
||||||
{
|
{
|
||||||
// second directive is a string
|
functions.Insert(item.directives[0].name, item.directives[1].name);
|
||||||
functions.Insert(item.directives[0], item.directives[1].c_str() + 1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Functions::Function * function;
|
Functions::Function * function;
|
||||||
|
|
||||||
if( Find(item.directives[1], &function) )
|
if( Find(item.directives[1].name, &function) )
|
||||||
{
|
{
|
||||||
if( function->type == Functions::function )
|
if( function->type == Functions::function )
|
||||||
functions.Insert(item.directives[0], function->user_function);
|
functions.Insert(item.directives[0].name, function->user_function);
|
||||||
else
|
else
|
||||||
functions.Insert(item.directives[0], function->variable);
|
functions.Insert(item.directives[0].name, function->variable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
src/ezc.h
37
src/ezc.h
|
@ -35,11 +35,6 @@
|
||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* version 0.9.2
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef headerfileezc
|
#ifndef headerfileezc
|
||||||
#define headerfileezc
|
#define headerfileezc
|
||||||
|
@ -87,13 +82,17 @@ public:
|
||||||
item_include, item_is, item_ifone, item_comment, item_def
|
item_include, item_is, item_ifone, item_comment, item_def
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Directive
|
||||||
|
{
|
||||||
|
bool is_text; // if true that means a directive in quotes "static text"
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ItemType type;
|
ItemType type;
|
||||||
std::string text;
|
std::string text;
|
||||||
std::vector<Item*> item_table;
|
std::vector<Item*> item_table;
|
||||||
std::vector<std::string> directives;
|
std::vector<Directive> directives;
|
||||||
|
|
||||||
Item();
|
Item();
|
||||||
Item(const Item & i);
|
Item(const Item & i);
|
||||||
|
@ -128,6 +127,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
bool CheckFileName(const char * name);
|
bool CheckFileName(const char * name);
|
||||||
|
std::string ReadFile(const std::string & name);
|
||||||
std::string ReadFile(const char * name);
|
std::string ReadFile(const char * name);
|
||||||
|
|
||||||
int ReadCharInText();
|
int ReadCharInText();
|
||||||
|
@ -135,9 +135,9 @@ private:
|
||||||
void SkipWhiteCharacters();
|
void SkipWhiteCharacters();
|
||||||
void CheckWhiteAndDelete(std::string & s);
|
void CheckWhiteAndDelete(std::string & s);
|
||||||
|
|
||||||
std::string ReadDirective();
|
Item::Directive ReadDirective();
|
||||||
std::string ReadString(bool skip_first_quote = false);
|
Item::Directive ReadString();
|
||||||
std::string ReadDirectiveOrString();
|
Item::Directive ReadDirectiveOrString();
|
||||||
|
|
||||||
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
||||||
|
|
||||||
|
@ -172,8 +172,12 @@ struct Info
|
||||||
{
|
{
|
||||||
// this variables you can set in your function
|
// this variables you can set in your function
|
||||||
std::ostringstream & out;
|
std::ostringstream & out;
|
||||||
std::string out_string;
|
//std::string out_string;
|
||||||
bool result;
|
bool result;
|
||||||
|
|
||||||
|
// in a [is function "text"] statement this is the pointer to "text" object
|
||||||
|
// otherwise this is null pointer
|
||||||
|
const std::string * is;
|
||||||
|
|
||||||
// this is set by Generator
|
// this is set by Generator
|
||||||
// normally is 0
|
// normally is 0
|
||||||
|
@ -183,15 +187,12 @@ struct Info
|
||||||
|
|
||||||
Info(std::ostringstream & o);
|
Info(std::ostringstream & o);
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
bool IsTrue() const;
|
|
||||||
bool IsFalse() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// functions or variables
|
||||||
class Functions
|
class Functions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -252,8 +253,8 @@ private:
|
||||||
bool Find(const std::string & key, Functions::Function ** function);
|
bool Find(const std::string & key, Functions::Function ** function);
|
||||||
|
|
||||||
|
|
||||||
bool Call(const std::string & name, Info & info, Functions::Function ** pfun = 0);
|
void Call(Functions::Function * function, Info & info, const std::string * is = 0);
|
||||||
void Call(Functions::Function * function, Info & info);
|
bool Call(const std::string & name, Info & info, Functions::Function ** pfun = 0, const std::string * is = 0);
|
||||||
|
|
||||||
void CallUserFunction(Functions::Function * function, Info & info);
|
void CallUserFunction(Functions::Function * function, Info & info);
|
||||||
void CallVariable(Functions::Function * function, Info & info);
|
void CallVariable(Functions::Function * function, Info & info);
|
||||||
|
@ -267,6 +268,8 @@ private:
|
||||||
void MakeTextFor(Pattern::Item & item);
|
void MakeTextFor(Pattern::Item & item);
|
||||||
void MakeTextContainer(Pattern::Item & item);
|
void MakeTextContainer(Pattern::Item & item);
|
||||||
void MakeTextNormal(Pattern::Item & item);
|
void MakeTextNormal(Pattern::Item & item);
|
||||||
|
bool MakeTextIsFunText(const std::string & fun_name, const std::string & text, bool & res);
|
||||||
|
bool MakeTextIsFunFun(const std::string & fun_name1, const std::string & fun_name2, bool & res);
|
||||||
void MakeTextIs(Pattern::Item & item);
|
void MakeTextIs(Pattern::Item & item);
|
||||||
void MakeTextDefine(Pattern::Item & item);
|
void MakeTextDefine(Pattern::Item & item);
|
||||||
void MakeText(Pattern::Item & item);
|
void MakeText(Pattern::Item & item);
|
||||||
|
|
Loading…
Reference in New Issue