diff --git a/src/cache.cpp b/src/cache.cpp index 32d4300..c539588 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014, Tomasz Sowa + * Copyright (c) 2014-2015, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,8 +64,7 @@ void Cache(Blocks & blocks, Item::Function & function) void Cache(Blocks & blocks, Item & item) { - for(size_t f=0; f < item.functions.size() ; ++f) - Cache(blocks, item.functions[f]); + Cache(blocks, item.function); for(size_t i=0; i < item.item_tab.size() ; ++i) Cache(blocks, *item.item_tab[i]); diff --git a/src/cache.h b/src/cache.h index 6a9aad4..36e0b4a 100644 --- a/src/cache.h +++ b/src/cache.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014, Tomasz Sowa + * Copyright (c) 2014-2015, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -71,8 +71,7 @@ void Cache(Functions & fun, Item::Function & function) template void Cache(Functions & fun, Item & item) { - for(size_t f=0; f < item.functions.size() ; ++f) - Cache(fun, item.functions[f]); + Cache(fun, item.function); for(size_t i=0; i < item.item_tab.size() ; ++i) Cache(fun, *item.item_tab[i]); diff --git a/src/generator.h b/src/generator.h index 04d0791..b4c834e 100644 --- a/src/generator.h +++ b/src/generator.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2014, Tomasz Sowa + * Copyright (c) 2007-2015, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -130,7 +130,6 @@ private: typedef std::map Vars; Vars vars; - Var temp_var; struct BlockStack { @@ -238,6 +237,8 @@ private: void ClearStream(StreamType & str); void RemoveStackFunData(Stack & sitem); + bool ConvertToBool(const std::wstring & str); + template CharType ToLower(CharType c); @@ -297,11 +298,6 @@ private: void MakeTextIf_go(Item & item, bool result); void MakeTextIf(Item & item); - void MakeTextIfno(Item & item); - void MakeTextIfany(Item & item); - void MakeTextIfone(Item & item); - void MakeTextIfanyno(Item & item); - void MakeTextIfoneno(Item & item); void MakeTextFor(Item & item); void MakeItemText(Item & item); void MakeTextContainer(Item & item); @@ -619,6 +615,15 @@ return c; } +template +bool Generator::ConvertToBool(const std::wstring & str) +{ + if( str == L"true" ) + return true; + +return false; +} + template void Generator::SetMax(size_t max_items_, size_t max_for_items_) @@ -715,7 +720,6 @@ void Generator::Generate() WriteTmpStreamToStreams(); vars.clear(); - temp_var.str.clear(); is_generator_working = false; } catch(...) @@ -894,7 +898,7 @@ void Generator::CallFunction(typename Functions::UserFun info.is_normal = is_generating_normal; info.is_filter = is_generating_filter; info.iter = info.stack.iter; - info.stack_tab = stack_tab.data(); + info.stack_tab = &stack_tab[0];//stack_tab.data();///////////////////////////////////////////////////////// info.stack_index = stack_index-1; (*function)(info); @@ -954,7 +958,7 @@ bool Generator::CallBlock(Item & item_block, #endif out_stream.write(str.c_str(), str.size()); - // last_res is set by [return ...] statement + // last_res is set by [return ...] statement or other last evaluated function ClearStream(*output_stream); output_stream = old_stream; @@ -964,7 +968,7 @@ return true; } -// return: true if a function or variable was found and called +// return: true if a function, variable or block was found and called template bool Generator::Call(Item::Function & item_fun, StreamType & out_stream, @@ -988,7 +992,7 @@ std::vector parameters; { Item::Function & fun_child = *item_fun.parameters[i]; - if( !fun_child.name.empty() ) + if( fun_child.is_function ) { StreamType local_temp_stream; Call(fun_child, local_temp_stream, true, empty_stream); @@ -1003,8 +1007,8 @@ std::vector parameters; } else { - parameters[i].str = fun_child.par; - parameters[i].res = !fun_child.par.empty(); + parameters[i].str = fun_child.name; + parameters[i].res = ConvertToBool(fun_child.name); } } @@ -1319,18 +1323,15 @@ void Generator::MakeTextContainer(Item & item) template void Generator::MakeTextNormal(Item & item) { - if( item.functions.size() != 1 ) - return; - is_generating_normal = true; if( output_stream ) { - Call(item.functions[0], *output_stream, false, empty_stream); + Call(item.function, *output_stream, false, empty_stream); } else { - Call(item.functions[0], stream_temp1, false, empty_stream); + Call(item.function, stream_temp1, false, empty_stream); ClearStream(stream_temp1); } } @@ -1358,137 +1359,27 @@ void Generator::MakeTextIf_go(Item & item, bool result) template void Generator::MakeTextIf(Item & item) { - if( item.functions.size() != 1 ) - return; - is_generating_if = true; - if( !Call(item.functions[0]) ) + if( !Call(item.function) ) return; MakeTextIf_go(item, last_res); } -template -void Generator::MakeTextIfno(Item & item) -{ - if( item.functions.size() != 1 ) - return; - - is_generating_if = true; - - if( !Call(item.functions[0]) ) - return; - - MakeTextIf_go(item, !last_res); -} - - -template -void Generator::MakeTextIfany(Item & item) -{ - std::vector::iterator d = item.functions.begin(); - unsigned how_many_true = 0; - - is_generating_if = true; - - for( ; d != item.functions.end() ; ++d ) - { - if( !Call(*d) ) - return; - - if( last_res ) - ++how_many_true; - } - - MakeTextIf_go(item, how_many_true == item.functions.size()); -} - - -template -void Generator::MakeTextIfone(Item & item) -{ - std::vector::iterator d = item.functions.begin(); - unsigned how_many_true = 0; - - is_generating_if = true; - - for( ; d != item.functions.end() ; ++d ) - { - if( Call(*d) ) - { - if( last_res ) - { - ++how_many_true; - break; // there is no sense to go through all functions - } - } - } - - MakeTextIf_go(item, how_many_true > 0); -} - - -template -void Generator::MakeTextIfanyno(Item & item) -{ - std::vector::iterator d = item.functions.begin(); - unsigned how_many_true = 0; - - is_generating_if = true; - - for( ; d != item.functions.end() ; ++d ) - { - if( !Call(*d) ) - return; - - if( last_res ) - ++how_many_true; - } - - MakeTextIf_go(item, how_many_true == 0); -} - - -template -void Generator::MakeTextIfoneno(Item & item) -{ - std::vector::iterator d = item.functions.begin(); - unsigned how_many_false = 0; - - is_generating_if = true; - - for( ; d != item.functions.end() ; ++d ) - { - if( Call(*d) ) - { - if( !last_res ) - { - ++how_many_false; - break; - } - } - } - - MakeTextIf_go(item, how_many_false > 0); -} - template void Generator::MakeTextFor(Item & item) { - if( item.functions.size() != 1 ) - return; - stack_tab[stack_index-1].is_for = true; for( ; !break_generating ; stack_tab[stack_index-1].iter += 1 ) { if( stack_tab[stack_index-1].iter >= max_for_items ) { - CreateMsg(item.functions[0].name.c_str(), + CreateMsg(item.function.name.c_str(), L"function exceeded a limit for a [for] statement"); break; } @@ -1496,7 +1387,7 @@ void Generator::MakeTextFor(Item & item) // is_generating_for will be changed by next call to MakeText() // so we should set it in each iterations is_generating_for = true; - Call(item.functions[0], stream_temp1, true, empty_stream); + Call(item.function, stream_temp1, true, empty_stream); if( !last_res ) break; @@ -1511,53 +1402,40 @@ void Generator::MakeTextFor(Item & item) template void Generator::MakeTextDefine(Item & item) { -Item::Function * pfun = 0; - if( !can_use_vars ) { CreateMsg(L"[def] statement not available"); return; } - - if( item.functions.size() == 1 && - item.functions[0].parameters.size() == 1 ) - { - if( item.functions[0].parameters[0]->name.empty() ) - { - // it is [def name "string"] - temp_var.str = item.functions[0].parameters[0]->par; - temp_var.res = !temp_var.str.empty(); - vars[item.functions[0].name] = temp_var; - } - else - { - // it is [def name [function "funpar"]] - pfun = item.functions[0].parameters[0]; - } - } - - if( item.functions.size() == 2 ) - { - // is is [def name function "funpar"] - pfun = &item.functions[1]; - } - - if( pfun ) - { - if( Call(*pfun, stream_temp_define, true, empty_stream) ) - { - #ifdef EZC_HAS_SPECIAL_STREAM - temp_var.str = stream_temp_define.Str(); - #else - temp_var.str = stream_temp_define.str(); - #endif - temp_var.res = last_res; - vars[item.functions[0].name] = temp_var; + Var & var = vars[item.function.name]; + var.str.clear(); + var.res = false; + + for(size_t i=0 ; i < item.function.parameters.size() ; ++i) + { + if( !item.function.parameters[i]->is_function ) + { + var.str += item.function.parameters[i]->name; + var.res = ConvertToBool(item.function.parameters[i]->name); } else { - CreateMsg(L"[def] unknown function/block/variable", pfun->name); + // it is a function parameter + if( Call(*item.function.parameters[i], stream_temp_define, true, empty_stream) ) + { + #ifdef EZC_HAS_SPECIAL_STREAM + var.str += stream_temp_define.Str(); + #else + var.str += stream_temp_define.str(); + #endif + + var.res = last_res; + } + else + { + CreateMsg(L"[def] unknown function/block/variable", item.function.name); + } } } } @@ -1568,14 +1446,11 @@ Item::Function * pfun = 0; template void Generator::MakeTextFilter(Item & item) { - if( item.functions.size() != 1 ) - return; - typename Functions::UserFunction * function; Item * item_block; std::wstring * variable; - if( !Find(item.functions[0], &function, &item_block, &variable) ) + if( !Find(item.function, &function, &item_block, &variable) ) return; // IMPROVE ME @@ -1605,13 +1480,11 @@ void Generator::MakeTextFilter(Item & item) if( old_stream ) { - //Call(function, item.functions[0].params, *old_stream, false, *output_stream); - Call(item.functions[0], *old_stream, false, *output_stream); + Call(item.function, *old_stream, false, *output_stream); } else { - //Call(function, item.functions[0].params, stream_temp1, true, *output_stream); - Call(item.functions[0], stream_temp1, true, *output_stream); + Call(item.function, stream_temp1, true, *output_stream); ClearStream(stream_temp1); } @@ -1632,7 +1505,7 @@ void Generator::MakeEzcStream(Item::Function & fun) for(size_t i=0 ; ipar.c_str()); // !! CHECK ME or ->name ? + size_t index = StrToSize(fun.parameters[i]->name.c_str()); if( index < output_stream_tab.size() ) { @@ -1665,15 +1538,12 @@ void Generator::MakeEzcStream(Item::Function & fun) template void Generator::MakeTextEzc(Item & item) { - for(size_t i=0 ; i::MakeTextReturn(Item & item) BlockStack & block_stack = block_stack_tab[block_stack_index - 1]; block_stack.was_return = true; - if( !item.functions.empty() ) + if( item.has_function ) { - // output stream in [return] statement is ignored + // output stream in [return] statement is ignored (we use only the stream produced by the whole block) // this Call() sets last_res which is used later when we return to CallBlock() - Call(item.functions[0], stream_temp1, false, empty_stream); + Call(item.function, stream_temp1, false, empty_stream); ClearStream(stream_temp1); } } @@ -1751,13 +1621,8 @@ void Generator::MakeText(Item & item) if ( item.type == Item::item_text ) MakeItemText(item); else if( item.type == Item::item_container )MakeTextContainer(item); - else if( item.type == Item::item_normal ) MakeTextNormal(item); + else if( item.type == Item::item_function ) MakeTextNormal(item); else if( item.type == Item::item_if ) MakeTextIf(item); - else if( item.type == Item::item_ifno ) MakeTextIfno(item); - else if( item.type == Item::item_ifany ) MakeTextIfany(item); - else if( item.type == Item::item_ifone ) MakeTextIfone(item); - else if( item.type == Item::item_ifanyno ) MakeTextIfanyno(item); - else if( item.type == Item::item_ifoneno ) MakeTextIfoneno(item); else if( item.type == Item::item_def ) MakeTextDefine(item); else if( item.type == Item::item_for ) MakeTextFor(item); else if( item.type == Item::item_filter ) MakeTextFilter(item); diff --git a/src/item.cpp b/src/item.cpp index df8adf5..234fbe7 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2014, Tomasz Sowa + * Copyright (c) 2007-2015, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -89,7 +89,8 @@ void Item::Clear() text.clear(); file_name.clear(); - functions.clear(); + has_function = false; + function.Clear(); type = item_none; } @@ -123,8 +124,10 @@ Item::Item() -Item::Item(const Item & i) : type(i.type), text(i.text), file_name(i.file_name), functions(i.functions) +Item::Item(const Item & i) : text(i.text), file_name(i.file_name), function(i.function) { + type = i.type; + has_function = i.has_function; CopyItemTable(i); } @@ -134,8 +137,9 @@ Item & Item::operator=(const Item & i) { type = i.type; text = i.text; - file_name = i.file_name; - functions = i.functions; + file_name = i.file_name; + has_function = i.has_function; + function = i.function; ClearItems(); CopyItemTable(i); @@ -173,8 +177,7 @@ void Item::ClearCache(Item::Function & function) void Item::ClearCache() { - for(size_t f = 0; f < functions.size() ; ++f) - ClearCache(functions[f]); + ClearCache(function); for(size_t i = 0; i < item_tab.size() ; ++i) item_tab[i]->ClearCache(); diff --git a/src/item.h b/src/item.h index fee4d41..69627b5 100644 --- a/src/item.h +++ b/src/item.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2014, Tomasz Sowa + * Copyright (c) 2007-2015, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -54,8 +54,7 @@ struct Item { enum Type { - item_none, item_container, item_text, item_normal, - item_if, item_ifno, item_ifany, item_ifone, item_ifanyno, item_ifoneno, + item_none, item_container, item_text, item_function, item_if, item_for, item_else, item_end, item_err, item_include, item_comment, item_def, item_filter, item_ezc, item_block, item_return }; @@ -63,21 +62,21 @@ struct Item struct Function { - std::wstring name; // function name (can be empty, means there is no any function -- only - // a text parameter and a boolean value) - std::wstring par; // string parameter - std::vector parameters; // if name is not empty then is is a function and can have 'parameters' - // if name is empty then parameters is empty too - void * fun_cache; // only valid if name is not empty + bool is_function; // if true then we have a function parameter, if false then we have a string parameter + std::wstring name; // a function or parameter name + std::vector parameters; // if is_function is true then it is a function and can have 'parameters' + // if is_functino is empty then 'parameters' is empty too + void * fun_cache; // only valid if is_function is true Item * item_block; - int arg; // used if name is numeric (if no then is equal -1) + int arg; // used if name is numeric (if no then is equal -1) Function() { - fun_cache = 0; - item_block = 0; - arg = -1; + is_function = false; + fun_cache = 0; + item_block = 0; + arg = -1; } ~Function() @@ -92,11 +91,11 @@ struct Item Function & operator=(const Function & f) { - name = f.name; - par = f.par; - fun_cache = f.fun_cache; - item_block = f.item_block; - arg = f.arg; + is_function = f.is_function; + name = f.name; + fun_cache = f.fun_cache; + item_block = f.item_block; + arg = f.arg; for(size_t i=0 ; i item_tab; // childs - std::vector functions; + bool has_function; // the [return] statement can be without a function + Function function; Item(); Item(const Item & i); diff --git a/src/patternparser.cpp b/src/patternparser.cpp index ee8d116..c77c998 100644 --- a/src/patternparser.cpp +++ b/src/patternparser.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2014, Tomasz Sowa + * Copyright (c) 2007-2015, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -425,6 +425,22 @@ void PatternParser::SkipWhite() } +void PatternParser::SkipOneStatement() +{ +size_t count = 1; + + while( *itext != 0 && count > 0 ) + { + if( *itext == '[' ) + count += 1; + else + if( *itext == ']' ) + count -= 1; + + itext += 1; + } +} + void PatternParser::CheckWhiteAndDelete(std::wstring & s) { @@ -440,6 +456,12 @@ size_t i; } +void PatternParser::CheckFunctionIsNumber(Item::Function & function) +{ + if( IsPositiveNumber(function.name) ) + function.arg = wcstol(function.name.c_str(), 0, 10); +} + bool PatternParser::IsNameChar(wchar_t c) { @@ -522,103 +544,176 @@ bool PatternParser::ReadString(std::wstring & str) } if( *itext == '\"' ) + { ++itext; - - // if there was not a quote at the end we do not report an error - -return true; + return true; + } + else + { + return false; + } } +bool PatternParser::ReadNestedFunction(Item::Function & function) +{ + ++itext; // skipping '[' + + bool res = ReadFunction(function.AddNewParam(), true); + + if( !res ) + { + SkipOneStatement(); + return false; + } + + SkipWhite(); + + if( *itext == ']' ) + { + ++itext; + return true; + } + else + { + SkipOneStatement(); + return false; + } +} + + +bool PatternParser::ReadParamString(Item::Function & function) +{ + Item::Function & fun = function.AddNewParam(); + fun.is_function = false; + +return ReadString(fun.name); +} + + +/* + returns true if it correctly reads all parameters +*/ bool PatternParser::ReadParams(Item::Function & function) { - while( true ) +bool res; + + do { SkipWhite(); if( *itext == '[' ) { - ++itext; // skipping '[' - ReadFunction(function.AddNewParam()); - - SkipWhite(); - if( *itext == ']' ) - ++itext; + res = ReadNestedFunction(function); } else if( *itext == '\"' ) { - if( ReadString(temp_param) ) - { - Item::Function & fun = function.AddNewParam(); - fun.par = temp_param; - // fun.name is empty so it is treated as a text parameter - } - - temp_param.clear(); + res = ReadParamString(function); + } + else + if( *itext != ']' && *itext != 0 ) + { + res = ReadFunction(function.AddNewParam(), false); } else { + // *itext is equal to ']' + res = true; break; } } + while( res ); -return !function.parameters.empty(); +return res; } -bool PatternParser::ReadFunction(Item::Function & function) +/* + returns true if it correctly reads all parameters +*/ +bool PatternParser::ReadFunction(Item::Function & function, bool with_params) { SkipWhite(); function.Clear(); + function.is_function = true; if( !ReadName(function.name) ) return false; - // !! IMPROVE ME add skiping some white characters (at the beginning and at the end) - if( IsPositiveNumber(function.name) ) - function.arg = wcstol(function.name.c_str(), 0, 10); + CheckFunctionIsNumber(function); - ReadParams(function); + if( with_params ) + return ReadParams(function); return true; } - - -bool PatternParser::ReadFunctions(Item & item) +/* + returns true if it correctly reads all parameters +*/ +bool PatternParser::ReadFunction(Item & item) { - item.functions.clear(); + SkipWhite(); - while( ReadFunction(temp_function) ) - item.functions.push_back(temp_function); + if( *itext == ']' ) + { + item.has_function = false; + } + else + { + item.has_function = true; - temp_function.Clear(); + if( !ReadFunction(item.function, true) ) + { + item.function.Clear(); + item.type = Item::item_err; + return false; + } + } -return !item.functions.empty(); +return true; } - void PatternParser::CreateTreeReadItemDirectiveCheckEnding(Item & item) { SkipWhite(); - if( *itext != ']' ) + if( *itext == ']' ) + { + itext += 1; + } + else { item.type = Item::item_err; - - while( *itext!=0 && *itext!=']' ) - ++itext; + item.function.Clear(); + SkipOneStatement(); } +} - if( *itext == ']' ) - ++itext; + +// user defined directive +void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item) +{ + item.type = Item::item_function; + item.has_function = true; + + item.function.Clear(); + item.function.name = name; + item.function.is_function = true; + CheckFunctionIsNumber(item.function); + + if( !ReadParams(item.function) ) + { + item.type = Item::item_err; + item.function.Clear(); + } } @@ -626,64 +721,11 @@ void PatternParser::CreateTreeReadItemDirectiveCheckEnding(Item & item) void PatternParser::ReadDirectiveIf(Item & item) { item.type = Item::item_if; - ReadFunctions(item); - - if( item.functions.size() != 1 ) - item.type = Item::item_err; + ReadFunction(item); } -void PatternParser::ReadDirectiveIfno(Item & item) -{ - item.type = Item::item_ifno; - ReadFunctions(item); - - if( item.functions.size() != 1 ) - item.type = Item::item_err; -} - - - -void PatternParser::ReadDirectiveIfany(Item & item) -{ - item.type = Item::item_ifany; - - if( !ReadFunctions(item) ) - item.type = Item::item_err; -} - - - -void PatternParser::ReadDirectiveIfone(Item & item) -{ - item.type = Item::item_ifone; - - if( !ReadFunctions(item) ) - item.type = Item::item_err; -} - - - -void PatternParser::ReadDirectiveIfanyno(Item & item) -{ - item.type = Item::item_ifanyno; - - if( !ReadFunctions(item) ) - item.type = Item::item_err; -} - - - -void PatternParser::ReadDirectiveIfoneno(Item & item) -{ - item.type = Item::item_ifoneno; - - if( !ReadFunctions(item) ) - item.type = Item::item_err; -} - - void PatternParser::ReadDirectiveEnd(Item & item) { @@ -702,10 +744,7 @@ void PatternParser::ReadDirectiveElse(Item & item) void PatternParser::ReadDirectiveFor(Item & item) { item.type = Item::item_for; - ReadFunctions(item); - - if( item.functions.size() != 1 ) - item.type = Item::item_err; + ReadFunction(item); } @@ -733,54 +772,32 @@ void PatternParser::ReadDirectiveInclude(Item & item) void PatternParser::ReadDirectiveDef(Item & item) { - item.type = Item::item_err; - ReadFunctions(item); - - if( item.functions.size() == 1 && item.functions[0].parameters.size() == 1 ) - { - // it is [def name "value"] - // or [def name [otherfunction]] - // or [def name [otherfunction "argument"]] etc. - - item.type = Item::item_def; - } - else - if( item.functions.size() == 2 && - item.functions[0].parameters.empty() ) - { - // it is: - // [def name function] - // or [def name function "funpar1" "funpar2"] etc. - - item.type = Item::item_def; - } + item.type = Item::item_def; + ReadFunction(item); } void PatternParser::ReadDirectiveFilter(Item & item) { item.type = Item::item_filter; - ReadFunctions(item); - - if( item.functions.size() != 1 ) - item.type = Item::item_err; + ReadFunction(item); } void PatternParser::ReadDirectiveEzc(Item & item) { item.type = Item::item_ezc; - ReadFunctions(item); + ReadFunction(item); } void PatternParser::ReadDirectiveBlock(Item & item) { item.type = Item::item_block; - ReadFunctions(item); + ReadFunction(item); // only one function without arguments - if( item.functions.size() != 1 || !item.functions[0].parameters.empty() ) + if( !item.function.parameters.empty() ) item.type = Item::item_err; } @@ -788,29 +805,10 @@ void PatternParser::ReadDirectiveBlock(Item & item) void PatternParser::ReadDirectiveReturn(Item & item) { item.type = Item::item_return; - ReadFunctions(item); - - // max one function - if( item.functions.size() > 1 ) - item.type = Item::item_err; + ReadFunction(item); } -// user defined directive -void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item) -{ - temp_function.Clear(); - ReadParams(temp_function); - temp_function.name = name; - - if( IsPositiveNumber(name) ) - temp_function.arg = wcstol(name.c_str(), 0, 10); - - item.functions.clear(); - - item.functions.push_back(temp_function); - item.type = Item::item_normal; -} @@ -822,11 +820,6 @@ std::wstring name; ReadName(name); if ( name == L"if" ) ReadDirectiveIf(item); - else if( name == L"if-no" ) ReadDirectiveIfno(item); - else if( name == L"if-any" ) ReadDirectiveIfany(item); - else if( name == L"if-one" ) ReadDirectiveIfone(item); - else if( name == L"if-any-no" ) ReadDirectiveIfanyno(item); - else if( name == L"if-one-no" ) ReadDirectiveIfoneno(item); else if( name == L"end" ) ReadDirectiveEnd(item); else if( name == L"else" ) ReadDirectiveElse(item); else if( name == L"for" ) ReadDirectiveFor(item); @@ -837,8 +830,7 @@ std::wstring name; else if( name == L"block" ) ReadDirectiveBlock(item); else if( name == L"return" ) ReadDirectiveReturn(item); else if( name == L"#" ) ReadDirectiveComment(item); - else - ReadDirectiveNormal(name, item); + else if( !name.empty() ) ReadDirectiveNormal(name, item); CreateTreeReadItemDirectiveCheckEnding(item); } @@ -950,8 +942,9 @@ Item item_block; if( item_block.LastItemType() == Item::item_end ) item_block.DeleteLastItem(); - if( pblocks && item.functions.size()==1 ) - pblocks->Insert(item.functions[0].name, item_block); + //if( pblocks && item.functions.size()==1 ) + if( pblocks ) + pblocks->Insert(item.function.name, item_block); } @@ -993,13 +986,8 @@ void PatternParser::CreateTree(Item & item) if( pitem->type == Item::item_end || pitem->type == Item::item_else ) return; - if( pitem->type == Item::item_if || - pitem->type == Item::item_ifno || - pitem->type == Item::item_ifany || - pitem->type == Item::item_ifone || - pitem->type == Item::item_ifanyno || - pitem->type == Item::item_ifoneno ) - CreateTreeReadIf(*pitem); + if( pitem->type == Item::item_if ) + CreateTreeReadIf(*pitem); if( pitem->type == Item::item_for || pitem->type == Item::item_filter ) diff --git a/src/patternparser.h b/src/patternparser.h index 441031a..901831c 100644 --- a/src/patternparser.h +++ b/src/patternparser.h @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2014, Tomasz Sowa + * Copyright (c) 2007-2015, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -130,9 +130,6 @@ private: // temporary object for a file name std::string afile_name; - // temporary object for a EZC function's parameter - std::wstring temp_param; - // temporary object for a EZC function Item::Function temp_function; @@ -150,7 +147,9 @@ private: int ReadCharInText(); bool IsWhite(wchar_t c); void SkipWhite(); + void SkipOneStatement(); void CheckWhiteAndDelete(std::wstring & s); + void CheckFunctionIsNumber(Item::Function & function); bool IsNameChar(wchar_t c); bool IsDigit(wchar_t c); @@ -158,16 +157,13 @@ private: bool ReadName(std::wstring & name); bool ReadString(std::wstring & str); + bool ReadNestedFunction(Item::Function & function); + bool ReadParamString(Item::Function & function); bool ReadParams(Item::Function & function); - bool ReadFunction(Item::Function & function); - bool ReadFunctions(Item & item); + bool ReadFunction(Item::Function & function, bool with_params); + bool ReadFunction(Item & item); void ReadDirectiveIf(Item & item); - void ReadDirectiveIfno(Item & item); - void ReadDirectiveIfany(Item & item); - void ReadDirectiveIfone(Item & item); - void ReadDirectiveIfanyno(Item & item); - void ReadDirectiveIfoneno(Item & item); void ReadDirectiveEnd(Item & item); void ReadDirectiveElse(Item & item); void ReadDirectiveFor(Item & item);