added: FunInfo<>::fun_data
now we have a pointer to FunData struct by default the pointer is null you can create an object of a class derived from FunData an set the pointer to the object those pointers will be kept on the [for] stack and will be auto removed (not finished yet -- need some testing) added: to FunInfo<>:: bool is_if; bool is_is; bool is_normal; bool is_filter; removed: from FunInfo<>: bool is_for_first_iter; changed: in FunInfo<>: int iter -> size_t iter now it indicates the number of a current iteration for the [for] statement for other statements than [for] this is always zero (the same old behaviour as before revision 331) added: in FunInfo<>: size_t last_iter it indicates the number of a previous [for] iteration for a [for] it returns not the current iterator but a value from a previous [for] git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@391 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
4480268172
commit
8e85a398d6
|
@ -47,6 +47,19 @@
|
|||
namespace Ezc
|
||||
{
|
||||
|
||||
struct FunData
|
||||
{
|
||||
|
||||
|
||||
FunData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~FunData()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
struct FunInfo
|
||||
|
@ -75,21 +88,47 @@ struct FunInfo
|
|||
// indicates that this function is from [for ...] statement
|
||||
bool is_for;
|
||||
|
||||
// indicates that this function is from [for ...] statement
|
||||
// and this is a first iteration (iter=0 too)
|
||||
// this is only for convenience -- you don't have to check is_for and iter==0
|
||||
// !! may a better name?
|
||||
bool is_for_first_iter;
|
||||
// indicates that this function is from [if ...] statement
|
||||
// is true for all kind of if's: if-one, if-any, if-no....
|
||||
bool is_if;
|
||||
|
||||
// indicates that this function is from [is ...] or [is-no ...] statements
|
||||
bool is_is;
|
||||
|
||||
// indicates that this funcion is a normal statement e.g.: [funcion_name]
|
||||
bool is_normal;
|
||||
|
||||
// indicates that this function is from a filter statement [filter ...]
|
||||
bool is_filter;
|
||||
|
||||
// a pointer to FunData struct
|
||||
// !! IMPROVE ME
|
||||
// !! give some info here
|
||||
// can be null
|
||||
FunData * fun_data;
|
||||
|
||||
|
||||
|
||||
FunData * last_fun_data;
|
||||
|
||||
|
||||
// this is set by Generator
|
||||
// it indicates the number of a current iteration in the last [for] statement (the first is 0)
|
||||
// it indicates the number of a current iteration for the [for] statement (the first iteration is 0)
|
||||
// if there was not any [for] before the value is zero
|
||||
int iter;
|
||||
// for other statements than [for] this is always zero
|
||||
size_t iter;
|
||||
|
||||
// this is set by Generator
|
||||
// it indicates the number of a previous [for] iteration
|
||||
// if there was not any [for] before the value is zero
|
||||
// for a [for] it returns not the current iterator but a value from a previous [for]
|
||||
size_t last_iter;
|
||||
|
||||
// return value from a user function (default false if not set directly by the user function)
|
||||
// for a variable it is set to true if the variable is not empty
|
||||
bool res;
|
||||
|
||||
|
||||
// arguments: output_stream, table_of_parameters, the_first_parameter
|
||||
FunInfo(StreamType & o,
|
||||
std::vector<std::wstring> & pars,
|
||||
|
@ -99,13 +138,20 @@ struct FunInfo
|
|||
Clear();
|
||||
}
|
||||
|
||||
|
||||
void Clear()
|
||||
{
|
||||
res = false; // result is false by default
|
||||
is_for = false;
|
||||
is_for_first_iter = false;
|
||||
is_if = false;
|
||||
is_is = false;
|
||||
is_normal = false;
|
||||
is_filter = false;
|
||||
iter = 0;
|
||||
last_iter = 0;
|
||||
case_sensitive = true;
|
||||
fun_data = 0;
|
||||
last_fun_data = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
122
src/generator.h
122
src/generator.h
|
@ -63,7 +63,7 @@ public:
|
|||
~Generator();
|
||||
|
||||
|
||||
void SetMax(int max_items_, int max_for_items_);
|
||||
void SetMax(size_t max_items_, size_t max_for_items_);
|
||||
|
||||
// recognizing some special characters in text patterns (item_text in Patterns)
|
||||
// \r will be a carriage return (13)
|
||||
|
@ -106,9 +106,9 @@ private:
|
|||
std::wstring temp_msg;
|
||||
|
||||
bool break_generating;
|
||||
int current_item;
|
||||
int max_items;
|
||||
int max_for_items;
|
||||
size_t current_item;
|
||||
size_t max_items;
|
||||
size_t max_for_items;
|
||||
bool special_chars;
|
||||
bool trim_white;
|
||||
bool skip_new_line;
|
||||
|
@ -132,8 +132,12 @@ private:
|
|||
// true if this Generator is working now
|
||||
bool is_generator_working;
|
||||
|
||||
// true if the Generator is working with [for ...] statement
|
||||
// true if the Generator is working with [for ...], [if ...] etc.
|
||||
bool is_generating_for;
|
||||
bool is_generating_if;
|
||||
bool is_generating_is;
|
||||
bool is_generating_normal;
|
||||
bool is_generating_filter;
|
||||
|
||||
// an empty string for FunInfo objects
|
||||
// when there is no any parameters
|
||||
|
@ -143,7 +147,14 @@ private:
|
|||
// currently only one item (iterator)
|
||||
struct StackItem
|
||||
{
|
||||
int iter;
|
||||
size_t iter;
|
||||
FunData * fun_data;
|
||||
|
||||
StackItem()
|
||||
{
|
||||
iter = 0;
|
||||
fun_data = 0;
|
||||
}
|
||||
};
|
||||
|
||||
// a stack for [for] statements
|
||||
|
@ -152,6 +163,7 @@ private:
|
|||
|
||||
void ResizeFilterTab();
|
||||
void ClearFilterTab();
|
||||
void ClearForStack();
|
||||
void ClearStream(StreamType & str);
|
||||
|
||||
template<class CharType>
|
||||
|
@ -179,7 +191,7 @@ private:
|
|||
void PrintNormalText(const wchar_t * start, const wchar_t * end);
|
||||
void TrimWhite(const wchar_t *& start, const wchar_t *& end);
|
||||
void SkipWhite(const wchar_t *& str);
|
||||
int StrToInt(const wchar_t * str, const wchar_t ** str_end);
|
||||
size_t StrToSize(const wchar_t * str, const wchar_t ** str_end);
|
||||
|
||||
void CreateMsg(StreamType & out, const wchar_t * type, const wchar_t * arg = 0);
|
||||
void CreateMsg(const wchar_t * type, const wchar_t * arg = 0);
|
||||
|
@ -257,7 +269,10 @@ Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamT
|
|||
skip_new_line = n.skip_new_line;
|
||||
|
||||
// don't copy filter tab
|
||||
filter_tab.clear();
|
||||
ClearFilterTab();
|
||||
|
||||
// don't copy [for] stack
|
||||
ClearForStack();
|
||||
|
||||
// don't copy 'is_generator_working' flag
|
||||
is_generator_working = false;
|
||||
|
@ -271,6 +286,7 @@ template<class StreamType>
|
|||
Generator<StreamType>::~Generator()
|
||||
{
|
||||
ClearFilterTab();
|
||||
ClearForStack();
|
||||
}
|
||||
|
||||
|
||||
|
@ -305,6 +321,16 @@ void Generator<StreamType>::ClearFilterTab()
|
|||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::ClearForStack()
|
||||
{
|
||||
for(size_t i=0 ; i<stack_tab.size() ; ++i)
|
||||
delete stack_tab[i].fun_data;
|
||||
|
||||
stack_tab.clear();
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::ClearStream(StreamType & str)
|
||||
{
|
||||
|
@ -362,7 +388,7 @@ bool Generator<StreamType>::AreStreamsEqual(StreamType & str1, StreamType & str2
|
|||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::SetMax(int max_items_, int max_for_items_)
|
||||
void Generator<StreamType>::SetMax(size_t max_items_, size_t max_for_items_)
|
||||
{
|
||||
max_items = max_items_;
|
||||
max_for_items = max_for_items_;
|
||||
|
@ -415,7 +441,7 @@ void Generator<StreamType>::Generate(StreamType * o, Pattern * p, Functions<Stre
|
|||
|
||||
break_generating = false;
|
||||
current_item = 0;
|
||||
stack_tab.clear();
|
||||
ClearForStack();
|
||||
ResizeFilterTab();
|
||||
filter_index = 0;
|
||||
|
||||
|
@ -490,13 +516,31 @@ void Generator<StreamType>::Call(typename Functions<StreamType>::Function * func
|
|||
{
|
||||
info.Clear();
|
||||
|
||||
if( stack_tab.empty() )
|
||||
info.iter = 0;
|
||||
else
|
||||
info.is_for = is_generating_for;
|
||||
info.is_if = is_generating_if;
|
||||
info.is_is = is_generating_is;
|
||||
info.is_normal = is_generating_normal;
|
||||
info.is_filter = is_generating_filter;
|
||||
|
||||
if( info.is_for )
|
||||
{
|
||||
if( !stack_tab.empty() )
|
||||
info.iter = stack_tab.back().iter;
|
||||
|
||||
info.is_for = is_generating_for;
|
||||
info.is_for_first_iter = (info.is_for && info.iter == 0);
|
||||
if( stack_tab.size() >= 2 )
|
||||
info.last_iter = stack_tab[stack_tab.size()-2].iter;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !stack_tab.empty() )
|
||||
info.last_iter = stack_tab.back().iter;
|
||||
}
|
||||
|
||||
if( !stack_tab.empty() )
|
||||
info.fun_data = stack_tab.back().fun_data;
|
||||
|
||||
if( stack_tab.size() >= 2 )
|
||||
info.last_fun_data = stack_tab[stack_tab.size()-2].fun_data;
|
||||
|
||||
if( function->type == Functions<StreamType>::function )
|
||||
{
|
||||
|
@ -508,6 +552,22 @@ void Generator<StreamType>::Call(typename Functions<StreamType>::Function * func
|
|||
info.res = !function->variable.empty();
|
||||
}
|
||||
|
||||
if( info.fun_data )
|
||||
{
|
||||
if( !stack_tab.empty() )
|
||||
{
|
||||
if( stack_tab.back().fun_data != info.fun_data )
|
||||
{
|
||||
delete stack_tab.back().fun_data;
|
||||
stack_tab.back().fun_data = info.fun_data;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delete info.fun_data;
|
||||
}
|
||||
}
|
||||
|
||||
last_res = info.res;
|
||||
last_case_sensitive = info.case_sensitive;
|
||||
}
|
||||
|
@ -699,12 +759,13 @@ void Generator<StreamType>::SkipWhite(const wchar_t *& str)
|
|||
|
||||
|
||||
template<class StreamType>
|
||||
int Generator<StreamType>::StrToInt(const wchar_t * str, const wchar_t ** str_end)
|
||||
size_t Generator<StreamType>::StrToSize(const wchar_t * str, const wchar_t ** str_end)
|
||||
{
|
||||
int res = 0;
|
||||
size_t res = 0;
|
||||
|
||||
SkipWhite(str);
|
||||
|
||||
// !! IMPROVE ME
|
||||
// overflow is not checked
|
||||
|
||||
while( *str>='0' && *str<='9' )
|
||||
|
@ -797,6 +858,7 @@ void Generator<StreamType>::MakeTextNormal(Item & item)
|
|||
if( item.functions.size() != 1 )
|
||||
return;
|
||||
|
||||
is_generating_normal = true;
|
||||
Call(item.functions[0], *output_stream, false);
|
||||
}
|
||||
|
||||
|
@ -826,6 +888,8 @@ void Generator<StreamType>::MakeTextIf(Item & item)
|
|||
if( item.functions.size() != 1 )
|
||||
return;
|
||||
|
||||
is_generating_if = true;
|
||||
|
||||
if( !Call(item.functions[0]) )
|
||||
return;
|
||||
|
||||
|
@ -839,6 +903,8 @@ void Generator<StreamType>::MakeTextIfno(Item & item)
|
|||
if( item.functions.size() != 1 )
|
||||
return;
|
||||
|
||||
is_generating_if = true;
|
||||
|
||||
if( !Call(item.functions[0]) )
|
||||
return;
|
||||
|
||||
|
@ -852,6 +918,8 @@ void Generator<StreamType>::MakeTextIfany(Item & item)
|
|||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_true = 0;
|
||||
|
||||
is_generating_if = true;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( !Call(*d) )
|
||||
|
@ -871,6 +939,8 @@ void Generator<StreamType>::MakeTextIfone(Item & item)
|
|||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_true = 0;
|
||||
|
||||
is_generating_if = true;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( Call(*d) )
|
||||
|
@ -893,6 +963,8 @@ void Generator<StreamType>::MakeTextIfanyno(Item & item)
|
|||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_true = 0;
|
||||
|
||||
is_generating_if = true;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( !Call(*d) )
|
||||
|
@ -912,6 +984,8 @@ void Generator<StreamType>::MakeTextIfoneno(Item & item)
|
|||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_false = 0;
|
||||
|
||||
is_generating_if = true;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( Call(*d) )
|
||||
|
@ -935,6 +1009,8 @@ void Generator<StreamType>::MakeTextIs(Item & item, bool equal)
|
|||
if( item.functions.size() != 2 )
|
||||
return;
|
||||
|
||||
is_generating_is = true;
|
||||
|
||||
// if one of these two functions has set case_sensitive to false
|
||||
// then we compare in case insensitive mode
|
||||
bool case_sensitive = true;
|
||||
|
@ -990,7 +1066,7 @@ bool Generator<StreamType>::MakeTextIfindexnumber(Item & item, bool & result)
|
|||
const wchar_t * number_text = item.functions[0].name.c_str();
|
||||
const wchar_t * last_char;
|
||||
|
||||
int number = StrToInt(number_text, &last_char);
|
||||
size_t number = StrToSize(number_text, &last_char);
|
||||
|
||||
if( *last_char != '\0' )
|
||||
{
|
||||
|
@ -1078,12 +1154,11 @@ void Generator<StreamType>::MakeTextFor(Item & item)
|
|||
if( !Find(item.functions[0], &function) )
|
||||
return;
|
||||
|
||||
StackItem s;
|
||||
s.iter = 0;
|
||||
stack_tab.push_back(s);
|
||||
stack_tab.push_back(StackItem());
|
||||
|
||||
MakeTextForLoop(item, function);
|
||||
|
||||
delete stack_tab.back().fun_data;
|
||||
stack_tab.erase(--stack_tab.end());
|
||||
}
|
||||
|
||||
|
@ -1154,6 +1229,7 @@ void Generator<StreamType>::MakeTextFilter(Item & item)
|
|||
if( !item.item_tab.empty() )
|
||||
MakeText( *item.item_tab[0] ); // should be only one item - item_container
|
||||
|
||||
is_generating_filter = true;
|
||||
Call(function, item.functions[0].params, *old_stream, false, *output_stream);
|
||||
|
||||
output_stream = old_stream;
|
||||
|
@ -1176,6 +1252,10 @@ void Generator<StreamType>::MakeText(Item & item)
|
|||
}
|
||||
|
||||
is_generating_for = false;
|
||||
is_generating_if = false;
|
||||
is_generating_is = false;
|
||||
is_generating_normal = false;
|
||||
is_generating_filter = false;
|
||||
|
||||
if ( item.type == Item::item_text ) MakeItemText(item);
|
||||
else if( item.type == Item::item_container )MakeTextContainer(item);
|
||||
|
|
Loading…
Reference in New Issue