diff --git a/src/blocks.cpp b/src/blocks.cpp index 544b3ae..4e4b8a5 100644 --- a/src/blocks.cpp +++ b/src/blocks.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2014, Tomasz Sowa + * Copyright (c) 2014-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -90,10 +90,12 @@ void Blocks::ClearCache() void Blocks::CacheBlocks(Blocks & blocks) { + /* BlocksTable::iterator i = blocks_tab.begin(); for( ; i != blocks_tab.end() ; ++i) Cache(blocks, i->second); + */ } diff --git a/src/cache.cpp b/src/cache.cpp index a6f1d69..0e1ed71 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -43,7 +43,7 @@ namespace Ezc { - +/* void Cache(Blocks & blocks, Item::Function & function) { function.item_block = 0; @@ -69,7 +69,7 @@ void Cache(Blocks & blocks, Item & item) 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 b749337..bccacab 100644 --- a/src/cache.h +++ b/src/cache.h @@ -51,7 +51,7 @@ namespace Ezc class Blocks; - +/* template void Cache(Functions & fun, Item::Function & function) { @@ -114,7 +114,7 @@ void Cache(Objects & objects, Item & item) for(size_t i=0; i < item.item_tab.size() ; ++i) Cache(objects, *item.item_tab[i]); } - +*/ } // namespace Ezc diff --git a/src/env.h b/src/env.h index a04f4c2..1af271f 100644 --- a/src/env.h +++ b/src/env.h @@ -52,7 +52,7 @@ namespace Ezc -typedef std::map Vars; +//typedef std::map> Vars; @@ -130,16 +130,15 @@ struct Stack template struct Env { - // a result consists of a string and a boolean value - // output stream + // an alias to res.stream StreamType & out; // result - Var & res; + Var & res; // table of parameters // the table can be empty - std::vector & params; + std::vector> & params; // the first parameter // you can always use it even if there are not any parameters (params is empty) @@ -191,8 +190,8 @@ struct Env - Env(Var & result, - std::vector & pars, + Env(Var & result, + std::vector> & pars, const StreamType & input_stream, Stack & s, const Item & item_) : out(result.stream), res(result), params(pars), in(input_stream), stack(s), item(item_) diff --git a/src/generator.h b/src/generator.h index a31a978..93275f9 100644 --- a/src/generator.h +++ b/src/generator.h @@ -51,6 +51,7 @@ #include "models.h" #include "log/log.h" #include "utf8/utf8.h" +#include "vars.h" @@ -78,10 +79,7 @@ public: ~Generator(); void SetPattern(Pattern & pattern); - void SetBlocks(Blocks & blocks); - void SetFunctions(Functions & functions); - void SetObjects(Objects & objects); - void SetVariables(Vars & variables); // [def] and [let] + void SetVariables(Vars & variables); void SetLogger(pt::Log & logger); @@ -118,10 +116,6 @@ public: // default stack size: 300 void SetStackSize(size_t new_stack_size); - // set whether or not we can use cache for functions or blocks - // true by default - void CanUseCache(bool can_use_cache); - // set whether or not we can use variables: [def ...] statement // true by default void CanUseVars(bool can_use_variables); @@ -143,13 +137,14 @@ private: struct FindHelper { - const std::wstring * fun_name; + //const std::wstring * fun_name; - BaseObj * base_obj; - int method_index; - typename Functions::UserFunction * function; - Item * item_block; - Var * variable; + //BaseObj * base_obj; + //int method_index; + + //typename Functions::UserFunction * function; + //Item * item_block; + Var * variable; #ifdef EZC_HAS_MORM_LIBRARY morm::Wrapper * wrapper; @@ -158,12 +153,12 @@ private: FindHelper() { - fun_name = nullptr; + //fun_name = nullptr; - base_obj = nullptr; - method_index = -1; - function = nullptr; - item_block = nullptr; + //base_obj = nullptr; + //method_index = -1; + //function = nullptr; + //item_block = nullptr; variable = nullptr; #ifdef EZC_HAS_MORM_LIBRARY @@ -176,7 +171,7 @@ private: struct BlockStack { - std::vector args; + std::vector> args; StreamType * out_stream; bool was_return; }; @@ -190,13 +185,12 @@ private: StreamType * output_stream; Pattern * ppattern; - Blocks * pblocks; - Functions * pfunctions; - Objects * pobjects; + + #ifdef EZC_HAS_MORM_LIBRARY Models * pmodels; #endif - Vars * pvars; + Vars * pvars; pt::Log * plog; @@ -256,7 +250,6 @@ private: std::vector stack_tab; bool can_use_vars; - bool can_find_in_cache; bool program_mode; ExpressionParser * expression_parser; @@ -291,73 +284,66 @@ private: bool CheckBlockArgument(int arg_index, FindHelper & find_helper); - bool FindInCache(Item::Function & item_fun, FindHelper & find_helper); #ifdef EZC_HAS_MORM_LIBRARY bool FindInModels(FindHelper & find_helper); #endif - bool FindInFunctionsAndBlocks(const std::wstring & name, FindHelper & find_helper); - bool FindInVariables(const std::wstring & name, FindHelper & find_helper); - bool Find(Item::Function & item_fun, FindHelper & find_helper); - void PrepareEnvStruct(Env & info); void CallFunction(typename Functions::UserFunction & function, Env & info); void CallFunction(typename Functions::UserFunction & function, - Var & result, - std::vector & parameters, + Var & result, + std::vector> & parameters, const StreamType & in_stream); bool CallBlock(Item & item_block, - Var & result, - std::vector & parameters); + Var & result, + std::vector> & parameters); - void CallObject(BaseObj & base_obj, int method_index, Env & info); + void PrintDate(pt::Date * date, Var & result, std::vector> & parameters); + bool PrintDatePart(pt::Date * date, const std::wstring & field, Var & result, std::vector> & parameters); - void PrintDate(pt::Date * date, Var & result, std::vector & parameters); - bool PrintDatePart(pt::Date * date, const std::wstring & field, Var & result, std::vector & parameters); + bool CallDate(FindHelper & find_helper, std::vector & fields, Var & result, std::vector> & parameters); - bool CallDate(FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters); - - void PrintLastSpaceField(pt::Space * space, Var & result, std::vector & parameters); - void CallSpaceObjectForLastField(Var & result, std::vector & parameters, pt::Space * space); + void PrintLastSpaceField(pt::Space * space, Var & result, std::vector> & parameters); + void CallSpaceObjectForLastField(Var & result, std::vector> & parameters, pt::Space * space); pt::Space * CallSpaceObjectForMiddleField(const std::wstring & root_space_name, std::vector & fields, size_t field_index, pt::Space * space); - void CallSpaceTableForLastField(morm::SpaceWrapper & space_wrapper, Var & result, std::vector & parameters, + void CallSpaceTableForLastField(morm::SpaceWrapper & space_wrapper, Var & result, std::vector> & parameters, pt::Space * space, size_t model_wrapper_space_table_index); pt::Space * CallSpaceTableForMiddleField(morm::SpaceWrapper & space_wrapper, const std::wstring & root_space_name, std::vector & fields, size_t field_index, pt::Space * space, size_t model_wrapper_space_table_index); - bool CallSpace(FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters); + bool CallSpace(FindHelper & find_helper, std::vector & fields, Var & result, std::vector> & parameters); #ifdef EZC_HAS_MORM_LIBRARY - bool CallModelField(morm::Model & model, const std::wstring & field, Var & result, std::vector & parameters, const StreamType & in_stream); - bool CallModel(morm::Model & model, FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters, const StreamType & in_stream); + bool CallModelField(morm::Model & model, const std::wstring & field, Var & result, std::vector> & parameters, const StreamType & in_stream); + bool CallModel(morm::Model & model, FindHelper & find_helper, std::vector & fields, Var & result, std::vector> & parameters, const StreamType & in_stream); void FindLastModelWrapper(FindHelper & find_helper, std::vector & fields); - bool CallWrapper(FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters, const StreamType & in_stream); + bool CallWrapper(FindHelper & find_helper, std::vector & fields, Var & result, std::vector> & parameters, const StreamType & in_stream); + + bool XXXRenameMe(Var & variable, std::vector & fields, size_t & field_index, Var & result, std::vector> & parameters, const StreamType & in_stream); + #endif - void CallObject(BaseObj & base_obj, - int method_index, - Var & result, - std::vector & parameters, - const StreamType & in_stream); - - bool CallVariable(Item::Function & item_fun, - Var & variable, - Var & result, - std::vector & parameters, + bool CallVariable(std::wstring & name, + std::vector & fields, + size_t & field_index, + Var & result, + std::vector> & parameters, const StreamType & in_stream); + void NormalizeResult(Var & result); + bool Call(Item::Function & item_fun, const std::wstring * fun_name, - Var & result, + Var & result, const StreamType & in_stream); - bool Call(Item::Function & item_fun, Var & result); + bool Call(Item::Function & item_fun, Var & result); wchar_t CreateSpecialChar(wchar_t c); const wchar_t * PrintSpecialChar(const wchar_t * start, const wchar_t * end); @@ -368,13 +354,13 @@ private: void SkipWhite(const wchar_t *& str); size_t StrToSize(const wchar_t * str, const wchar_t ** str_end = 0); - bool HasParam(std::vector & parameters, const wchar_t * param1, const wchar_t * param2 = nullptr); - bool ShouldMakeSpaceDump(std::vector & parameters); - bool ShouldMakeJsonDump(std::vector & parameters); - bool IsPrettyPrint(std::vector & parameters); + bool HasParam(std::vector> & parameters, const wchar_t * param1, const wchar_t * param2 = nullptr); + bool ShouldMakeSpaceDump(std::vector> & parameters); + bool ShouldMakeJsonDump(std::vector> & parameters); + bool IsPrettyPrint(std::vector> & parameters); - void DumpSpaceIfNeeded(Var & result, std::vector & parameters, pt::Space * space); - void DumpModelIfNeeded(morm::Model & model, Var & result, std::vector & parameters); + void DumpSpaceIfNeeded(Var & result, std::vector> & parameters, pt::Space * space); + void DumpModelIfNeeded(morm::Model & model, Var & result, std::vector> & parameters); void CopyTmpStreamToOutputStreams(Item::Function & fun, StreamType & ezc_out_tmp_stream, StreamType & previous_stream); @@ -401,10 +387,10 @@ private: void MakeItemText(Item & item); void MakeTextContainer(Item & item); void MakeTextFunction(Item & item); - void MakeTextDefine(Item & item, Var & var); + void MakeTextDefine(Item & item, Var & var); void MakeTextDefine(Item & item); void MakeTextDefineIfNotSet(Item & item); - void MakeTextLet(Item & item, Var & var); + void MakeTextLet(Item & item, Var & var); void MakeTextLet(Item & item); void MakeTextLetIfNotSet(Item & item); void MakeTextFilter(Item & item); @@ -428,9 +414,6 @@ template Generator::Generator() : empty_stream() { ppattern = nullptr; - pblocks = nullptr; - pfunctions = nullptr; - pobjects = nullptr; pvars = nullptr; plog = nullptr; @@ -448,7 +431,6 @@ Generator::Generator() : stack_size = 300; block_stack_size = 64; ezc_frames_stack_size = 16; - can_find_in_cache = true; can_use_vars = true; expression_parser = nullptr; program_mode = false; @@ -468,9 +450,6 @@ Generator & Generator::operator=(const Generator & n) { ppattern = n.ppattern; - pblocks = n.pblocks; - pfunctions = n.pfunctions; - pobjects = n.pobjects; pvars = n.pvars; plog = n.plog; @@ -483,7 +462,6 @@ Generator::operator=(cons special_chars = n.special_chars; trim_white = n.trim_white; skip_new_line = n.skip_new_line; - can_find_in_cache = n.can_find_in_cache; can_use_vars = n.can_use_vars; // filter, stack and block_stack will be auto resized when calling Generate() method @@ -529,31 +507,8 @@ void Generator::SetPatter } - - template -void Generator::SetBlocks(Blocks & blocks) -{ - pblocks = &blocks; -} - - -template -void Generator::SetFunctions(Functions & functions) -{ - pfunctions = &functions; -} - - -template -void Generator::SetObjects(Objects & objects) -{ - pobjects = &objects; -} - - -template -void Generator::SetVariables(Vars & variables) +void Generator::SetVariables(Vars & variables) { pvars = &variables; } @@ -575,11 +530,6 @@ void Generator::SetModels } #endif -template -void Generator::CanUseCache(bool can_use_cache) -{ - can_find_in_cache = can_use_cache; -} template @@ -991,35 +941,6 @@ bool Generator::CheckBloc -template -bool Generator::FindInCache(Item::Function & item_fun, FindHelper & find_helper) -{ - if( can_find_in_cache ) - { - if( item_fun.base_obj ) - { - find_helper.base_obj = reinterpret_cast * >(item_fun.base_obj); - find_helper.method_index = item_fun.method_index; - return true; - } - - if( item_fun.fun_cache ) - { - find_helper.function = reinterpret_cast::UserFunction*>(item_fun.fun_cache); - return true; - } - - if( item_fun.item_block ) - { - find_helper.item_block = item_fun.item_block; - return true; - } - } - -return false; -} - - #ifdef EZC_HAS_MORM_LIBRARY @@ -1043,102 +964,6 @@ bool Generator::FindInMod #endif -template -bool Generator::FindInFunctionsAndBlocks(const std::wstring & name, FindHelper & find_helper) -{ - if( pobjects ) - { - typename Objects::Iterator i = pobjects->Find(name, find_helper.method_index); - - if( i != pobjects->End() ) - { - find_helper.base_obj = *i; - return true; - } - } - - if( pfunctions ) - { - typename Functions::Iterator i = pfunctions->Find(name); - - if( i != pfunctions->End() ) - { - find_helper.function = &i->second; - return true; - } - } - - if( pblocks ) - { - Blocks::Iterator i = pblocks->Find(name); - - if( i != pblocks->End() ) - { - find_helper.item_block = &i->second; - return true; - } - } - -return false; -} - - -template -bool Generator::FindInVariables(const std::wstring & name, FindHelper & find_helper) -{ - if( pvars ) - { - Vars::iterator i = pvars->find(name); - - if( i != pvars->end() ) - { - find_helper.variable = &(i->second); - return true; - } - } - - return false; -} - - - -/* - * fun_name can be null, it is used only with [let ...] statements - * and if not null then means: as a funcion name we are not using item_fun.name but fun_name - */ -template -bool Generator::Find(Item::Function & item_fun, FindHelper & find_helper) -{ - if( CheckBlockArgument(item_fun.arg, find_helper) ) - return true; - - #ifdef EZC_HAS_MORM_LIBRARY - if( FindInModels(find_helper) ) - return true; - - if( !item_fun.fields.empty() && !IsTestingFunctionExistence() ) - { - CreateMsg(L"unknown model", find_helper.fun_name->c_str()); - return false; - } - - #endif - - if( FindInCache(item_fun, find_helper) ) - return true; - - if( FindInFunctionsAndBlocks(*find_helper.fun_name, find_helper) ) - return true; - - if( FindInVariables(*find_helper.fun_name, find_helper) ) - return true; - - if( !IsTestingFunctionExistence() ) - CreateMsg(L"unknown function", find_helper.fun_name->c_str()); - - return false; -} - template void Generator::PrepareEnvStruct(Env & info) @@ -1163,15 +988,14 @@ void Generator::CallFunct { PrepareEnvStruct(info); (function)(info); - //last_res = info.res; } template void Generator::CallFunction(typename Functions::UserFunction & function, - Var & result, - std::vector & parameters, + Var & result, + std::vector> & parameters, const StreamType & in_stream) { if( !IsTestingFunctionExistence() ) @@ -1191,22 +1015,10 @@ void Generator::CallFunct - template -void Generator::CallObject(BaseObj & base_obj, int method_index, Env & info) +bool Generator::HasParam(std::vector> & parameters, const wchar_t * param1, const wchar_t * param2) { - PrepareEnvStruct(info); - base_obj.CallFun(method_index, info); - //last_res = info.res; -} - - - - -template -bool Generator::HasParam(std::vector & parameters, const wchar_t * param1, const wchar_t * param2) -{ - for(Var & var : parameters) + for(Var & var : parameters) { if( var.is_equal(param1) || (param2 && var.is_equal(param2)) ) { @@ -1220,21 +1032,21 @@ bool Generator::HasParam( template -bool Generator::ShouldMakeSpaceDump(std::vector & parameters) +bool Generator::ShouldMakeSpaceDump(std::vector> & parameters) { return HasParam(parameters, L"dump", L"dump_to_space"); } template -bool Generator::ShouldMakeJsonDump(std::vector & parameters) +bool Generator::ShouldMakeJsonDump(std::vector> & parameters) { return HasParam(parameters, L"dump_to_json"); } template -bool Generator::IsPrettyPrint(std::vector & parameters) +bool Generator::IsPrettyPrint(std::vector> & parameters) { return HasParam(parameters, L"pretty"); } @@ -1242,7 +1054,7 @@ bool Generator::IsPrettyP template -void Generator::DumpSpaceIfNeeded(Var & result, std::vector & parameters, pt::Space * space) +void Generator::DumpSpaceIfNeeded(Var & result, std::vector> & parameters, pt::Space * space) { bool dump_space = ShouldMakeSpaceDump(parameters); bool dump_json = ShouldMakeJsonDump(parameters); @@ -1254,13 +1066,13 @@ void Generator::DumpSpace if( dump_space ) { space->serialize_to_space_stream(result.stream, pretty); - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; } else if( dump_json ) { space->serialize_to_json_stream(result.stream, pretty); - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; } } } @@ -1268,7 +1080,7 @@ void Generator::DumpSpace template void Generator::DumpModelIfNeeded( - morm::Model & model, Var & result, std::vector & parameters) + morm::Model & model, Var & result, std::vector> & parameters) { bool dump_space = ShouldMakeSpaceDump(parameters); bool dump_json = ShouldMakeJsonDump(parameters); @@ -1290,7 +1102,7 @@ void Generator::DumpModel pt::TextStream temp_str; model.to_text(temp_str, false, false); result.stream << temp_str; // what about escaping here? why Model::to_text() don't take WTextStream? - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; //out_stream << temp_str; } } @@ -1300,7 +1112,7 @@ void Generator::DumpModel template void Generator::PrintDate( - pt::Date * date, Var & result, std::vector & parameters) + pt::Date * date, Var & result, std::vector> & parameters) { bool is_roman = HasParam(parameters, L"roman"); bool is_no_sec = HasParam(parameters, L"no_sec"); @@ -1309,13 +1121,13 @@ void Generator::PrintDate if( only_date ) { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; date->SerializeYearMonthDay(result.stream, is_roman); } else if( only_time ) { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; if( is_no_sec ) date->SerializeHourMin(result.stream); @@ -1324,7 +1136,7 @@ void Generator::PrintDate } else { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; date->Serialize(result.stream, is_roman, !is_no_sec); } } @@ -1332,7 +1144,7 @@ void Generator::PrintDate template bool Generator::PrintDatePart( - pt::Date * date, const std::wstring & field, Var & result, std::vector & parameters) + pt::Date * date, const std::wstring & field, Var & result, std::vector> & parameters) { bool is_test = IsTestingFunctionExistence(); @@ -1340,7 +1152,7 @@ bool Generator::PrintDate { if( !is_test ) { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; result.stream << date->year; } } @@ -1350,7 +1162,7 @@ bool Generator::PrintDate if( !is_test ) { bool is_roman = HasParam(parameters, L"roman"); - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; if( is_roman ) pt::Date::SerializeMonthAsRoman(result.stream, date->month); @@ -1363,7 +1175,7 @@ bool Generator::PrintDate { if( !is_test ) { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; result.stream << date->day; } } @@ -1372,7 +1184,7 @@ bool Generator::PrintDate { if( !is_test ) { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; result.stream << date->hour; } } @@ -1381,7 +1193,7 @@ bool Generator::PrintDate { if( !is_test ) { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; result.stream << date->min; } } @@ -1390,7 +1202,7 @@ bool Generator::PrintDate { if( !is_test ) { - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; result.stream << date->sec; } } @@ -1405,7 +1217,7 @@ bool Generator::PrintDate template bool Generator::CallDate( - FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters) + FindHelper & find_helper, std::vector & fields, Var & result, std::vector> & parameters) { bool found = true; bool all_fields_known = (find_helper.field_index == fields.size()); @@ -1445,7 +1257,7 @@ bool Generator::CallDate( template -void Generator::CallSpaceObjectForLastField(Var & result, std::vector & parameters, pt::Space * space) +void Generator::CallSpaceObjectForLastField(Var & result, std::vector> & parameters, pt::Space * space) { if( !IsTestingFunctionExistence() ) { @@ -1473,7 +1285,7 @@ pt::Space * Generator::Ca template void Generator::CallSpaceTableForLastField( - morm::SpaceWrapper & space_wrapper, Var & result, std::vector & parameters, + morm::SpaceWrapper & space_wrapper, Var & result, std::vector> & parameters, pt::Space * space, size_t model_wrapper_space_table_index) { pt::Space::TableType * table = space->get_table(); @@ -1538,7 +1350,7 @@ pt::Space * Generator::Ca template void Generator::PrintLastSpaceField( - pt::Space * space, Var & result, std::vector & parameters) + pt::Space * space, Var & result, std::vector> & parameters) { bool no_escape = HasParam(parameters, L"raw", L"noescape"); @@ -1548,14 +1360,14 @@ void Generator::PrintLast { //pt::WTextStream str; space->serialize_to_string(result.stream); - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; //CopyStream(str, out_stream, false); } else { // space->serialize_to_string(out_stream); space->serialize_to_string(result.stream); - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; } } @@ -1563,7 +1375,7 @@ void Generator::PrintLast template bool Generator::CallSpace( - FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters) + FindHelper & find_helper, std::vector & fields, Var & result, std::vector> & parameters) { morm::SpaceWrapper * space_wrapper = find_helper.wrapper->space_wrapper; pt::Space * space = space_wrapper->get_space(); @@ -1661,7 +1473,7 @@ bool Generator::CallSpace template bool Generator::CallModelField( - morm::Model & model, const std::wstring & field, Var & result, std::vector & parameters, const StreamType & in_stream) + morm::Model & model, const std::wstring & field, Var & result, std::vector> & parameters, const StreamType & in_stream) { /* * if 'field' is a POD type then 'str' will be used in get_raw_value() @@ -1672,24 +1484,14 @@ bool Generator::CallModel pt::WTextStream str; bool found = false; - if( parameters.empty() ) - { - Env info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); - found = model.get_raw_value(nullptr, field.c_str(), nullptr, info, str, false); - //last_res = info.res; - } - else - { - Env info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); - found = model.get_raw_value(nullptr, field.c_str(), nullptr, info, str, false); - //last_res = info.res; - } + Env info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + found = model.get_raw_value(nullptr, field.c_str(), nullptr, info, str, false); if( found && !str.empty()) { bool no_escape = HasParam(parameters, L"raw", L"noescape"); CopyStream(str, result.stream, !no_escape); - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; } return found; @@ -1699,7 +1501,7 @@ bool Generator::CallModel template bool Generator::CallModel( morm::Model & model, FindHelper & find_helper, std::vector & fields, - Var & result, std::vector & parameters, const StreamType & in_stream) + Var & result, std::vector> & parameters, const StreamType & in_stream) { bool found = true; @@ -1741,7 +1543,8 @@ bool Generator::CallModel template -void Generator::FindLastModelWrapper(FindHelper & find_helper, std::vector & fields) +void Generator::FindLastModelWrapper( + FindHelper & find_helper, std::vector & fields) { for(find_helper.field_index = 0 ; find_helper.field_index < fields.size() && find_helper.wrapper->has_model_object() ; ++find_helper.field_index) { @@ -1782,9 +1585,11 @@ void Generator::FindLastM } + template -bool Generator::CallWrapper(FindHelper & find_helper, std::vector & fields, - Var & result, std::vector & parameters, const StreamType & in_stream) +bool Generator::CallWrapper( + FindHelper & find_helper, std::vector & fields, + Var & result, std::vector> & parameters, const StreamType & in_stream) { bool found = true; //last_res = false; @@ -1854,34 +1659,10 @@ bool Generator::CallWrapp -template -void Generator::CallObject(BaseObj & base_obj, - int method_index, - Var & result, - std::vector & parameters, - const StreamType & in_stream) -{ - if( !IsTestingFunctionExistence() ) - { - if( parameters.empty() ) - { - Env info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); - CallObject(base_obj, method_index, info); - } - else - { - Env info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); - CallObject(base_obj, method_index, info); - } - } -} - - - template bool Generator::CallBlock(Item & item_block, - Var & result, - std::vector & parameters) + Var & result, + std::vector> & parameters) { if( block_stack_index >= block_stack_tab.size() ) { @@ -1904,7 +1685,7 @@ bool Generator::CallBlock MakeText(item_block); CopyStream(*output_stream, result.stream); - result.type = Var::TYPE_STREAM; + result.type = Var::TYPE_STREAM; // last_res is set by [return ...] statement or other last evaluated function // FIXME what about result now? @@ -1920,19 +1701,158 @@ return true; template -bool Generator::CallVariable( - Item::Function & item_fun, Var & variable, Var & result, std::vector & parameters, const StreamType & in_stream) +bool Generator::XXXRenameMe( + Var & variable, std::vector & fields, size_t & field_index, Var & result, std::vector> & parameters, const StreamType & in_stream) { - if( variable.type == Var::TYPE_FUNCTION ) + Var * last_var = &variable; + Var res; + + //find_helper.wrapper->has_model_object() + while( field_index < fields.size() ) { - if( variable.space_local.is_wstr() ) + std::wstring & field = fields[field_index]; + size_t old_field_index = field_index; + + if( last_var->type == Var::TYPE_FUNCTION ) { - //return Call(item_fun, variable.space_local.get_wstr()->c_str(), out_stream, false, result, in_stream); - return Call(item_fun, variable.space_local.get_wstr(), result, in_stream); + std::vector> params; + params.push_back(*last_var); + field_index += 1; + + if( !CallVariable(field, fields, field_index, res, params, in_stream) ) + return false; + } + + if( last_var->type == Var::TYPE_MODEL ) + { + /* + * if 'field' is a POD type then 'str' will be used in get_raw_value() + * if 'field' is a getter method with pt::Stream then 'str' will be used too + * if 'field' is a getter method which takes Env<> then out_stream will be used and 'str' will be empty + * + */ + bool found = false; + + Env info(res, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + found = last_var->model->get_raw_value(nullptr, field.c_str(), nullptr, info); + + if( found && res.type == Var::TYPE_VOID && !res.stream.empty() ) + { + res.type = Var::TYPE_STREAM; + } + + if( !found ) + { + CreateMsg(L"not found: ", field.c_str()); + return false; + } + } + + if( last_var->type == Var::TYPE_SPACE_WRAPPER ) + { + //CallSpace(); + } + + + last_var = &res; + + if( old_field_index == field_index ) + field_index += 1; + } + + result = res; + + return true; +} + +template +bool Generator::CallVariable( + std::wstring & name, std::vector & fields, size_t & field_index, Var & result, std::vector> & parameters, const StreamType & in_stream) +{ + + Var * variable = pvars->find(name); + Var res; + + if( !variable ) + return false; + + while( variable->type == Var::TYPE_FUNCTION || variable->type == Var::TYPE_MODEL ) + { + if( variable->type == Var::TYPE_FUNCTION ) + { + if( variable->user_function ) + { + CallFunction(variable->user_function, res, parameters, in_stream); + } + else + { + // put some log that variable.user_function is null? + return false; + } + } + else + if( variable->type == Var::TYPE_MODEL ) + { + if( variable->model ) + { + if( !XXXRenameMe(variable, fields, field_index, res, parameters, in_stream) ) + return false; + } + else + { + // put some log that model is null? + return false; + } + } + + variable = &res; + } + + + { + if( !IsTestingFunctionExistence() ) + { + result = variable; + //variable.serialize_to(out_stream); + //out_stream << variable.str; + //last_res = variable.res; + } + + return true; + } + + result = res; +} + + +/* +template +bool Generator::CallVariable( + std::vector & fields, size_t & field_index, Var & variable, Var & result, std::vector> & parameters, const StreamType & in_stream) +{ + if( variable.type == Var::TYPE_FUNCTION ) + { + if( variable.user_function ) + { + CallFunction(variable.user_function, result, parameters, in_stream); + return true; } else { - // put some log? + // put some log that variable.user_function is null? + return false; + } + } + else + if( variable.type == Var::TYPE_MODEL ) + { + if( variable.model ) + { + return XXXRenameMe(variable, fields, field_index, result, parameters, in_stream); + } + else + { + // put some log that model is null? return false; } } @@ -1949,6 +1869,19 @@ bool Generator::CallVaria return true; } } +*/ + + + + +// give me a better name +template +void Generator::NormalizeResult(Var & result) +{ + if( result.type == Var::TYPE_VOID && !result.stream.empty() ) + result.type = Var::TYPE_STREAM; +} + /* @@ -1961,11 +1894,11 @@ template bool Generator::Call( Item::Function & item_fun, const std::wstring * fun_name, - Var & result, + Var & result, const StreamType & in_stream) { FindHelper find_helper; -std::vector parameters; +std::vector> parameters; // if( clear_out_stream ) // ClearStream(out_stream); @@ -1974,13 +1907,26 @@ std::vector parameters; // if constexpr(is_autoescape_stream) // out_stream.Escape(true); - find_helper.fun_name = fun_name; + Var * var = nullptr; + const std::wstring * name = nullptr; - if( !find_helper.fun_name ) - find_helper.fun_name = &item_fun.name; + if( pvars ) + { + if( fun_name ) + name = fun_name; + else + name = &item_fun.name; + + var = pvars->find(*name); + } + + if( !var ) + { + if( !IsTestingFunctionExistence() ) + CreateMsg(name->c_str(), L"is not defined"); - if( !Find(item_fun, find_helper) ) return false; + } parameters.resize(item_fun.parameters.size()); @@ -1990,47 +1936,26 @@ std::vector parameters; if( fun_child.is_function ) { -// StreamType local_temp_stream; // what about local_temp_stream? may it should be moved to Var? -// Call(fun_child, nullptr, local_temp_stream, true, parameters[i], empty_stream); - Call(fun_child, nullptr, parameters[i], empty_stream); - - //CopyStreamToString(local_temp_stream, parameters[i].str); - //parameters[i].res = last_res; } else { -// parameters[i].str = fun_child.name; -// parameters[i].res = ConvertToBool(fun_child.name); + // currently in Patterns we can define only strings parameters[i].set(fun_child.name); } } -#ifdef EZC_HAS_MORM_LIBRARY - if( find_helper.wrapper ) - return CallWrapper(find_helper, item_fun.fields, result, parameters, in_stream); - else -#endif - if( find_helper.base_obj ) - CallObject(*find_helper.base_obj, find_helper.method_index, result, parameters, in_stream); - else - if( find_helper.function ) - CallFunction(*find_helper.function, result, parameters, in_stream); - else - if( find_helper.item_block ) - return CallBlock(*find_helper.item_block, result, parameters); - else - if( find_helper.variable ) - return CallVariable(item_fun, *find_helper.variable, result, parameters, in_stream); - - return true; + size_t field_index = 0; + bool result_status = CallVariable(item_fun.fields, field_index, *var, result, parameters, in_stream); + NormalizeResult(result); + return result_status; } // return: true if a function or variable was found and called template -bool Generator::Call(Item::Function & item_fun, Var & result) +bool Generator::Call(Item::Function & item_fun, Var & result) { //return Call(item_fun, nullptr, stream_temp1, true, result, empty_stream); return Call(item_fun, nullptr, result, empty_stream); @@ -2415,7 +2340,7 @@ void Generator::MakeTextF } else { - Var result; + Var result; Call(item.function, nullptr, result, empty_stream); if( output_stream ) @@ -2464,7 +2389,7 @@ template void Generator::MakeTextIf(Item & item) { is_generating_if = true; - Var result; + Var result; if( program_mode ) { @@ -2484,7 +2409,7 @@ template void Generator::MakeTextIfDef(Item & item) { is_generating_if_def = true; - Var result; + Var result; if( program_mode ) { @@ -2504,7 +2429,7 @@ template void Generator::MakeTextIfNotDef(Item & item) { is_generating_if_not_def = true; - Var result; + Var result; if( program_mode ) { @@ -2524,7 +2449,7 @@ template void Generator::MakeTextFor(Item & item) { stack_tab[stack_index-1].is_for = true; - Var result; + Var result; for( ; !break_generating ; stack_tab[stack_index-1].iter += 1 ) { @@ -2560,7 +2485,7 @@ void Generator::MakeTextF template -void Generator::MakeTextDefine(Item & item, Var & var) +void Generator::MakeTextDefine(Item & item, Var & var) { // var.str.clear(); // var.res = ConvertToBool(var.str); @@ -2606,20 +2531,27 @@ void Generator::MakeTextD template void Generator::MakeTextDefine(Item & item) { + return; + + /* if( !can_use_vars || !pvars ) { CreateMsg(L"[def] statement not available"); return; } - Var & var = (*pvars)[item.function.name]; + Var & var = (*pvars)[item.function.name]; MakeTextDefine(item, var); + */ } template void Generator::MakeTextDefineIfNotSet(Item & item) { + return; + + /* if( !can_use_vars || !pvars ) { CreateMsg(L"[def?] statement not available"); @@ -2630,16 +2562,17 @@ void Generator::MakeTextD if( vi == pvars->end() ) { - Var & var = (*pvars)[item.function.name]; + Var & var = (*pvars)[item.function.name]; MakeTextDefine(item, var); } + */ } template -void Generator::MakeTextLet(Item & item, Var & var) +void Generator::MakeTextLet(Item & item, Var & var) { // var.str.clear(); // var.res = ConvertToBool(var.str); @@ -2677,20 +2610,27 @@ void Generator::MakeTextL template void Generator::MakeTextLet(Item & item) { + return; + + /* if( !can_use_vars || !pvars ) { CreateMsg(L"[let] statement not available"); return; } - Var & var = (*pvars)[item.function.name]; + Var & var = (*pvars)[item.function.name]; MakeTextLet(item, var); + */ } template void Generator::MakeTextLetIfNotSet(Item & item) { + return; + + /* if( !can_use_vars || !pvars ) { CreateMsg(L"[let?] statement not available"); @@ -2701,9 +2641,10 @@ void Generator::MakeTextL if( vi == pvars->end() ) { - Var & var = (*pvars)[item.function.name]; + Var & var = (*pvars)[item.function.name]; MakeTextLet(item, var); } + */ } @@ -2717,7 +2658,7 @@ void Generator::MakeTextF return; } - Var result; + Var result; StreamType * old_stream = output_stream; output_stream = filter_tab[filter_index]; ClearStream(*output_stream); @@ -2834,7 +2775,7 @@ void Generator::MakeTextR if( item.has_function ) { - Var result; + Var result; // 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() diff --git a/src/item.cpp b/src/item.cpp index f6adfff..178bacf 100644 --- a/src/item.cpp +++ b/src/item.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2007-2018, Tomasz Sowa + * Copyright (c) 2007-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -168,10 +168,10 @@ Item::~Item() void Item::ClearCache(Item::Function & function) { - function.base_obj = 0; - function.method_index = -1; - function.fun_cache = 0; - function.item_block = 0; +// function.base_obj = 0; +// function.method_index = -1; +// function.fun_cache = 0; +// function.item_block = 0; for(size_t i=0 ; i parameters; // if is_function is true then it is a function and can have 'parameters' // if is_function is empty then 'parameters' is empty too - void * fun_cache; // only valid if is_function is true - Item * item_block; - void * base_obj; - int method_index; + //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) Function() { is_function = false; - fun_cache = 0; - item_block = 0; - base_obj = 0; - method_index = -1; + //fun_cache = 0; + //item_block = 0; arg = -1; } @@ -102,10 +98,8 @@ struct Item name = f.name; fields = f.fields; postfix = f.postfix; - fun_cache = f.fun_cache; - item_block = f.item_block; - base_obj = f.base_obj; - method_index = f.method_index; + //fun_cache = f.fun_cache; + //item_block = f.item_block; arg = f.arg; for(size_t i=0 ; iempty(); - else - if( space_local.is_wstr() ) - return !space_local.get_wstr()->empty(); - - return false; -} - - - -void Var::set(bool val) -{ - type = TYPE_BOOL; - space_local.set(val); -} - - -void Var::set(const char * str) -{ - type = TYPE_STRING; - space_local.set(str); -} - - -void Var::set(const wchar_t * str) -{ - type = TYPE_STRING; - space_local.set(str); -} - - -void Var::set(const std::string & str) -{ - type = TYPE_STRING; - space_local.set(str); -} - - -void Var::set(const std::wstring & str) -{ - type = TYPE_STRING; - space_local.set(str); -} - - -void Var::set_function(const std::wstring & str) -{ - type = TYPE_FUNCTION; - space_local.set(str); -} - - - -bool Var::is_equal(const char * str) const -{ - switch(type) - { - case TYPE_BOOL: - return is_equal_bool(str); - - case TYPE_STRING: - return is_equal_string(str); - } - - return false; -} - - -bool Var::is_equal(const wchar_t * str) const -{ - switch(type) - { - case TYPE_BOOL: - return is_equal_bool(str); - - case TYPE_STRING: - return is_equal_string(str); - } - - return false; -} - - -bool Var::is_equal(const std::string & str) const -{ - return is_equal(str.c_str()); -} - - -bool Var::is_equal(const std::wstring & str) const -{ - return is_equal(str.c_str()); -} - - -bool Var::is_equal_bool(const char * str) const -{ - if( space_local.to_bool() ) - { - return str[0] != 0; - } - else - { - return str[0] == 0; - } -} - - -bool Var::is_equal_string(const char * str) const -{ - if( space_local.is_str() ) - { - return space_local.is_equal(str); - } - else - if( space_local.is_wstr() ) - { - std::string space_str_utf8; - pt::wide_to_utf8(*space_local.get_wstr(), space_str_utf8); - return space_str_utf8 == str; - } - - return false; -} - - - -bool Var::is_equal_bool(const wchar_t * str) const -{ - if( space_local.to_bool() ) - { - return str[0] != 0; - } - else - { - return str[0] == 0; - } -} - - -bool Var::is_equal_string(const wchar_t * str) const -{ - if( space_local.is_wstr() ) - { - return space_local.is_equal(str); - } - else - if( space_local.is_str() ) - { - std::string str_utf8; - pt::wide_to_utf8(str, str_utf8); - return space_local.is_equal(str_utf8); - } - - return false; -} - - -void Var::serialize_to(pt::WTextStream & str) -{ - switch(type) - { - case TYPE_BOOL: - case TYPE_LONG: - case TYPE_STRING: - space_local.serialize_to_string(str); - break; - case TYPE_STREAM: - str = stream; - break; - } -} - - - -Var & Var::operator<<(const char * str) -{ - type == TYPE_STREAM; - stream << str; - return *this; -} - - -Var & Var::operator<<(const wchar_t * str) -{ - type == TYPE_STREAM; - stream << str; - return *this; -} - - -Var & Var::operator<<(const std::string & str) -{ - type == TYPE_STREAM; - stream << str; - return *this; -} - - -Var & Var::operator<<(const std::wstring & str) -{ - type == TYPE_STREAM; - stream << str; - return *this; -} - - diff --git a/src/var.h b/src/var.h index 6e2eb8c..796fe12 100644 --- a/src/var.h +++ b/src/var.h @@ -48,22 +48,31 @@ namespace Ezc { +template +struct Env; + /* a variable */ +template class Var { public: + typedef void (*UserFunction)(Env &); enum Type { // string or wstring from space_local TYPE_VOID, + + // or change maybe to something like TYPE_LOCAL_SPACE? TYPE_BOOL, TYPE_LONG, + TYPE_DOUBLE, TYPE_STRING, + TYPE_STREAM, TYPE_FUNCTION, @@ -84,13 +93,39 @@ public: bool to_bool() const; - void set(bool val); void set(const char * str); void set(const wchar_t * str); void set(const std::string & str); void set(const std::wstring & str); - void set_function(const std::wstring & str); +// void set(char val); +// void set(unsigned char val); +// void set(wchar_t val); + void set(bool val); + void set(short val); + void set(int val); + void set(long val); + void set(long long val); + void set(unsigned short val); + void set(unsigned int val); + void set(unsigned long val); + void set(unsigned long long val); + + void set(float val); + void set(double val); + void set(long double val); + + // this str object is copied + void set(const pt::Stream & str); + + void set(UserFunction user_function); + + // this model is not copied, is it a correct interface? + void set(morm::Model & model); + + + + bool is_equal(const char * str) const; bool is_equal(const wchar_t * str) const; @@ -105,27 +140,35 @@ public: Var & operator<<(const wchar_t * str); Var & operator<<(const std::string & str); Var & operator<<(const std::wstring & str); - // add the rest of << operators... + Var & operator<<(char val); + Var & operator<<(unsigned char val); + Var & operator<<(wchar_t val); + Var & operator<<(bool val); + Var & operator<<(short val); + Var & operator<<(int val); + Var & operator<<(long val); + Var & operator<<(long long val); + Var & operator<<(unsigned short val); + Var & operator<<(unsigned int val); + Var & operator<<(unsigned long val); + Var & operator<<(unsigned long long val); + Var & operator<<(float val); + Var & operator<<(double val); + Var & operator<<(long double val); + Var & operator<<(const pt::Stream & str); + UserFunction user_function; morm::Model * model; morm::ModelContainerWrapper * model_container_wrapper; pt::Date * date; morm::SpaceWrapper * space_wrapper; - - - //pt::Space * space; - - pt::Space space_local; - pt::WTextStream stream; - + StreamType stream; private: - bool to_bool_str() const; - bool is_equal_bool(const char * str) const; bool is_equal_string(const char * str) const; @@ -134,6 +177,7 @@ private: + /* * old */ @@ -153,6 +197,559 @@ private: +template +Var::Var() +{ + clear(); +} + + +template +void Var::clear() +{ + //res = false; + //is_function = false; + + type = TYPE_VOID; + user_function = nullptr; + model = nullptr; + model_container_wrapper = nullptr; + date = nullptr; + space_wrapper = nullptr; + space_local.clear(); + stream.clear(); +} + + + +template +bool Var::to_bool() const +{ + switch(type) + { + case TYPE_VOID: + return false; + + case TYPE_BOOL: + case TYPE_LONG: + case TYPE_DOUBLE: + case TYPE_STRING: + return space_local.to_bool(); + + case TYPE_STREAM: + case TYPE_FUNCTION: + case TYPE_MODEL: + case TYPE_MODEL_CONTAINER_WRAPPER: + case TYPE_SPACE_WRAPPER: + break; + } + + return false; +} + + + + +template +void Var::set(const char * str) +{ + type = TYPE_STRING; + space_local.set(str); +} + + +template +void Var::set(const wchar_t * str) +{ + type = TYPE_STRING; + space_local.set(str); +} + + +template +void Var::set(const std::string & str) +{ + type = TYPE_STRING; + space_local.set(str); +} + + +template +void Var::set(const std::wstring & str) +{ + type = TYPE_STRING; + space_local.set(str); +} + +/* +template +void Var::set(char val) +{ + type = TYPE_STRING; + space_local.set(str); +} + +template +void Var::set(unsigned char val) +{ + type = TYPE_STRING; + space_local.set(str); +} + +template +void Var::set(wchar_t val) +{ + type = TYPE_STRING; + space_local.set(str); +} +*/ + + +template +void Var::set(bool val) +{ + type = TYPE_BOOL; + space_local.set(val); +} + + + +template +void Var::set(short val) +{ + type = TYPE_LONG; + space_local.set(val); +} + +template +void Var::set(int val) +{ + type = TYPE_LONG; + space_local.set(val); +} + +template +void Var::set(long val) +{ + type = TYPE_LONG; + space_local.set(val); +} + +template +void Var::set(long long val) +{ + type = TYPE_LONG; + space_local.set(val); +} + +template +void Var::set(unsigned short val) +{ + type = TYPE_LONG; + space_local.set(val); +} + +template +void Var::set(unsigned int val) +{ + type = TYPE_LONG; + space_local.set(val); +} + +template +void Var::set(unsigned long val) +{ + type = TYPE_LONG; + space_local.set(val); +} + +template +void Var::set(unsigned long long val) +{ + type = TYPE_LONG; + space_local.set(val); +} + + +template +void Var::set(float val) +{ + type = TYPE_DOUBLE; + space_local.set(val); +} + + +template +void Var::set(double val) +{ + type = TYPE_DOUBLE; + space_local.set(val); +} + + +template +void Var::set(long double val) +{ + type = TYPE_DOUBLE; + space_local.set(val); +} + + +template +void Var::set(const pt::Stream & str) +{ + type = TYPE_STREAM; + stream.clear(); + stream << str; +} + + + +template +void Var::set(UserFunction user_function) +{ + type = TYPE_FUNCTION; + this->user_function = user_function; +} + + +template +void Var::set(morm::Model & model) +{ + type = TYPE_MODEL; + this->model = &model; +} + + + +template +bool Var::is_equal(const char * str) const +{ + switch(type) + { + case TYPE_BOOL: + return is_equal_bool(str); + + case TYPE_STRING: + return is_equal_string(str); + + case TYPE_VOID: + case TYPE_LONG: + case TYPE_DOUBLE: + case TYPE_STREAM: + case TYPE_FUNCTION: + case TYPE_MODEL: + case TYPE_MODEL_CONTAINER_WRAPPER: + case TYPE_SPACE_WRAPPER: + break; + + } + + return false; +} + + +template +bool Var::is_equal(const wchar_t * str) const +{ + switch(type) + { + case TYPE_BOOL: + return is_equal_bool(str); + + case TYPE_STRING: + return is_equal_string(str); + + case TYPE_VOID: + case TYPE_LONG: + case TYPE_DOUBLE: + case TYPE_STREAM: + case TYPE_FUNCTION: + case TYPE_MODEL: + case TYPE_MODEL_CONTAINER_WRAPPER: + case TYPE_SPACE_WRAPPER: + break; + + } + + return false; +} + + +template +bool Var::is_equal(const std::string & str) const +{ + return is_equal(str.c_str()); +} + + +template +bool Var::is_equal(const std::wstring & str) const +{ + return is_equal(str.c_str()); +} + + +template +bool Var::is_equal_bool(const char * str) const +{ + if( space_local.to_bool() ) + { + return str[0] != 0; + } + else + { + return str[0] == 0; + } +} + + +template +bool Var::is_equal_string(const char * str) const +{ + if( space_local.is_str() ) + { + return space_local.is_equal(str); + } + else + if( space_local.is_wstr() ) + { + std::string space_str_utf8; + pt::wide_to_utf8(*space_local.get_wstr(), space_str_utf8); + return space_str_utf8 == str; + } + + return false; +} + + + +template +bool Var::is_equal_bool(const wchar_t * str) const +{ + if( space_local.to_bool() ) + { + return str[0] != 0; + } + else + { + return str[0] == 0; + } +} + + +template +bool Var::is_equal_string(const wchar_t * str) const +{ + if( space_local.is_wstr() ) + { + return space_local.is_equal(str); + } + else + if( space_local.is_str() ) + { + std::string str_utf8; + pt::wide_to_utf8(str, str_utf8); + return space_local.is_equal(str_utf8); + } + + return false; +} + + +template +void Var::serialize_to(pt::WTextStream & str) +{ + switch(type) + { + case TYPE_BOOL: + case TYPE_LONG: + case TYPE_DOUBLE: + case TYPE_STRING: + space_local.serialize_to_string(str); + break; + + case TYPE_STREAM: + str = stream; + break; + + case TYPE_VOID: + case TYPE_FUNCTION: + case TYPE_MODEL: + case TYPE_MODEL_CONTAINER_WRAPPER: + case TYPE_SPACE_WRAPPER: + break; + } +} + + + +template +Var & Var::operator<<(const char * str) +{ + type = TYPE_STREAM; + stream << str; + return *this; +} + + +template +Var & Var::operator<<(const wchar_t * str) +{ + type = TYPE_STREAM; + stream << str; + return *this; +} + + +template +Var & Var::operator<<(const std::string & str) +{ + type = TYPE_STREAM; + stream << str; + return *this; +} + + +template +Var & Var::operator<<(const std::wstring & str) +{ + type = TYPE_STREAM; + stream << str; + return *this; +} + + +template +Var & Var::operator<<(char val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(unsigned char val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(wchar_t val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(bool val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(short val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(int val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(long val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(long long val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(unsigned short val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(unsigned int val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(unsigned long val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(unsigned long long val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(float val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(double val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(long double val) +{ + type = TYPE_STREAM; + stream << val; + return *this; +} + +template +Var & Var::operator<<(const pt::Stream & str) +{ + type = TYPE_STREAM; + stream << str; + return *this; +} + + + } #endif diff --git a/src/vars.h b/src/vars.h index 7ce121d..add668b 100644 --- a/src/vars.h +++ b/src/vars.h @@ -40,20 +40,23 @@ #include "var.h" #include "utf8/utf8.h" +#include "env.h" #include #include #include - namespace Ezc { +// rename to something like Object? or a better name? template class Vars { public: + typedef void (*UserFunction)(Env &); + Var & add(const char * name); Var & add(const wchar_t * name); @@ -65,6 +68,16 @@ public: void add(const std::string & name, const Var & var); void add(const std::wstring & name, const Var & var); + Var & add(const char * name, UserFunction user_function); + Var & add(const wchar_t * name, UserFunction user_function); + Var & add(const std::string & name, UserFunction user_function); + Var & add(const std::wstring & name, UserFunction user_function); + + Var & add(const char * name, morm::Model & model); + Var & add(const wchar_t * name, morm::Model & model); + Var & add(const std::string & name, morm::Model & model); + Var & add(const std::wstring & name, morm::Model & model); + Var * find(const char * name) const; Var * find(const wchar_t * name) const; Var * find(const std::string & name) const; @@ -77,7 +90,7 @@ private: VarList var_list; typedef std::map*> VarMap; - VarMap var_map + VarMap var_map; }; @@ -95,9 +108,8 @@ Var & Vars::add(const char * name) template Var & Vars::add(const wchar_t * name) { - Var & var = var_map[name]; - var.clear(); - return var; + std::wstring name_str(name); + return add(name_str); } @@ -113,9 +125,16 @@ Var & Vars::add(const std::string & name) template Var & Vars::add(const std::wstring & name) { - Var & var = var_map[name]; - var.clear(); - return var; + auto i = var_map.insert(std::make_pair(name, nullptr)); + + if( i.second ) + { + Var & var = var_list.emplace_back(); + i.first->second = &var; + } + + i.first->second->clear(); + return *(i.first->second); } @@ -131,8 +150,8 @@ void Vars::add(const char * name, const Var & var) template void Vars::add(const wchar_t * name, const Var & var) { - var_list.push_back(var); - var_map[name] = &var_list.back(); + std::wstring name_str(name); + add(name_str, var); } @@ -153,6 +172,73 @@ void Vars::add(const std::wstring & name, const Var & va } +template +Var & Vars::add(const char * name, UserFunction user_function) +{ + Var & var = add(name); + var.set(user_function); + return var; +} + +template +Var & Vars::add(const wchar_t * name, UserFunction user_function) +{ + Var & var = add(name); + var.set(user_function); + return var; +} + +template +Var & Vars::add(const std::string & name, UserFunction user_function) +{ + Var & var = add(name); + var.set(user_function); + return var; +} + +template +Var & Vars::add(const std::wstring & name, UserFunction user_function) +{ + Var & var = add(name); + var.set(user_function); + return var; +} + + +template +Var & Vars::add(const char * name, morm::Model & model) +{ + Var & var = add(name); + var.set(model); + return var; +} + +template +Var & Vars::add(const wchar_t * name, morm::Model & model) +{ + Var & var = add(name); + var.set(model); + return var; +} + +template +Var & Vars::add(const std::string & name, morm::Model & model) +{ + Var & var = add(name); + var.set(model); + return var; +} + +template +Var & Vars::add(const std::wstring & name, morm::Model & model) +{ + Var & var = add(name); + var.set(model); + return var; +} + + + template Var * Vars::find(const char * name) const { @@ -165,11 +251,11 @@ Var * Vars::find(const char * name) const template Var * Vars::find(const wchar_t * name) const { - VarMap::const_iterator i = var_map.find(name); + typename VarMap::const_iterator i = var_map.find(name); if( i != var_map.end() ) { - return &(*i); + return i->second; } return nullptr; @@ -188,11 +274,11 @@ Var * Vars::find(const std::string & name) const template Var * Vars::find(const std::wstring & name) const { - VarMap::const_iterator i = var_map.find(name); + typename VarMap::const_iterator i = var_map.find(name); if( i != var_map.end() ) { - return &(*i); + return i->second; } return nullptr;