diff --git a/src/generator.h b/src/generator.h index fc5b61a..cecbad6 100644 --- a/src/generator.h +++ b/src/generator.h @@ -2441,7 +2441,15 @@ template void Generator::MakeTextEzc(Item & item) { if( item.function.name == L"frame" ) + { MakeEzcFrame(item); + } + else + if( item.function.name == L"clear_all_white_nodes" || item.function.name == L"trim_text_nodes" ) + { + // text nodes are already cleared/trimmed by PatternParser + MakeTextContainer(item); + } // in the future we can use more builtin functions } diff --git a/src/patternparser.cpp b/src/patternparser.cpp index d82b623..7402133 100644 --- a/src/patternparser.cpp +++ b/src/patternparser.cpp @@ -136,6 +136,30 @@ void PatternParser::SetLogger(pt::Log * log) } +void PatternParser::InitializeEnvTab() +{ + env_tab.clear(); + + Env env; + env.clear_all_white_nodes = delete_white_text_items; + env_tab.push_back(env); +} + + +void PatternParser::IncreaseEnvTab() +{ + if( env_tab.empty() ) + { + InitializeEnvTab(); + } + else + { + env_tab.push_back(env_tab.back()); + } +} + + + void PatternParser::ParseFile(const std::string & file_name, Pattern & pattern) { ParseFile(file_name.c_str(), pattern); @@ -147,10 +171,13 @@ void PatternParser::ParseFile(const std::string & file_name, Pattern & pattern) void PatternParser::ParseFile(const char * file_name, Pattern & pattern) { pat = &pattern; + pat->Clear(); pt::utf8_to_wide(file_name, pat->item_root.file_name); include_level = 0; + InitializeEnvTab(); CreateTreeReadIncludeSkipAllowFlag(pat->item_root); + env_tab.clear(); } @@ -167,9 +194,13 @@ void PatternParser::ParseFile(const std::wstring & file_name, Pattern & pattern) void PatternParser::ParseFile(const wchar_t * file_name, Pattern & pattern) { pat = &pattern; + pat->Clear(); pat->item_root.file_name = file_name; include_level = 0; + InitializeEnvTab(); + CreateTreeReadIncludeSkipAllowFlag(pat->item_root); + env_tab.clear(); } @@ -194,11 +225,13 @@ void PatternParser::ParseString(const std::string & str, Pattern & pattern) void PatternParser::ParseString(const wchar_t * str, Pattern & pattern) { pat = &pattern; + pat->Clear(); itext = str; include_level = 0; + InitializeEnvTab(); - pat->item_root.Clear(); CreateTreeContainer(pat->item_root); + env_tab.clear(); } @@ -387,13 +420,7 @@ return *(itext++); bool PatternParser::IsWhite(wchar_t c) { - // 13 (\r) is from a dos file at the end of a line (\r\n) - // 160 is a non-breaking space - - if( c==' ' || c=='\t' || c==13 || c==160 || c==10 ) - return true; - -return false; + return pt::is_white(c, true, true); } @@ -425,7 +452,7 @@ size_t count = 1; void PatternParser::CheckWhiteAndDelete(std::wstring & s) { size_t i; - + if( s.empty() ) return; @@ -851,6 +878,9 @@ void PatternParser::ReadDirectiveFilter(Item & item) } + + + void PatternParser::ReadDirectiveEzc(Item & item) { item.type = Item::item_ezc; @@ -901,7 +931,53 @@ void PatternParser::ReadDirectiveReturn(Item & item) } +/* + * returns true if an Env struct has been added to env_tab + */ +bool PatternParser::CheckEnv(Item & item) +{ + if( item.function.name == L"clear_all_white_nodes" ) + { + IncreaseEnvTab(); + env_tab.back().clear_all_white_nodes = CheckEnvIsYesParameter(item); + return true; + } + if( item.function.name == L"trim_text_nodes" ) + { + IncreaseEnvTab(); + env_tab.back().trim_text_nodes = CheckEnvIsYesParameter(item); + return true; + } + + return false; +} + + +/* + * + * if no parameters are present then we assume the "yes" is by default + * + */ +bool PatternParser::CheckEnvIsYesParameter(Item & item) +{ + if( item.function.parameters.size() > 0 && !item.function.parameters[0]->is_function ) + { + std::wstring & name = item.function.parameters[0]->name; + + if( name == L"yes" || name == L"true" ) + { + return true; + } + else + if( name == L"no" || name == L"false" ) + { + return false; + } + } + + return true; +} void PatternParser::CreateTreeReadItemDirective(Item & item) @@ -947,8 +1023,20 @@ int c; while( (c = ReadCharInText()) != -1 ) item.text += static_cast(c); - if( delete_white_text_items ) - CheckWhiteAndDelete(item.text); + if( !env_tab.empty() ) + { + Env & env = env_tab.back(); + + if( env.clear_all_white_nodes ) + { + CheckWhiteAndDelete(item.text); + } + + if( env.trim_text_nodes ) + { + pt::trim_white(item.text, true, true); + } + } item.type = Item::item_text; } @@ -1199,7 +1287,7 @@ void PatternParser::CreateTreeReadBlock(Item & item) -void PatternParser::CreateTreeReadFor(Item & item) +void PatternParser::CreateTreeReadOneChild(Item & item) { Item * pitem = item.AddItem(); @@ -1228,22 +1316,29 @@ bool PatternParser::CreateTree(Item & item) } while( item.type == Item::item_comment || item.type == Item::item_block ); + bool reduce_env_tab = false; + + if(item.type == Item::item_ezc) + reduce_env_tab = CheckEnv(item); + // such container can be read in program mode if( item.type == Item::item_container ) CreateTreeContainer(item); if( item.type == Item::item_if ) - CreateTreeReadIf(item); + CreateTreeReadIf(item); // reads one child or two if [else] statement is present - // CHECK ME is it correct to check item_filter and item_ezc here and call CreateTreeReadFor? if( item.type == Item::item_for || item.type == Item::item_filter || item.type == Item::item_ezc ) - CreateTreeReadFor(item); + CreateTreeReadOneChild(item); if( item.type == Item::item_include ) CreateTreeReadInclude(item); + if( reduce_env_tab && !env_tab.empty() ) + env_tab.resize(env_tab.size() - 1); + return true; } diff --git a/src/patternparser.h b/src/patternparser.h index bab52f3..421d1ad 100644 --- a/src/patternparser.h +++ b/src/patternparser.h @@ -85,6 +85,21 @@ public: private: + struct Env + { + bool clear_all_white_nodes; + bool trim_text_nodes; + + Env() + { + clear_all_white_nodes = false; + trim_text_nodes = false; + } + + }; + + std::vector env_tab; + // the output object Pattern * pat; @@ -130,6 +145,8 @@ private: pt::Log * log; + void InitializeEnvTab(); + void IncreaseEnvTab(); void ReadFile(const std::wstring & name, std::wstring & result); void ReadFile(const wchar_t * name, std::wstring & result); @@ -175,6 +192,9 @@ private: void ReadDirectiveReturn(Item & item); void ReadNormalStatement(Item & item); + bool CheckEnv(Item & item); + bool CheckEnvIsYesParameter(Item & item); + void CreateTreeReadDirectiveExpression(Item & item, bool is_statement); bool CreateTreeCheckProgramDirective(Item & item); bool CreateTreeReadExpression(Item & item); @@ -185,7 +205,7 @@ private: bool CreateTreeReadItem(Item & item); void CreateTreeReadIf(Item & item); void CreateTreeReadBlock(Item & item); - void CreateTreeReadFor(Item & item); + void CreateTreeReadOneChild(Item & item); bool CreateTree(Item & item); void CreateTreeContainer(Item & item); void CreateTreeReadInclude(Item & item);