diff --git a/src/Makefile.dep b/src/Makefile.dep index b6e23c4..0877035 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -3,33 +3,56 @@ blocks.o: blocks.h item.h cache.h functions.h ../../pikotools/src/utf8/utf8.h blocks.o: ../../pikotools/src/textstream/stream.h blocks.o: ../../pikotools/src/utf8/utf8_templates.h -blocks.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h objects.h +blocks.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h var.h +blocks.o: ../../pikotools/src/date/date.h +blocks.o: ../../pikotools/src/convert/inttostr.h +blocks.o: ../../pikotools/src/textstream/textstream.h +blocks.o: ../../pikotools/src/textstream/stream.h +blocks.o: ../../pikotools/src/space/space.h +blocks.o: ../../pikotools/src/textstream/types.h +blocks.o: ../../pikotools/src/membuffer/membuffer.h +blocks.o: ../../pikotools/src/textstream/types.h objects.h cache.o: cache.h item.h functions.h ../../pikotools/src/utf8/utf8.h cache.o: ../../pikotools/src/textstream/stream.h cache.o: ../../pikotools/src/utf8/utf8_templates.h -cache.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h objects.h blocks.h +cache.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h var.h +cache.o: ../../pikotools/src/date/date.h +cache.o: ../../pikotools/src/convert/inttostr.h +cache.o: ../../pikotools/src/textstream/textstream.h +cache.o: ../../pikotools/src/textstream/stream.h +cache.o: ../../pikotools/src/space/space.h +cache.o: ../../pikotools/src/textstream/types.h +cache.o: ../../pikotools/src/membuffer/membuffer.h +cache.o: ../../pikotools/src/textstream/types.h objects.h blocks.h item.o: item.h models.o: models.h pattern.o: pattern.h item.h cache.h functions.h pattern.o: ../../pikotools/src/utf8/utf8.h pattern.o: ../../pikotools/src/textstream/stream.h pattern.o: ../../pikotools/src/utf8/utf8_templates.h -pattern.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h objects.h -pattern.o: blocks.h +pattern.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h var.h +pattern.o: ../../pikotools/src/date/date.h +pattern.o: ../../pikotools/src/convert/inttostr.h +pattern.o: ../../pikotools/src/textstream/textstream.h +pattern.o: ../../pikotools/src/textstream/stream.h +pattern.o: ../../pikotools/src/space/space.h +pattern.o: ../../pikotools/src/textstream/types.h +pattern.o: ../../pikotools/src/membuffer/membuffer.h +pattern.o: ../../pikotools/src/textstream/types.h objects.h blocks.h patternparser.o: patternparser.h blocks.h item.h cache.h functions.h patternparser.o: ../../pikotools/src/utf8/utf8.h patternparser.o: ../../pikotools/src/textstream/stream.h patternparser.o: ../../pikotools/src/utf8/utf8_templates.h -patternparser.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h objects.h -patternparser.o: pattern.h ../../pikotools/src/log/log.h +patternparser.o: ../../pikotools/src/utf8/utf8_private.h funinfo.h var.h +patternparser.o: ../../pikotools/src/date/date.h +patternparser.o: ../../pikotools/src/convert/inttostr.h patternparser.o: ../../pikotools/src/textstream/textstream.h patternparser.o: ../../pikotools/src/textstream/stream.h patternparser.o: ../../pikotools/src/space/space.h patternparser.o: ../../pikotools/src/textstream/types.h -patternparser.o: ../../pikotools/src/convert/inttostr.h -patternparser.o: ../../pikotools/src/date/date.h patternparser.o: ../../pikotools/src/membuffer/membuffer.h -patternparser.o: ../../pikotools/src/textstream/types.h +patternparser.o: ../../pikotools/src/textstream/types.h objects.h pattern.h +patternparser.o: ../../pikotools/src/log/log.h patternparser.o: ../../pikotools/src/log/filelog.h patternparser.o: ../../pikotools/src/convert/convert.h patternparser.o: ../../pikotools/src/convert/inttostr.h @@ -38,3 +61,14 @@ patternparser.o: ../../pikotools/src/convert/strtoint.h patternparser.o: ../../pikotools/src/convert/text.h patternparser.o: ../../pikotools/src/convert/misc.h patternparser.o: ../../pikotools/src/convert/double.h +var.o: var.h ../../pikotools/src/date/date.h +var.o: ../../pikotools/src/convert/inttostr.h +var.o: ../../pikotools/src/textstream/textstream.h +var.o: ../../pikotools/src/textstream/stream.h +var.o: ../../pikotools/src/space/space.h +var.o: ../../pikotools/src/textstream/types.h ../../pikotools/src/utf8/utf8.h +var.o: ../../pikotools/src/textstream/stream.h +var.o: ../../pikotools/src/utf8/utf8_templates.h +var.o: ../../pikotools/src/utf8/utf8_private.h +var.o: ../../pikotools/src/membuffer/membuffer.h +var.o: ../../pikotools/src/textstream/types.h diff --git a/src/Makefile.o.dep b/src/Makefile.o.dep index 2f6a2c4..32a64b6 100644 --- a/src/Makefile.o.dep +++ b/src/Makefile.o.dep @@ -1 +1 @@ -o = blocks.o cache.o item.o models.o pattern.o patternparser.o \ No newline at end of file +o = blocks.o cache.o item.o models.o pattern.o patternparser.o var.o \ No newline at end of file diff --git a/src/funinfo.h b/src/funinfo.h index 606e9c0..efa05e0 100644 --- a/src/funinfo.h +++ b/src/funinfo.h @@ -42,33 +42,14 @@ #include #include #include "item.h" +#include "modelcontainerwrapper.h" +#include "var.h" namespace Ezc { -/* - a variable -*/ -struct Var -{ - /* - * if true then means 'str' is a function name and should be called (res is ignored) - * - * if false then means 'str' is a string value and res is a boolean value - */ - bool is_function; - - std::wstring str; // a string value - bool res; // a boolean value - - Var() - { - res = false; - is_function = false; - } -}; typedef std::map Vars; @@ -152,8 +133,9 @@ struct FunInfo // a result consists of a string and a boolean value // output stream StreamType & out; - // return value from a user's function (default false if not set directly by the function) - bool res; + + // result + Var & res; // table of parameters // the table can be empty @@ -162,7 +144,7 @@ struct FunInfo // the first parameter // you can always use it even if there are not any parameters (params is empty) // in such a way the reference points to an empty string - const std::wstring & par; + //const std::wstring & par; // an input stream used in [filter] statement // if there is other statement than [filter] then this is an empty stream @@ -209,13 +191,11 @@ struct FunInfo - // arguments: output_stream, table_of_parameters, the_first_parameter - FunInfo(StreamType & o, + FunInfo(Var & result, std::vector & pars, - const std::wstring & first_par, const StreamType & input_stream, Stack & s, - const Item & item_) : out(o), params(pars), par(first_par), in(input_stream), stack(s), item(item_) + const Item & item_) : out(result.stream), res(result), params(pars), in(input_stream), stack(s), item(item_) { Clear(); } @@ -223,7 +203,6 @@ struct FunInfo void Clear() { - res = false; // result is false by default is_for = false; is_if = false; is_if_def = false; @@ -231,7 +210,7 @@ struct FunInfo is_normal = false; is_filter = false; iter = 0; - stack_tab = 0; + stack_tab = nullptr; stack_index = 0; } @@ -242,6 +221,7 @@ struct FunInfo * * add a function with const wchar_t * */ + /* Stack * FindLastFor(const std::wstring & name) { for(size_t i = stack_index ; i > 0 ; --i) @@ -257,8 +237,9 @@ struct FunInfo return 0; } + */ - + /* Stack * FindLastFor(const std::wstring & name, const std::wstring & postfix) { for(size_t i = stack_index ; i > 0 ; --i) @@ -274,8 +255,10 @@ struct FunInfo return 0; } + */ + /* template FunUserObject * FindUserObject(const std::wstring & function_name, Stack ** ezc_stack = 0) { @@ -294,7 +277,7 @@ struct FunInfo return 0; } - + */ }; diff --git a/src/generator.h b/src/generator.h index 517bdb5..7dd83f8 100644 --- a/src/generator.h +++ b/src/generator.h @@ -143,7 +143,7 @@ private: struct FindHelper { - std::wstring * fun_name; + const std::wstring * fun_name; BaseObj * base_obj; int method_index; @@ -231,10 +231,11 @@ private: // temporary streams used in [if..] [for...] or [def ...] // or if output_stream is null and an ezc function should be called - StreamType stream_temp1, stream_temp_define; + //StreamType stream_temp1, stream_temp_define; + //StreamType stream_temp_define; // last result from a user function (FunInfo::res) - bool last_res; + //bool last_res; // true if this Generator is working now bool is_generator_working; @@ -249,7 +250,7 @@ private: // an empty string for FunInfo objects // when there is no any parameters - const std::wstring empty; + //const std::wstring empty; // a stack for [for] statements std::vector stack_tab; @@ -305,59 +306,58 @@ private: void CallFunction(typename Functions::UserFunction & function, FunInfo & info); void CallFunction(typename Functions::UserFunction & function, + Var & result, std::vector & parameters, - StreamType & out_stream, const StreamType & in_stream); bool CallBlock(Item & item_block, - std::vector & parameters, - StreamType & out_stream); + Var & result, + std::vector & parameters); void CallObject(BaseObj & base_obj, int method_index, FunInfo & info); - void PrintDate(pt::Date * date, std::vector & parameters, StreamType & out_stream); - bool PrintDatePart(pt::Date * date, const std::wstring & field, std::vector & parameters, StreamType & out_stream); + 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, std::vector & parameters, StreamType & out_stream); + bool CallDate(FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters); - void PrintLastSpaceField(pt::Space * space, std::vector & parameters, StreamType & out_stream); - void CallSpaceObjectForLastField(std::vector & parameters, StreamType & out_stream, pt::Space * space); - pt::Space * CallSpaceObjectForMiddleField(std::wstring & root_space_name, std::vector & fields, size_t field_index, 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, std::vector & parameters, StreamType & out_stream, + 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, std::wstring & root_space_name, std::vector & fields, + 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, std::vector & parameters, StreamType & out_stream); + 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, std::vector & parameters, StreamType & out_stream, const StreamType & in_stream); - bool CallModel(morm::Model & model, FindHelper & find_helper, std::vector & fields, std::vector & parameters, StreamType & out_stream, 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, std::vector & parameters, StreamType & out_stream, const StreamType & in_stream); + bool CallWrapper(FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters, const StreamType & in_stream); #endif void CallObject(BaseObj & base_obj, int method_index, + Var & result, std::vector & parameters, - StreamType & out_stream, const StreamType & in_stream); bool CallVariable(Item::Function & item_fun, Var & variable, + Var & result, std::vector & parameters, - StreamType & out_stream, const StreamType & in_stream); bool Call(Item::Function & item_fun, - std::wstring * fun_name, - StreamType & out_stream, - bool clear_out_stream, + const std::wstring * fun_name, + Var & result, const StreamType & in_stream); - bool Call(Item::Function & item_fun); + 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); @@ -374,8 +374,8 @@ private: bool IsPrettyPrint(std::vector & parameters); bool IsCurrentParam(std::vector & parameters); - void DumpSpaceIfNeeded(std::vector & parameters, StreamType & out_stream, pt::Space * space); - void DumpModelIfNeeded(morm::Model & model, std::vector & parameters, StreamType & out_stream); + 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); @@ -1164,27 +1164,27 @@ void Generator::CallFunct { PrepareEnvStruct(info); (function)(info); - last_res = info.res; + //last_res = info.res; } template void Generator::CallFunction(typename Functions::UserFunction & function, + Var & result, std::vector & parameters, - StreamType & out_stream, const StreamType & in_stream) { if( !IsTestingFunctionExistence() ) { if( parameters.empty() ) { - FunInfo info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + FunInfo info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallFunction(function, info); } else { - FunInfo info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + FunInfo info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallFunction(function, info); } } @@ -1198,7 +1198,7 @@ void Generator::CallObjec { PrepareEnvStruct(info); base_obj.CallFun(method_index, info); - last_res = info.res; + //last_res = info.res; } @@ -1209,12 +1209,9 @@ bool Generator::HasParam( { for(Var & var : parameters) { - if( !var.is_function ) + if( var.is_equal(param1) || (param2 && var.is_equal(param2)) ) { - if( var.str == param1 || (param2 && var.str == param2) ) - { - return true; - } + return true; } } @@ -1253,7 +1250,7 @@ bool Generator::IsPrettyP template -void Generator::DumpSpaceIfNeeded(std::vector & parameters, StreamType & out_stream, pt::Space * space) +void Generator::DumpSpaceIfNeeded(Var & result, std::vector & parameters, pt::Space * space) { bool dump_space = ShouldMakeSpaceDump(parameters); bool dump_json = ShouldMakeJsonDump(parameters); @@ -1264,19 +1261,22 @@ void Generator::DumpSpace if( dump_space ) { - space->serialize_to_space_stream(out_stream, pretty); + space->serialize_to_space_stream(result.stream, pretty); + result.type = Var::TYPE_STREAM; } else if( dump_json ) { - space->serialize_to_json_stream(out_stream, pretty); + space->serialize_to_json_stream(result.stream, pretty); + result.type = Var::TYPE_STREAM; } } } template -void Generator::DumpModelIfNeeded(morm::Model & model, std::vector & parameters, StreamType & out_stream) +void Generator::DumpModelIfNeeded( + morm::Model & model, Var & result, std::vector & parameters) { bool dump_space = ShouldMakeSpaceDump(parameters); bool dump_json = ShouldMakeJsonDump(parameters); @@ -1297,7 +1297,9 @@ void Generator::DumpModel // need to be made in a different way pt::TextStream temp_str; model.to_text(temp_str, false, false); - out_stream << temp_str; + result.stream << temp_str; // what about escaping here? why Model::to_text() don't take WTextStream? + result.type = Var::TYPE_STREAM; + //out_stream << temp_str; } } } @@ -1305,7 +1307,8 @@ void Generator::DumpModel template -void Generator::PrintDate(pt::Date * date, std::vector & parameters, StreamType & out_stream) +void Generator::PrintDate( + pt::Date * date, Var & result, std::vector & parameters) { bool is_roman = HasParam(parameters, L"roman"); bool is_no_sec = HasParam(parameters, L"no_sec"); @@ -1314,32 +1317,40 @@ void Generator::PrintDate if( only_date ) { - date->SerializeYearMonthDay(out_stream, is_roman); + result.type = Var::TYPE_STREAM; + date->SerializeYearMonthDay(result.stream, is_roman); } else if( only_time ) { + result.type = Var::TYPE_STREAM; + if( is_no_sec ) - date->SerializeHourMin(out_stream); + date->SerializeHourMin(result.stream); else - date->SerializeHourMinSec(out_stream); + date->SerializeHourMinSec(result.stream); } else { - date->Serialize(out_stream, is_roman, !is_no_sec); + result.type = Var::TYPE_STREAM; + date->Serialize(result.stream, is_roman, !is_no_sec); } } template -bool Generator::PrintDatePart(pt::Date * date, const std::wstring & field, std::vector & parameters, StreamType & out_stream) +bool Generator::PrintDatePart( + pt::Date * date, const std::wstring & field, Var & result, std::vector & parameters) { bool is_test = IsTestingFunctionExistence(); if( field == L"year" ) { if( !is_test ) - out_stream << date->year; + { + result.type = Var::TYPE_STREAM; + result.stream << date->year; + } } else if( field == L"month" ) @@ -1347,36 +1358,49 @@ bool Generator::PrintDate if( !is_test ) { bool is_roman = HasParam(parameters, L"roman"); + result.type = Var::TYPE_STREAM; if( is_roman ) - pt::Date::SerializeMonthAsRoman(out_stream, date->month); + pt::Date::SerializeMonthAsRoman(result.stream, date->month); else - out_stream << date->month; + result.stream << date->month; } } else if( field == L"day" ) { if( !is_test ) - out_stream << date->day; + { + result.type = Var::TYPE_STREAM; + result.stream << date->day; + } } else if( field == L"hour" ) { if( !is_test ) - out_stream << date->hour; + { + result.type = Var::TYPE_STREAM; + result.stream << date->hour; + } } else if( field == L"min" ) { if( !is_test ) - out_stream << date->min; + { + result.type = Var::TYPE_STREAM; + result.stream << date->min; + } } else if( field == L"sec" ) { if( !is_test ) - out_stream << date->sec; + { + result.type = Var::TYPE_STREAM; + result.stream << date->sec; + } } else { @@ -1388,7 +1412,8 @@ bool Generator::PrintDate template -bool Generator::CallDate(FindHelper & find_helper, std::vector & fields, std::vector & parameters, StreamType & out_stream) +bool Generator::CallDate( + FindHelper & find_helper, std::vector & fields, Var & result, std::vector & parameters) { bool found = true; bool all_fields_known = (find_helper.field_index == fields.size()); @@ -1396,12 +1421,12 @@ bool Generator::CallDate( if( all_fields_known ) { - PrintDate(find_helper.wrapper->date, parameters, out_stream); + PrintDate(find_helper.wrapper->date, result, parameters); } else if( last_field_not_known ) { - if( !PrintDatePart(find_helper.wrapper->date, fields[find_helper.field_index], parameters, out_stream) ) + if( !PrintDatePart(find_helper.wrapper->date, fields[find_helper.field_index], result, parameters) ) { if( !IsTestingFunctionExistence() ) { @@ -1428,18 +1453,18 @@ bool Generator::CallDate( template -void Generator::CallSpaceObjectForLastField(std::vector & parameters, StreamType & out_stream, pt::Space * space) +void Generator::CallSpaceObjectForLastField(Var & result, std::vector & parameters, pt::Space * space) { if( !IsTestingFunctionExistence() ) { // CHECKME should we convert the last value to last_res? - DumpSpaceIfNeeded(parameters, out_stream, space); + DumpSpaceIfNeeded(result, parameters, space); } } template -pt::Space * Generator::CallSpaceObjectForMiddleField(std::wstring & root_space_name, std::vector & fields, size_t field_index, pt::Space * space) +pt::Space * Generator::CallSpaceObjectForMiddleField(const std::wstring & root_space_name, std::vector & fields, size_t field_index, pt::Space * space) { std::wstring & next_field = fields[field_index]; space = space->get_space(next_field); @@ -1455,8 +1480,9 @@ pt::Space * Generator::Ca template -void Generator::CallSpaceTableForLastField(morm::SpaceWrapper & space_wrapper, std::vector & parameters, StreamType & out_stream, - pt::Space * space, size_t model_wrapper_space_table_index) +void Generator::CallSpaceTableForLastField( + 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(); @@ -1465,19 +1491,20 @@ void Generator::CallSpace // we are in [for...]statement, increment iterator and check the range space_wrapper.increment_iterator(model_wrapper_space_table_index, table->size()); space_wrapper.invalidate_iterators(model_wrapper_space_table_index + 1); - size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index); - last_res = (iterator_value < table->size()); + //size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index); + space_wrapper.get_space_iterator_value(model_wrapper_space_table_index); + //last_res = (iterator_value < table->size()); } else { // we are not in [for..], it can be for example [if...], return true if the table is not empty // if we are in [if-def...] - then last_res is set later in MakeTextIfDef(Item & item) when Call() method returns - last_res = !table->empty(); + //last_res = !table->empty(); } if( !IsTestingFunctionExistence() ) { - DumpSpaceIfNeeded(parameters, out_stream, space); + DumpSpaceIfNeeded(result, parameters, space); if( IsCurrentParam(parameters) ) { @@ -1485,7 +1512,10 @@ void Generator::CallSpace if( iterator_value < table->size() ) { - (*table)[iterator_value]->serialize_to_string(out_stream); + //(*table)[iterator_value]->serialize_to_string(out_stream); + + (*table)[iterator_value]->serialize_to_string(result.stream); + result.type = Var::TYPE_STREAM; } } } @@ -1493,8 +1523,9 @@ void Generator::CallSpace template -pt::Space * Generator::CallSpaceTableForMiddleField(morm::SpaceWrapper & space_wrapper, std::wstring & root_space_name, std::vector & fields, - size_t field_index, pt::Space * space, size_t model_wrapper_space_table_index) +pt::Space * Generator::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) { pt::Space::TableType * table = space->get_table(); @@ -1517,30 +1548,37 @@ pt::Space * Generator::Ca template -void Generator::PrintLastSpaceField(pt::Space * space, std::vector & parameters, StreamType & out_stream) +void Generator::PrintLastSpaceField( + pt::Space * space, Var & result, std::vector & parameters) { bool no_escape = HasParam(parameters, L"raw", L"noescape"); + // FIXME what about escaping here? + if( no_escape ) { - pt::WTextStream str; - space->serialize_to_string(str); - CopyStream(str, out_stream, false); + //pt::WTextStream str; + space->serialize_to_string(result.stream); + result.type = Var::TYPE_STREAM; + //CopyStream(str, out_stream, false); } else { - space->serialize_to_string(out_stream); +// space->serialize_to_string(out_stream); + space->serialize_to_string(result.stream); + result.type = Var::TYPE_STREAM; } } template -bool Generator::CallSpace(FindHelper & find_helper, std::vector & fields, std::vector & parameters, StreamType & out_stream) +bool Generator::CallSpace( + 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(); - last_res = false; + //last_res = false; size_t field_index = find_helper.field_index; /* @@ -1558,7 +1596,7 @@ bool Generator::CallSpace { if( is_last_field ) { - CallSpaceObjectForLastField(parameters, out_stream, space); + CallSpaceObjectForLastField(result, parameters, space); } else { @@ -1576,7 +1614,7 @@ bool Generator::CallSpace { if( is_last_field ) { - CallSpaceTableForLastField(*space_wrapper, parameters, out_stream, space, model_wrapper_space_table_index); + CallSpaceTableForLastField(*space_wrapper, result, parameters, space, model_wrapper_space_table_index); field_index += 1; } else @@ -1597,7 +1635,7 @@ bool Generator::CallSpace { if( !IsTestingFunctionExistence() ) { - PrintLastSpaceField(space, parameters, out_stream); + PrintLastSpaceField(space, result, parameters); } field_index += 1; @@ -1623,7 +1661,7 @@ bool Generator::CallSpace template bool Generator::CallModelField( - morm::Model & model, const std::wstring & field, std::vector & parameters, StreamType & out_stream, 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() @@ -1636,21 +1674,22 @@ bool Generator::CallModel if( parameters.empty() ) { - FunInfo info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + FunInfo 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; + //last_res = info.res; } else { - FunInfo info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + FunInfo 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; + //last_res = info.res; } if( found && !str.empty()) { bool no_escape = HasParam(parameters, L"raw", L"noescape"); - CopyStream(str, out_stream, !no_escape); + CopyStream(str, result.stream, !no_escape); + result.type = Var::TYPE_STREAM; } return found; @@ -1658,8 +1697,9 @@ bool Generator::CallModel template -bool Generator::CallModel(morm::Model & model, FindHelper & find_helper, std::vector & fields, - std::vector & parameters, StreamType & out_stream, const StreamType & in_stream) +bool Generator::CallModel( + morm::Model & model, FindHelper & find_helper, std::vector & fields, + Var & result, std::vector & parameters, const StreamType & in_stream) { bool found = true; @@ -1668,14 +1708,14 @@ bool Generator::CallModel // all fields items are models or models containers if( !IsTestingFunctionExistence() ) { - DumpModelIfNeeded(model, parameters, out_stream); + DumpModelIfNeeded(model, result, parameters); } } else if( find_helper.field_index + 1 == fields.size() ) { // last field is not a model nor a models container - if( !CallModelField(model, fields[find_helper.field_index], parameters, out_stream, in_stream) ) + if( !CallModelField(model, fields[find_helper.field_index], result, parameters, in_stream) ) { if( !IsTestingFunctionExistence() ) { @@ -1744,10 +1784,10 @@ void Generator::FindLastM template bool Generator::CallWrapper(FindHelper & find_helper, std::vector & fields, - std::vector & parameters, StreamType & out_stream, const StreamType & in_stream) + Var & result, std::vector & parameters, const StreamType & in_stream) { bool found = true; - last_res = false; + //last_res = false; FindLastModelWrapper(find_helper, fields); // if: @@ -1760,17 +1800,17 @@ bool Generator::CallWrapp if( find_helper.wrapper->space_wrapper ) { - found = CallSpace(find_helper, fields, parameters, out_stream); + found = CallSpace(find_helper, fields, result, parameters); } if( find_helper.wrapper->date ) { - found = CallDate(find_helper, fields, parameters, out_stream); + found = CallDate(find_helper, fields, result, parameters); } if( find_helper.wrapper->model ) { - found = CallModel(*find_helper.wrapper->model, find_helper, fields, parameters, out_stream, in_stream); + found = CallModel(*find_helper.wrapper->model, find_helper, fields, result, parameters, in_stream); } if( find_helper.wrapper->model_container_wrapper ) @@ -1779,7 +1819,7 @@ bool Generator::CallWrapp if( model ) { - found = CallModel(*model, find_helper, fields, parameters, out_stream, in_stream); + found = CallModel(*model, find_helper, fields, result, parameters, in_stream); } else { @@ -1797,12 +1837,12 @@ bool Generator::CallWrapp { find_helper.wrapper->model_container_wrapper->increment_iterator(); find_helper.wrapper->clear_childs(); - last_res = find_helper.wrapper->model_container_wrapper->is_iterator_correct(); + //last_res = find_helper.wrapper->model_container_wrapper->is_iterator_correct(); } else { // for [if-def...] last_res will be set later - last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty(); + //last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty(); } } } @@ -1817,20 +1857,20 @@ bool Generator::CallWrapp template void Generator::CallObject(BaseObj & base_obj, int method_index, + Var & result, std::vector & parameters, - StreamType & out_stream, const StreamType & in_stream) { if( !IsTestingFunctionExistence() ) { if( parameters.empty() ) { - FunInfo info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + FunInfo info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallObject(base_obj, method_index, info); } else { - FunInfo info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); + FunInfo info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item); CallObject(base_obj, method_index, info); } } @@ -1840,8 +1880,8 @@ void Generator::CallObjec template bool Generator::CallBlock(Item & item_block, - std::vector & parameters, - StreamType & out_stream) + Var & result, + std::vector & parameters) { if( block_stack_index >= block_stack_tab.size() ) { @@ -1863,9 +1903,12 @@ bool Generator::CallBlock MakeText(item_block); - CopyStream(*output_stream, out_stream); + CopyStream(*output_stream, result.stream); + result.type = Var::TYPE_STREAM; // last_res is set by [return ...] statement or other last evaluated function + // FIXME what about result now? + ClearStream(*output_stream); output_stream = old_stream; block_stack_index -= 1; @@ -1877,18 +1920,30 @@ return true; template -bool Generator::CallVariable(Item::Function & item_fun, Var & variable, std::vector & parameters, StreamType & out_stream, const StreamType & in_stream) +bool Generator::CallVariable( + Item::Function & item_fun, Var & variable, Var & result, std::vector & parameters, const StreamType & in_stream) { - if( variable.is_function ) + if( variable.type == Var::TYPE_FUNCTION ) { - return Call(item_fun, &variable.str, out_stream, false, in_stream); + if( variable.space_local.is_wstr() ) + { + //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); + } + else + { + // put some log? + return false; + } } else { if( !IsTestingFunctionExistence() ) { - out_stream << variable.str; - last_res = variable.res; + result = variable; + //variable.serialize_to(out_stream); + //out_stream << variable.str; + //last_res = variable.res; } return true; @@ -1903,20 +1958,21 @@ bool Generator::CallVaria * return: true if a function, variable or block was found and called (evaluated) */ template -bool Generator::Call(Item::Function & item_fun, - std::wstring * fun_name, - StreamType & out_stream, - bool clear_out_stream, - const StreamType & in_stream) +bool Generator::Call( + Item::Function & item_fun, + const std::wstring * fun_name, + Var & result, + const StreamType & in_stream) { FindHelper find_helper; std::vector parameters; - if( clear_out_stream ) - ClearStream(out_stream); +// if( clear_out_stream ) +// ClearStream(out_stream); - if constexpr(is_autoescape_stream) - out_stream.Escape(true); +// FIXME where to set this? +// if constexpr(is_autoescape_stream) +// out_stream.Escape(true); find_helper.fun_name = fun_name; @@ -1934,35 +1990,38 @@ std::vector parameters; if( fun_child.is_function ) { - StreamType local_temp_stream; - Call(fun_child, nullptr, local_temp_stream, true, empty_stream); +// 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); - CopyStreamToString(local_temp_stream, parameters[i].str); - parameters[i].res = last_res; + 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); +// parameters[i].str = fun_child.name; +// parameters[i].res = ConvertToBool(fun_child.name); + parameters[i].set(fun_child.name); } } #ifdef EZC_HAS_MORM_LIBRARY if( find_helper.wrapper ) - return CallWrapper(find_helper, item_fun.fields, parameters, out_stream, in_stream); + 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, parameters, out_stream, in_stream); + CallObject(*find_helper.base_obj, find_helper.method_index, result, parameters, in_stream); else if( find_helper.function ) - CallFunction(*find_helper.function, parameters, out_stream, in_stream); + CallFunction(*find_helper.function, result, parameters, in_stream); else if( find_helper.item_block ) - return CallBlock(*find_helper.item_block, parameters, out_stream); + return CallBlock(*find_helper.item_block, result, parameters); else if( find_helper.variable ) - return CallVariable(item_fun, *find_helper.variable, parameters, out_stream, in_stream); + return CallVariable(item_fun, *find_helper.variable, result, parameters, in_stream); return true; } @@ -1971,9 +2030,10 @@ std::vector parameters; // return: true if a function or variable was found and called template -bool Generator::Call(Item::Function & item_fun) +bool Generator::Call(Item::Function & item_fun, Var & result) { - return Call(item_fun, nullptr, stream_temp1, true, empty_stream); + //return Call(item_fun, nullptr, stream_temp1, true, result, empty_stream); + return Call(item_fun, nullptr, result, empty_stream); } @@ -2287,13 +2347,13 @@ void Generator::EvaluateP *output_stream << " for: " << item.text; } - last_res = false; + //last_res = false; if( expression_parser ) { if( expression_parser->Parse(item.text) ) { - last_res = expression_parser->LastResultToBool(); + //last_res = expression_parser->LastResultToBool(); if( output_stream ) { @@ -2355,15 +2415,28 @@ void Generator::MakeTextF } else { + Var result; + Call(item.function, nullptr, result, empty_stream); + if( output_stream ) { - Call(item.function, nullptr, *output_stream, false, empty_stream); + result.serialize_to(*output_stream); + } + + /* + if( output_stream ) + { + //Call(item.function, nullptr, *output_stream, false, result, empty_stream); + Call(item.function, nullptr, result, empty_stream); + result.serialize_to(*output_stream); } else { - Call(item.function, nullptr, stream_temp1, false, empty_stream); - ClearStream(stream_temp1); + //Call(item.function, nullptr, stream_temp1, false, result, empty_stream); + Call(item.function, nullptr, result, empty_stream); + //ClearStream(stream_temp1); } + */ } } @@ -2391,6 +2464,7 @@ template void Generator::MakeTextIf(Item & item) { is_generating_if = true; + Var result; if( program_mode ) { @@ -2398,11 +2472,11 @@ void Generator::MakeTextI } else { - if( !Call(item.function) ) + if( !Call(item.function, result) ) return; } - MakeTextIf_go(item, last_res); + MakeTextIf_go(item, result.to_bool()); } @@ -2410,6 +2484,7 @@ template void Generator::MakeTextIfDef(Item & item) { is_generating_if_def = true; + Var result; if( program_mode ) { @@ -2418,10 +2493,10 @@ void Generator::MakeTextI } else { - last_res = Call(item.function); + Call(item.function, result); } - MakeTextIf_go(item, last_res); + MakeTextIf_go(item, result.to_bool()); } @@ -2429,6 +2504,7 @@ template void Generator::MakeTextIfNotDef(Item & item) { is_generating_if_not_def = true; + Var result; if( program_mode ) { @@ -2437,10 +2513,10 @@ void Generator::MakeTextI } else { - last_res = !Call(item.function); + Call(item.function, result); } - MakeTextIf_go(item, last_res); + MakeTextIf_go(item, !result.to_bool()); } @@ -2448,6 +2524,7 @@ template void Generator::MakeTextFor(Item & item) { stack_tab[stack_index-1].is_for = true; + Var result; for( ; !break_generating ; stack_tab[stack_index-1].iter += 1 ) { @@ -2461,6 +2538,7 @@ void Generator::MakeTextF // is_generating_for will be changed by next call to MakeText() // so we should set it in each iterations is_generating_for = true; + result.clear(); if( program_mode ) { @@ -2468,10 +2546,11 @@ void Generator::MakeTextF } else { - Call(item.function, nullptr, stream_temp1, true, empty_stream); + //Call(item.function, nullptr, stream_temp1, true, result, empty_stream); + Call(item.function, nullptr, result, empty_stream); } - if( !last_res ) + if( !result.to_bool() ) break; if( !item.item_tab.empty() ) @@ -2483,9 +2562,10 @@ void Generator::MakeTextF template void Generator::MakeTextDefine(Item & item, Var & var) { - var.str.clear(); - var.res = ConvertToBool(var.str); - var.is_function = false; +// var.str.clear(); +// var.res = ConvertToBool(var.str); +// var.is_function = false; + var.clear(); if( item.function.parameters.empty() ) { @@ -2503,10 +2583,11 @@ void Generator::MakeTextD if( fun.is_function ) { // call function - if( Call(fun, nullptr, stream_temp_define, true, empty_stream) ) + //if( Call(fun, nullptr, stream_temp_define, true, var, empty_stream) ) + if( Call(fun, nullptr, var, empty_stream) ) { - CopyStreamToString(stream_temp_define, var.str); - var.res = last_res; + //CopyStreamToString(stream_temp_define, var.str); + //var.res = last_res; } else { @@ -2515,8 +2596,9 @@ void Generator::MakeTextD } else { - var.str = fun.name; - var.res = ConvertToBool(fun.name); +// var.str = fun.name; +// var.res = ConvertToBool(fun.name); + var.set(fun.name); } } @@ -2559,13 +2641,13 @@ void Generator::MakeTextD template void Generator::MakeTextLet(Item & item, Var & var) { - var.str.clear(); - var.res = ConvertToBool(var.str); - var.is_function = true; +// var.str.clear(); +// var.res = ConvertToBool(var.str); +// var.is_function = true; if( item.function.parameters.empty() ) { - var.is_function = false; + //var.is_function = false; return; } @@ -2576,13 +2658,19 @@ void Generator::MakeTextL } Item::Function & fun = *item.function.parameters[0]; - var.str = fun.name; - var.is_function = fun.is_function; - if( !fun.is_function ) - { - var.res = ConvertToBool(var.str); - } + if( fun.is_function ) + var.set_function(fun.name); + else + var.set(fun.name); + +// var.str = fun.name; +// var.is_function = fun.is_function; + +// if( !fun.is_function ) +// { +// var.res = ConvertToBool(var.str); +// } } @@ -2629,6 +2717,7 @@ void Generator::MakeTextF return; } + Var result; StreamType * old_stream = output_stream; output_stream = filter_tab[filter_index]; ClearStream(*output_stream); @@ -2642,12 +2731,15 @@ void Generator::MakeTextF if( old_stream ) { - Call(item.function, nullptr, *old_stream, false, *output_stream); + //Call(item.function, nullptr, *old_stream, false, result, *output_stream); + Call(item.function, nullptr, result, *output_stream); + result.serialize_to(*old_stream); } else { - Call(item.function, nullptr, stream_temp1, true, *output_stream); - ClearStream(stream_temp1); +// Call(item.function, nullptr, stream_temp1, true, result, *output_stream); +// ClearStream(stream_temp1); + Call(item.function, nullptr, result, *output_stream); } ClearStream(*output_stream); @@ -2728,7 +2820,7 @@ void Generator::MakeTextE template void Generator::MakeTextReturn(Item & item) { - last_res = false; + //last_res = false; if( block_stack_index == 0 ) { @@ -2742,10 +2834,13 @@ void Generator::MakeTextR if( item.has_function ) { + 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() - Call(item.function, nullptr, stream_temp1, false, empty_stream); - ClearStream(stream_temp1); + //Call(item.function, nullptr, stream_temp1, false, result, empty_stream); + //ClearStream(stream_temp1); + Call(item.function, nullptr, result, empty_stream); } } diff --git a/src/var.cpp b/src/var.cpp new file mode 100644 index 0000000..89ddf7d --- /dev/null +++ b/src/var.cpp @@ -0,0 +1,301 @@ +/* + * This file is a part of EZC -- Easy templating in C++ library + * and is distributed under the BSD 3-Clause licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "var.h" +#include "utf8/utf8.h" + + +namespace Ezc +{ + + +Var::Var() +{ + clear(); +} + +void Var::clear() +{ + //res = false; + //is_function = false; + + type = TYPE_VOID; + model = nullptr; + model_container_wrapper = nullptr; + date = nullptr; + space_wrapper = nullptr; + space_local.clear(); + stream.clear(); +} + + + +bool Var::to_bool() const +{ + switch(type) + { + case TYPE_VOID: + return false; + + case TYPE_BOOL: + return space_local.to_bool(); + + case TYPE_STRING: + return to_bool_str(); + } + + return false; +} + + +bool Var::to_bool_str() const +{ + if( space_local.is_str() ) + return !space_local.get_str()->empty(); + 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 new file mode 100644 index 0000000..6e2eb8c --- /dev/null +++ b/src/var.h @@ -0,0 +1,159 @@ +/* + * This file is a part of EZC -- Easy templating in C++ library + * and is distributed under the BSD 3-Clause licence. + * Author: Tomasz Sowa + */ + +/* + * Copyright (c) 2021, Tomasz Sowa + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name Tomasz Sowa nor the names of contributors to this + * project may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef headerfile_ezc_var +#define headerfile_ezc_var + +#include "spacewrapper.h" +#include "date/date.h" +#include "modelcontainerwrapper.h" +#include "textstream/textstream.h" + + + +namespace Ezc +{ + + +/* + a variable +*/ +class Var +{ +public: + + + enum Type + { + // string or wstring from space_local + TYPE_VOID, + TYPE_BOOL, + TYPE_LONG, + TYPE_STRING, + TYPE_STREAM, + + TYPE_FUNCTION, + + TYPE_MODEL, + TYPE_MODEL_CONTAINER_WRAPPER, + TYPE_SPACE_WRAPPER, // or just type_space + + }; + + Type type; + + Var(); + + void clear(); + + + 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); + + bool is_equal(const char * str) const; + bool is_equal(const wchar_t * str) const; + + bool is_equal(const std::string & str) const; + bool is_equal(const std::wstring & str) const; + + void serialize_to(pt::WTextStream & str); + + + Var & operator<<(const char * str); + Var & operator<<(const wchar_t * str); + Var & operator<<(const std::string & str); + Var & operator<<(const std::wstring & str); + // add the rest of << operators... + + + 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; + + +private: + + bool to_bool_str() const; + + bool is_equal_bool(const char * str) const; + bool is_equal_string(const char * str) const; + + bool is_equal_bool(const wchar_t * str) const; + bool is_equal_string(const wchar_t * str) const; + + + + /* + * old + */ + + + /* + * if true then means 'str' is a function name and should be called (res is ignored) + * + * if false then means 'str' is a string value and res is a boolean value + */ + //bool is_function; + + //std::wstring str; // a string value + //bool res; // a boolean value + +}; + + + +} + +#endif +