add two new ezc statements: [if-def ...] and [if-not-def ...]

[if-def my_function] returns true if my_function is defined somewhere (either a model, model container, space, date, block, function or variable)
add support for "noescape" or "raw" parameters to Space fields
fixed: CallWrapper() didn't return a status if a model/space/date/container was found
This commit is contained in:
Tomasz Sowa 2021-07-02 20:23:20 +02:00
parent 849b3e9ecc
commit 995cccdace
5 changed files with 333 additions and 128 deletions

View File

@ -172,9 +172,14 @@ struct FunInfo
bool is_for;
// indicates that this function is from [if ...] statement
// it is true for all kind of if's: if-one, if-any, if-no....
bool is_if;
// indicates that this function is from [if-def ...] statement
bool is_if_def;
// indicates that this function is from [if-not-def ...] statement
bool is_if_not_def;
// indicates that this funcion is a normal statement e.g.: [funcion_name]
bool is_normal;
@ -221,6 +226,8 @@ struct FunInfo
res = false; // result is false by default
is_for = false;
is_if = false;
is_if_def = false;
is_if_not_def = false;
is_normal = false;
is_filter = false;
iter = 0;

View File

@ -242,6 +242,8 @@ private:
// true if the Generator is working with [for ...], [if ...] etc.
bool is_generating_for;
bool is_generating_if;
bool is_generating_if_def;
bool is_generating_if_not_def;
bool is_generating_normal;
bool is_generating_filter;
@ -259,7 +261,6 @@ private:
ExpressionParser * expression_parser;
void ResizeStreamStack(std::vector<StreamType*> & stream_tab, size_t stream_tab_max_size);
void ResizeFilterTab();
void ResizeStack();
@ -285,6 +286,7 @@ private:
template<class CharType>
CharType ToLower(CharType c);
bool IsTestingFunctionExistence();
bool CheckBlockArgument(int arg_index, FindHelper & find_helper);
@ -295,11 +297,11 @@ private:
#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(FunInfo<StreamType> & info);
void CallFunction(typename Functions<StreamType>::UserFunction & function, FunInfo<StreamType> & info);
void CallFunction(typename Functions<StreamType>::UserFunction & function,
@ -316,8 +318,10 @@ private:
void PrintDate(pt::Date * date, std::vector<Var> parameters, StreamType & out_stream);
bool PrintDatePart(pt::Date * date, const std::wstring & field, std::vector<Var> parameters, StreamType & out_stream);
void CallSpaceObjectForLastField(std::vector<Var> & parameters, StreamType & out_stream, pt::Space * space);
bool CallDate(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream);
void PrintLastSpaceField(pt::Space * space, std::vector<Var> & parameters, StreamType & out_stream);
void CallSpaceObjectForLastField(std::vector<Var> & parameters, StreamType & out_stream, pt::Space * space);
pt::Space * CallSpaceObjectForMiddleField(std::wstring & root_space_name, std::vector<std::wstring> & fields, size_t field_index, pt::Space * space);
void CallSpaceTableForLastField(morm::SpaceWrapper & space_wrapper, std::vector<Var> & parameters, StreamType & out_stream,
@ -326,13 +330,13 @@ private:
pt::Space * CallSpaceTableForMiddleField(morm::SpaceWrapper & space_wrapper, std::wstring & root_space_name, std::vector<std::wstring> & fields,
size_t field_index, pt::Space * space, size_t model_wrapper_space_table_index);
void CallSpace(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> & parameters, StreamType & out_stream);
bool CallSpace(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> & parameters, StreamType & out_stream);
#ifdef EZC_HAS_MORM_LIBRARY
bool CallModelField(morm::Model & model, const std::wstring & field, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream);
void CallModel(morm::Model & model, FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream);
bool CallModel(morm::Model & model, FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream);
void FindLastModelWrapper(FindHelper & find_helper, std::vector<std::wstring> & fields);
void CallWrapper(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream);
bool CallWrapper(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream);
#endif
void CallObject(BaseObj<StreamType> & base_obj,
@ -392,6 +396,8 @@ private:
void MakeTextIf_go(Item & item, bool result);
void MakeTextIf(Item & item);
void MakeTextIfDef(Item & item);
void MakeTextIfNotDef(Item & item);
void MakeTextFor(Item & item);
void MakeItemText(Item & item);
void MakeTextContainer(Item & item);
@ -677,8 +683,6 @@ void Generator<StreamType>::ResizeBlockStack()
template<class StreamType>
void Generator<StreamType>::ClearStreamStack(std::vector<StreamType*> & stream_tab)
{
@ -956,6 +960,12 @@ void Generator<StreamType>::Generate(OutStreams<StreamType> & out_streams)
}
template<class StreamType>
bool Generator<StreamType>::IsTestingFunctionExistence()
{
return is_generating_if_def || is_generating_if_not_def;
}
template<class StreamType>
bool Generator<StreamType>::CheckBlockArgument(int arg_index, FindHelper & find_helper)
@ -1102,7 +1112,7 @@ bool Generator<StreamType>::Find(Item::Function & item_fun, FindHelper & find_he
if( FindInModels(find_helper) )
return true;
if( !item_fun.fields.empty() )
if( !item_fun.fields.empty() && !IsTestingFunctionExistence() )
{
CreateMsg(L"unknown model", find_helper.fun_name->c_str());
return false;
@ -1122,27 +1132,36 @@ bool Generator<StreamType>::Find(Item::Function & item_fun, FindHelper & find_he
if( FindInVariables(*find_helper.fun_name, find_helper) )
return true;
CreateMsg(L"unknown function", find_helper.fun_name->c_str());
if( !IsTestingFunctionExistence() )
CreateMsg(L"unknown function", find_helper.fun_name->c_str());
return false;
}
template<class StreamType>
void Generator<StreamType>::PrepareEnvStruct(FunInfo<StreamType> & info)
{
info.Clear();
info.is_for = is_generating_for;
info.is_if = is_generating_if;
info.is_if_def = is_generating_if_def;
info.is_if_not_def = is_generating_if_not_def;
info.is_normal = is_generating_normal;
info.is_filter = is_generating_filter;
info.iter = info.stack.iter;
info.stack_tab = stack_tab.data();
info.stack_index = stack_index-1;
}
template<class StreamType>
void Generator<StreamType>::CallFunction(typename Functions<StreamType>::UserFunction & function, FunInfo<StreamType> & info)
{
info.Clear();
info.is_for = is_generating_for;
info.is_if = is_generating_if;
info.is_normal = is_generating_normal;
info.is_filter = is_generating_filter;
info.iter = info.stack.iter;
info.stack_tab = stack_tab.data();
info.stack_index = stack_index-1;
PrepareEnvStruct(info);
(function)(info);
last_res = info.res;
}
@ -1154,39 +1173,29 @@ void Generator<StreamType>::CallFunction(typename Functions<StreamType>::UserFun
StreamType & out_stream,
const StreamType & in_stream)
{
if( parameters.empty() )
if( !IsTestingFunctionExistence() )
{
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(function, info);
}
else
{
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(function, info);
if( parameters.empty() )
{
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(function, info);
}
else
{
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallFunction(function, info);
}
}
}
template<class StreamType>
void Generator<StreamType>::CallObject(BaseObj<StreamType> & base_obj, int method_index, FunInfo<StreamType> & info)
{
info.Clear();
info.is_for = is_generating_for;
info.is_if = is_generating_if;
info.is_normal = is_generating_normal;
info.is_filter = is_generating_filter;
info.iter = info.stack.iter;
info.stack_tab = stack_tab.data();
info.stack_index = stack_index-1;
PrepareEnvStruct(info);
base_obj.CallFun(method_index, info);
last_res = info.res;
}
@ -1306,35 +1315,100 @@ void Generator<StreamType>::PrintDate(pt::Date * date, std::vector<Var> paramete
template<class StreamType>
bool Generator<StreamType>::PrintDatePart(pt::Date * date, const std::wstring & field, std::vector<Var> parameters, StreamType & out_stream)
{
bool is_test = IsTestingFunctionExistence();
if( field == L"year" )
out_stream << date->year;
{
if( !is_test )
out_stream << date->year;
}
else
if( field == L"month" )
out_stream << date->month;
{
if( !is_test )
out_stream << date->month;
}
else
if( field == L"day" )
out_stream << date->day;
{
if( !is_test )
out_stream << date->day;
}
else
if( field == L"hour" )
out_stream << date->hour;
{
if( !is_test )
out_stream << date->hour;
}
else
if( field == L"min" )
out_stream << date->min;
{
if( !is_test )
out_stream << date->min;
}
else
if( field == L"sec" )
out_stream << date->sec;
{
if( !is_test )
out_stream << date->sec;
}
else
{
return false;
}
return true;
}
template<class StreamType>
bool Generator<StreamType>::CallDate(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream)
{
bool found = true;
bool all_fields_known = (find_helper.field_index == fields.size());
bool last_field_not_known = (find_helper.field_index + 1 == fields.size());
if( all_fields_known )
{
PrintDate(find_helper.wrapper->date, parameters, out_stream);
}
else
if( last_field_not_known )
{
if( !PrintDatePart(find_helper.wrapper->date, fields[find_helper.field_index], parameters, out_stream) )
{
if( !IsTestingFunctionExistence() )
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", unknown property ", fields[find_helper.field_index].c_str(), L" of date object");
}
found = false;
}
}
else
{
if( !IsTestingFunctionExistence() )
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", ", fields[find_helper.field_index].c_str(), L" is not a model nor a model container nor a space");
}
found = false;
}
return found;
}
template<class StreamType>
void Generator<StreamType>::CallSpaceObjectForLastField(std::vector<Var> & parameters, StreamType & out_stream, pt::Space * space)
{
// CHECKME should we convert the last value to last_res?
DumpSpaceIfNeeded(parameters, out_stream, space);
if( !IsTestingFunctionExistence() )
{
// CHECKME should we convert the last value to last_res?
DumpSpaceIfNeeded(parameters, out_stream, space);
}
}
@ -1344,7 +1418,7 @@ pt::Space * Generator<StreamType>::CallSpaceObjectForMiddleField(std::wstring &
std::wstring & next_field = fields[field_index];
space = space->get_space(next_field);
if( !space )
if( !space && !IsTestingFunctionExistence() )
{
CreateMsg(L"cannot find space field: ", root_space_name, fields, field_index + 1);
}
@ -1360,7 +1434,7 @@ void Generator<StreamType>::CallSpaceTableForLastField(morm::SpaceWrapper & spac
{
pt::Space::TableType * table = space->get_table();
if( stack_tab[stack_index-1].is_for )
if( is_generating_for )
{
// we are in [for...]statement, increment iterator and check the range
space_wrapper.increment_iterator(model_wrapper_space_table_index, table->size());
@ -1370,23 +1444,27 @@ void Generator<StreamType>::CallSpaceTableForLastField(morm::SpaceWrapper & spac
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();
}
DumpSpaceIfNeeded(parameters, out_stream, space);
if( IsCurrentParam(parameters) )
if( !IsTestingFunctionExistence() )
{
size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index);
DumpSpaceIfNeeded(parameters, out_stream, space);
if( iterator_value < table->size() )
if( IsCurrentParam(parameters) )
{
(*table)[iterator_value]->serialize_to_string(out_stream);
size_t iterator_value = space_wrapper.get_space_iterator_value(model_wrapper_space_table_index);
if( iterator_value < table->size() )
{
(*table)[iterator_value]->serialize_to_string(out_stream);
}
}
}
}
template<class StreamType>
pt::Space * Generator<StreamType>::CallSpaceTableForMiddleField(morm::SpaceWrapper & space_wrapper, std::wstring & root_space_name, std::vector<std::wstring> & fields,
size_t field_index, pt::Space * space, size_t model_wrapper_space_table_index)
@ -1402,6 +1480,7 @@ pt::Space * Generator<StreamType>::CallSpaceTableForMiddleField(morm::SpaceWrapp
}
else
{
// this message can be print even for [if-def...]
CreateMsg(L"space table: ", root_space_name, fields, field_index, L" is not initialized, have you forgotten to use [for...] statement?");
space = nullptr;
}
@ -1411,7 +1490,26 @@ pt::Space * Generator<StreamType>::CallSpaceTableForMiddleField(morm::SpaceWrapp
template<class StreamType>
void Generator<StreamType>::CallSpace(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> & parameters, StreamType & out_stream)
void Generator<StreamType>::PrintLastSpaceField(pt::Space * space, std::vector<Var> & parameters, StreamType & out_stream)
{
bool no_escape = HasParam(parameters, L"raw", L"noescape");
if( no_escape )
{
pt::WTextStream str;
space->serialize_to_string(str);
CopyStream(str, out_stream, false);
}
else
{
space->serialize_to_string(out_stream);
}
}
template<class StreamType>
bool Generator<StreamType>::CallSpace(FindHelper & find_helper, std::vector<std::wstring> & fields, std::vector<Var> & parameters, StreamType & out_stream)
{
morm::SpaceWrapper * space_wrapper = find_helper.wrapper->space_wrapper;
pt::Space * space = space_wrapper->get_space();
@ -1463,23 +1561,33 @@ void Generator<StreamType>::CallSpace(FindHelper & find_helper, std::vector<std:
else
{
CreateMsg(L"", *find_helper.fun_name, fields, field_index, L" exceeded the maximum number of fields for a space object");
break;
space = nullptr;
}
}
else
{
if( is_last_field )
{
space->serialize_to_string(out_stream);
if( !IsTestingFunctionExistence() )
{
PrintLastSpaceField(space, parameters, out_stream);
}
field_index += 1;
}
else
{
CreateMsg(L"", *find_helper.fun_name, fields, field_index, L" is not a model, model container nor a space");
break;
if( !IsTestingFunctionExistence() )
{
CreateMsg(L"", *find_helper.fun_name, fields, field_index, L" of a space is not an object nor a table");
}
space = nullptr;
}
}
}
return space != nullptr;
}
@ -1513,8 +1621,8 @@ bool Generator<StreamType>::CallModelField(morm::Model & model, const std::wstri
if( found && !str.empty())
{
bool should_escape = HasParam(parameters, L"raw", L"noescape");
CopyStream(str, out_stream, should_escape);
bool no_escape = HasParam(parameters, L"raw", L"noescape");
CopyStream(str, out_stream, !no_escape);
}
return found;
@ -1522,13 +1630,18 @@ bool Generator<StreamType>::CallModelField(morm::Model & model, const std::wstri
template<class StreamType>
void Generator<StreamType>::CallModel(morm::Model & model, FindHelper & find_helper, std::vector<std::wstring> & fields,
std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream)
bool Generator<StreamType>::CallModel(morm::Model & model, FindHelper & find_helper, std::vector<std::wstring> & fields,
std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream)
{
bool found = true;
if( find_helper.field_index == fields.size() )
{
// all fields items are models or models containers
DumpModelIfNeeded(model, parameters, out_stream);
if( !IsTestingFunctionExistence() )
{
DumpModelIfNeeded(model, parameters, out_stream);
}
}
else
if( find_helper.field_index + 1 == fields.size() )
@ -1536,13 +1649,25 @@ void Generator<StreamType>::CallModel(morm::Model & model, FindHelper & find_hel
// last field is not a model nor a models container
if( !CallModelField(model, fields[find_helper.field_index], parameters, out_stream, in_stream) )
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", unknown property ", fields[find_helper.field_index].c_str(), L" of a model object");
if( !IsTestingFunctionExistence() )
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", unknown property ", fields[find_helper.field_index].c_str(), L" of a model object");
}
found = false;
}
}
else
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", ", fields[find_helper.field_index].c_str(), L" is not a model nor a model container nor a space");
if( !IsTestingFunctionExistence() )
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", ", fields[find_helper.field_index].c_str(), L" is not a model nor a model container nor a space");
}
found = false;
}
return found;
}
@ -1590,9 +1715,10 @@ void Generator<StreamType>::FindLastModelWrapper(FindHelper & find_helper, std::
template<class StreamType>
void Generator<StreamType>::CallWrapper(FindHelper & find_helper, std::vector<std::wstring> & fields,
bool Generator<StreamType>::CallWrapper(FindHelper & find_helper, std::vector<std::wstring> & fields,
std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream)
{
bool found = true;
last_res = false;
FindLastModelWrapper(find_helper, fields);
@ -1606,33 +1732,17 @@ void Generator<StreamType>::CallWrapper(FindHelper & find_helper, std::vector<st
if( find_helper.wrapper->space_wrapper )
{
CallSpace(find_helper, fields, parameters, out_stream);
found = CallSpace(find_helper, fields, parameters, out_stream);
}
if( find_helper.wrapper->date )
{
if( all_fields_known )
{
PrintDate(find_helper.wrapper->date, parameters, out_stream);
}
else
if( last_field_not_known )
{
// last field is not a model nor a models container
if( !PrintDatePart(find_helper.wrapper->date, fields[find_helper.field_index], parameters, out_stream) )
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", unknown property ", fields[find_helper.field_index].c_str(), L" of date object");
}
}
else
{
CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", ", fields[find_helper.field_index].c_str(), L" is not a model nor a model container nor a space");
}
found = CallDate(find_helper, fields, parameters, out_stream);
}
if( find_helper.wrapper->model )
{
CallModel(*find_helper.wrapper->model, find_helper, fields, parameters, out_stream, in_stream);
found = CallModel(*find_helper.wrapper->model, find_helper, fields, parameters, out_stream, in_stream);
}
if( find_helper.wrapper->model_container_wrapper )
@ -1641,19 +1751,21 @@ void Generator<StreamType>::CallWrapper(FindHelper & find_helper, std::vector<st
if( model )
{
CallModel(*model, find_helper, fields, parameters, out_stream, in_stream);
found = CallModel(*model, find_helper, fields, parameters, out_stream, in_stream);
}
else
{
if( last_field_not_known )
{
// can be printed even for [if-def...]
CreateMsg(L"model ", *find_helper.fun_name, fields, L" is not initialized, have you forgotten to use [for ...] statement?");
found = false;
}
}
if( all_fields_known )
{
if( stack_tab[stack_index-1].is_for )
if( is_generating_for )
{
find_helper.wrapper->model_container_wrapper->increment_iterator();
find_helper.wrapper->clear_childs();
@ -1661,10 +1773,13 @@ void Generator<StreamType>::CallWrapper(FindHelper & find_helper, std::vector<st
}
else
{
// for [if-def...] last_res will be set later
last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty();
}
}
}
return found;
}
#endif
@ -1678,15 +1793,18 @@ void Generator<StreamType>::CallObject(BaseObj<StreamType> & base_obj,
StreamType & out_stream,
const StreamType & in_stream)
{
if( parameters.empty() )
if( !IsTestingFunctionExistence() )
{
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallObject(base_obj, method_index, info);
}
else
{
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallObject(base_obj, method_index, info);
if( parameters.empty() )
{
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallObject(base_obj, method_index, info);
}
else
{
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
CallObject(base_obj, method_index, info);
}
}
}
@ -1703,24 +1821,27 @@ bool Generator<StreamType>::CallBlock(Item & item_block,
return false;
}
StreamType * old_stream = output_stream;
BlockStack & block_stack = block_stack_tab[block_stack_index];
if( !IsTestingFunctionExistence() )
{
StreamType * old_stream = output_stream;
BlockStack & block_stack = block_stack_tab[block_stack_index];
block_stack.was_return = false;
block_stack.args = parameters;
block_stack.was_return = false;
block_stack.args = parameters;
output_stream = block_stack.out_stream;
ClearStream(*output_stream);
block_stack_index += 1;
output_stream = block_stack.out_stream;
ClearStream(*output_stream);
block_stack_index += 1;
MakeText(item_block);
MakeText(item_block);
CopyStream(*output_stream, out_stream);
// last_res is set by [return ...] statement or other last evaluated function
CopyStream(*output_stream, out_stream);
// last_res is set by [return ...] statement or other last evaluated function
ClearStream(*output_stream);
output_stream = old_stream;
block_stack_index -= 1;
ClearStream(*output_stream);
output_stream = old_stream;
block_stack_index -= 1;
}
return true;
}
@ -1736,8 +1857,12 @@ bool Generator<StreamType>::CallVariable(Item::Function & item_fun, Var & variab
}
else
{
out_stream << variable.str;
last_res = variable.res;
if( !IsTestingFunctionExistence() )
{
out_stream << variable.str;
last_res = variable.res;
}
return true;
}
}
@ -1793,7 +1918,7 @@ std::vector<Var> parameters;
#ifdef EZC_HAS_MORM_LIBRARY
if( find_helper.wrapper )
CallWrapper(find_helper, item_fun.fields, parameters, out_stream, in_stream);
return CallWrapper(find_helper, item_fun.fields, parameters, out_stream, in_stream);
else
#endif
if( find_helper.base_obj )
@ -2250,6 +2375,42 @@ void Generator<StreamType>::MakeTextIf(Item & item)
}
template<class StreamType>
void Generator<StreamType>::MakeTextIfDef(Item & item)
{
is_generating_if_def = true;
if( program_mode )
{
//CHECKME
//EvaluateProgramNode(item);
}
else
{
last_res = Call(item.function);
}
MakeTextIf_go(item, last_res);
}
template<class StreamType>
void Generator<StreamType>::MakeTextIfNotDef(Item & item)
{
is_generating_if_not_def = true;
if( program_mode )
{
//CHECKME
//EvaluateProgramNode(item);
}
else
{
last_res = !Call(item.function);
}
MakeTextIf_go(item, last_res);
}
template<class StreamType>
@ -2598,12 +2759,14 @@ void Generator<StreamType>::MakeText(Item & item)
if( LimitAchieved() )
return;
current_item += 1;
stack_index += 1;
is_generating_for = false;
is_generating_if = false;
is_generating_normal = false;
is_generating_filter = false;
current_item += 1;
stack_index += 1;
is_generating_for = false;
is_generating_if = false;
is_generating_if_def = false;
is_generating_if_not_def = false;
is_generating_normal = false;
is_generating_filter = false;
stack_tab[stack_index-1].Clear();
stack_tab[stack_index-1].item = &item;
@ -2612,6 +2775,8 @@ void Generator<StreamType>::MakeText(Item & item)
else if( item.type == Item::item_container ) MakeTextContainer(item);
else if( item.type == Item::item_function ) MakeTextFunction(item);
else if( item.type == Item::item_if ) MakeTextIf(item);
else if( item.type == Item::item_if_def ) MakeTextIfDef(item);
else if( item.type == Item::item_if_not_def ) MakeTextIfNotDef(item);
else if( item.type == Item::item_def ) MakeTextDefine(item);
else if( item.type == Item::item_def_if_not_set ) MakeTextDefineIfNotSet(item);
else if( item.type == Item::item_let ) MakeTextLet(item);

View File

@ -53,7 +53,7 @@ struct Item
{
enum Type
{
item_none, item_container, item_text, item_function, item_if,
item_none, item_container, item_text, item_function, item_if, item_if_def, item_if_not_def,
item_for, item_else, item_end, item_err, item_include, item_comment,
item_def, item_def_if_not_set, item_let, item_let_if_not_set,
item_filter, item_ezc, item_block, item_return

View File

@ -745,6 +745,35 @@ void PatternParser::ReadDirectiveIf(Item & item)
}
void PatternParser::ReadDirectiveIfDef(Item & item)
{
item.type = Item::item_if_def;
if( ReadFunction(item) )
{
if( !item.function.is_function || item.function.parameters.size() > 0 )
{
item.type = Item::item_err;
item.function.Clear();
}
}
}
void PatternParser::ReadDirectiveIfNotDef(Item & item)
{
item.type = Item::item_if_not_def;
if( ReadFunction(item) )
{
if( !item.function.is_function || item.function.parameters.size() > 0 )
{
item.type = Item::item_err;
item.function.Clear();
}
}
}
void PatternParser::ReadDirectiveEnd(Item & item)
{
@ -991,6 +1020,8 @@ std::wstring name;
ReadName(name);
if ( name == L"if" ) ReadDirectiveIf(item);
else if( name == L"if-def" ) ReadDirectiveIfDef(item);
else if( name == L"if-not-def" )ReadDirectiveIfNotDef(item);
else if( name == L"end" ) ReadDirectiveEnd(item);
else if( name == L"else" ) ReadDirectiveElse(item);
else if( name == L"for" ) ReadDirectiveFor(item);
@ -1325,7 +1356,7 @@ bool PatternParser::CreateTree(Item & item)
if( item.type == Item::item_container )
CreateTreeContainer(item);
if( item.type == Item::item_if )
if( item.type == Item::item_if || item.type == Item::item_if_def || item.type == Item::item_if_not_def )
CreateTreeReadIf(item); // reads one child or two if [else] statement is present
if( item.type == Item::item_for ||

View File

@ -176,6 +176,8 @@ private:
bool ReadFunction(Item & item);
void ReadDirectiveIf(Item & item);
void ReadDirectiveIfDef(Item & item);
void ReadDirectiveIfNotDef(Item & item);
void ReadDirectiveEnd(Item & item);
void ReadDirectiveElse(Item & item);
void ReadDirectiveFor(Item & item);