added filters:
a new statement [filter] syntax: [filter funcion_name]....[end] everything which is between [filter] and [end] is processed normally and at the end it is passed to the function (function_name) FunInfo struct has 'in' input stream now git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@333 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
3c85fa1a75
commit
542e50d757
|
@ -59,14 +59,11 @@ public:
|
||||||
|
|
||||||
struct Function
|
struct Function
|
||||||
{
|
{
|
||||||
Type type;
|
Function();
|
||||||
|
|
||||||
|
Type type;
|
||||||
UserFunction user_function; // used when type is 'function'
|
UserFunction user_function; // used when type is 'function'
|
||||||
std::wstring variable; // used when type is 'variable'
|
std::wstring variable; // used when type is 'variable'
|
||||||
|
|
||||||
bool is_running; // true if this function is currently executed
|
|
||||||
|
|
||||||
Function();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -101,7 +98,6 @@ Functions<StreamType>::Function::Function()
|
||||||
{
|
{
|
||||||
type = Functions::variable;
|
type = Functions::variable;
|
||||||
user_function = 0;
|
user_function = 0;
|
||||||
is_running = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,10 @@ struct FunInfo
|
||||||
// in such a way the reference points to an empty string
|
// 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
|
||||||
|
const StreamType & in;
|
||||||
|
|
||||||
// this is set by Generator
|
// 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 in the last [for] statement (the first is 0)
|
||||||
// if there was not any [for] before the value is zero
|
// if there was not any [for] before the value is zero
|
||||||
|
@ -73,7 +77,10 @@ struct FunInfo
|
||||||
bool res;
|
bool res;
|
||||||
|
|
||||||
// arguments: output_stream, table_of_parameters, the_first_parameter
|
// arguments: output_stream, table_of_parameters, the_first_parameter
|
||||||
FunInfo(StreamType & o, std::vector<std::wstring> & pars, const std::wstring & p) : out(o), params(pars), par(p)
|
FunInfo(StreamType & o,
|
||||||
|
std::vector<std::wstring> & pars,
|
||||||
|
const std::wstring & first_par,
|
||||||
|
const StreamType & i) : out(o), params(pars), par(first_par), in(i)
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
329
src/generator.h
329
src/generator.h
|
@ -43,6 +43,8 @@
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
namespace Ezc
|
namespace Ezc
|
||||||
{
|
{
|
||||||
|
@ -56,6 +58,10 @@ class Generator
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Generator();
|
Generator();
|
||||||
|
Generator(const Generator & n);
|
||||||
|
Generator & operator=(const Generator & n);
|
||||||
|
~Generator();
|
||||||
|
|
||||||
|
|
||||||
void SetMax(int max_items_, int max_for_items_);
|
void SetMax(int max_items_, int max_for_items_);
|
||||||
|
|
||||||
|
@ -80,6 +86,9 @@ public:
|
||||||
// default: false
|
// default: false
|
||||||
void SkipNewLine(bool skip);
|
void SkipNewLine(bool skip);
|
||||||
|
|
||||||
|
// default: 20
|
||||||
|
void SetMaxFilters(size_t new_len);
|
||||||
|
|
||||||
// the main methods for generating
|
// the main methods for generating
|
||||||
void Generate(StreamType & o, Pattern & p, Functions<StreamType> & f);
|
void Generate(StreamType & o, Pattern & p, Functions<StreamType> & f);
|
||||||
|
|
||||||
|
@ -103,6 +112,17 @@ private:
|
||||||
bool special_chars;
|
bool special_chars;
|
||||||
bool trim_white;
|
bool trim_white;
|
||||||
bool skip_new_line;
|
bool skip_new_line;
|
||||||
|
|
||||||
|
size_t filter_index;
|
||||||
|
size_t filter_size;
|
||||||
|
// we have to use a pointers table because standard streams such
|
||||||
|
// as std::wostringstream are not copyable
|
||||||
|
std::vector<StreamType*> filter_tab;
|
||||||
|
const StreamType empty_stream;
|
||||||
|
|
||||||
|
|
||||||
|
bool is_used;
|
||||||
|
|
||||||
|
|
||||||
// an empty string for info objects
|
// an empty string for info objects
|
||||||
// when there is no any parameters
|
// when there is no any parameters
|
||||||
|
@ -119,15 +139,20 @@ private:
|
||||||
// a stack for 'for' statements
|
// a stack for 'for' statements
|
||||||
std::vector<StackItem> stack_tab;
|
std::vector<StackItem> stack_tab;
|
||||||
|
|
||||||
|
void ResizeFilterTab();
|
||||||
|
void ClearFilterTab();
|
||||||
|
void ClearStream(StreamType & str);
|
||||||
|
|
||||||
bool Find(const Item::Function & item_fun, typename Functions<StreamType>::Function ** function);
|
bool Find(const Item::Function & item_fun, typename Functions<StreamType>::Function ** function);
|
||||||
|
|
||||||
void Call(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info);
|
void Call(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info);
|
||||||
|
void Call(typename Functions<StreamType>::Function * function, std::vector<std::wstring> & params,
|
||||||
|
StreamType & out_stream, const StreamType & in_stream, bool * info_res = 0);
|
||||||
|
|
||||||
bool Call(Item::Function & function, bool * info_res = 0, typename Functions<StreamType>::Function ** pfun = 0);
|
bool Call(Item::Function & function, bool * info_res = 0, typename Functions<StreamType>::Function ** pfun = 0);
|
||||||
void Call(typename Functions<StreamType>::Function * function, std::vector<std::wstring> & params, bool * info_res = 0);
|
void Call(typename Functions<StreamType>::Function * function, std::vector<std::wstring> & params, bool * info_res = 0);
|
||||||
|
|
||||||
void CallUserFunction(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info);
|
|
||||||
void CallVariable(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info);
|
|
||||||
|
|
||||||
wchar_t CreateSpecialChar(wchar_t c);
|
wchar_t CreateSpecialChar(wchar_t c);
|
||||||
const wchar_t * PrintSpecialChar(const wchar_t * start, const wchar_t * end);
|
const wchar_t * PrintSpecialChar(const wchar_t * start, const wchar_t * end);
|
||||||
void PrintSpecialText(const wchar_t * start, const wchar_t * end);
|
void PrintSpecialText(const wchar_t * start, const wchar_t * end);
|
||||||
|
@ -136,6 +161,7 @@ private:
|
||||||
void SkipWhite(const wchar_t *& str);
|
void SkipWhite(const wchar_t *& str);
|
||||||
int StrToInt(const wchar_t * str, const wchar_t ** str_end);
|
int StrToInt(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);
|
void CreateMsg(const wchar_t * type, const wchar_t * arg = 0);
|
||||||
void CreateMsg(const std::wstring & type, const std::wstring & arg);
|
void CreateMsg(const std::wstring & type, const std::wstring & arg);
|
||||||
void CreateMsg(const std::wstring & type);
|
void CreateMsg(const std::wstring & type);
|
||||||
|
@ -158,8 +184,11 @@ private:
|
||||||
void MakeTextIs(Item & item);
|
void MakeTextIs(Item & item);
|
||||||
void MakeTextIsno(Item & item);
|
void MakeTextIsno(Item & item);
|
||||||
void MakeTextDefine(Item & item);
|
void MakeTextDefine(Item & item);
|
||||||
|
void MakeTextFilter(Item & item);
|
||||||
void MakeText(Item & item);
|
void MakeText(Item & item);
|
||||||
|
|
||||||
|
void Generate(StreamType * o, Pattern * p, Functions<StreamType> * f);
|
||||||
|
|
||||||
}; // class Generator
|
}; // class Generator
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,12 +205,94 @@ Generator<StreamType>::Generator()
|
||||||
|
|
||||||
max_items = 50000;
|
max_items = 50000;
|
||||||
max_for_items = 5000;
|
max_for_items = 5000;
|
||||||
|
filter_size = 20;
|
||||||
special_chars = false;
|
special_chars = false;
|
||||||
trim_white = false;
|
trim_white = false;
|
||||||
skip_new_line = false;
|
skip_new_line = false;
|
||||||
|
is_used = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
Generator<StreamType>::Generator(const Generator<StreamType> & n)
|
||||||
|
{
|
||||||
|
operator=(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamType> & n)
|
||||||
|
{
|
||||||
|
output_stream = n.output_stream;
|
||||||
|
pattern = n.pattern;
|
||||||
|
functions = n.functions;
|
||||||
|
|
||||||
|
max_items = n.max_items;
|
||||||
|
max_for_items = n.max_for_items;
|
||||||
|
filter_size = n.filter_size;
|
||||||
|
special_chars = n.special_chars;
|
||||||
|
trim_white = n.trim_white;
|
||||||
|
skip_new_line = n.skip_new_line;
|
||||||
|
|
||||||
|
// don't copy filter tab
|
||||||
|
filter_tab.clear();
|
||||||
|
|
||||||
|
// don't copy 'is_used' flag
|
||||||
|
is_used = false;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
Generator<StreamType>::~Generator()
|
||||||
|
{
|
||||||
|
ClearFilterTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::ResizeFilterTab()
|
||||||
|
{
|
||||||
|
if( filter_tab.size() != filter_size )
|
||||||
|
{
|
||||||
|
if( filter_tab.size() < filter_size )
|
||||||
|
{
|
||||||
|
for(size_t i=filter_tab.size() ; i<filter_size ; ++i)
|
||||||
|
filter_tab.push_back( new StreamType() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(size_t i=filter_size ; i<filter_tab.size() ; ++i)
|
||||||
|
delete filter_tab[i];
|
||||||
|
|
||||||
|
filter_tab.resize(filter_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::ClearFilterTab()
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i<filter_tab.size() ; ++i)
|
||||||
|
delete filter_tab[i];
|
||||||
|
|
||||||
|
filter_tab.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::ClearStream(StreamType & str)
|
||||||
|
{
|
||||||
|
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||||
|
str.Clear();
|
||||||
|
#else
|
||||||
|
str.str(L"");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
|
@ -214,30 +325,64 @@ void Generator<StreamType>::SkipNewLine(bool skip)
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::Generate(StreamType & o, Pattern & p, Functions<StreamType> & f)
|
void Generator<StreamType>::SetMaxFilters(size_t new_len)
|
||||||
{
|
{
|
||||||
output_stream = &o;
|
// the table will be resized when Generate() method is called
|
||||||
pattern = &p;
|
filter_size = new_len;
|
||||||
functions = &f;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::Generate(StreamType * o, Pattern * p, Functions<StreamType> * f)
|
||||||
|
{
|
||||||
|
if( is_used )
|
||||||
|
{
|
||||||
|
if( o )
|
||||||
|
CreateMsg(*o, L"generator busy");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
output_stream = o;
|
||||||
|
pattern = p;
|
||||||
|
functions = f;
|
||||||
|
|
||||||
break_generating = false;
|
break_generating = false;
|
||||||
current_item = 0;
|
current_item = 0;
|
||||||
|
stack_tab.clear();
|
||||||
|
ResizeFilterTab();
|
||||||
|
filter_index = 0;
|
||||||
|
|
||||||
MakeText( pattern->item_root );
|
if( output_stream && pattern )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
is_used = true;
|
||||||
|
MakeText( pattern->item_root );
|
||||||
|
is_used = false;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
is_used = false;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::Generate(StreamType & o, Pattern & p, Functions<StreamType> & f)
|
||||||
|
{
|
||||||
|
Generate(&o, &p, &f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::Generate(StreamType & o, Pattern & p)
|
void Generator<StreamType>::Generate(StreamType & o, Pattern & p)
|
||||||
{
|
{
|
||||||
output_stream = &o;
|
Generate(&o, &p, 0);
|
||||||
pattern = &p;
|
|
||||||
functions = 0;
|
|
||||||
|
|
||||||
break_generating = false;
|
|
||||||
current_item = 0;
|
|
||||||
|
|
||||||
MakeText( pattern->item_root );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -272,29 +417,6 @@ return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::CallUserFunction(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info)
|
|
||||||
{
|
|
||||||
if( function->is_running )
|
|
||||||
{
|
|
||||||
// recurrences are not allowed
|
|
||||||
CreateMsg(L"the function is being executed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function->is_running = true;
|
|
||||||
(function->user_function)(info);
|
|
||||||
function->is_running = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
|
||||||
void Generator<StreamType>::CallVariable(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info)
|
|
||||||
{
|
|
||||||
info.res = !function->variable.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
|
@ -308,52 +430,54 @@ void Generator<StreamType>::Call(typename Functions<StreamType>::Function * func
|
||||||
info.iter = stack_tab.back().iter;
|
info.iter = stack_tab.back().iter;
|
||||||
|
|
||||||
if( function->type == Functions<StreamType>::function )
|
if( function->type == Functions<StreamType>::function )
|
||||||
CallUserFunction(function, info);
|
(function->user_function)(info);
|
||||||
else
|
else
|
||||||
CallVariable(function, info);
|
info.res = !function->variable.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::Call(typename Functions<StreamType>::Function * function,
|
||||||
|
std::vector<std::wstring> & params,
|
||||||
|
StreamType & out_stream, const StreamType & in_stream,
|
||||||
|
bool * info_res)
|
||||||
|
{
|
||||||
|
if( params.empty() )
|
||||||
|
{
|
||||||
|
FunInfo<StreamType> info(out_stream, params, empty, in_stream);
|
||||||
|
Call(function, info);
|
||||||
|
|
||||||
|
if( info_res )
|
||||||
|
*info_res = info.res;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FunInfo<StreamType> info(out_stream, params, params[0], in_stream);
|
||||||
|
Call(function, info);
|
||||||
|
|
||||||
|
if( info_res )
|
||||||
|
*info_res = info.res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// return: true if a function or variable was found and called
|
// return: true if a function or variable was found and called
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
bool Generator<StreamType>::Call(Item::Function & item_fun, bool * info_res, typename Functions<StreamType>::Function ** pfun)
|
bool Generator<StreamType>::Call(Item::Function & item_fun, bool * info_res, typename Functions<StreamType>::Function ** pfun)
|
||||||
{
|
{
|
||||||
typename Functions<StreamType>::Function * fun;
|
typename Functions<StreamType>::Function * fun;
|
||||||
bool called = false;
|
|
||||||
|
|
||||||
if( item_fun.params.empty() )
|
if( !Find(item_fun, &fun) )
|
||||||
{
|
return false;
|
||||||
FunInfo<StreamType> info(*output_stream, item_fun.params, empty);
|
|
||||||
|
|
||||||
if( Find(item_fun, &fun) )
|
Call(fun, item_fun.params, *output_stream, empty_stream, info_res);
|
||||||
{
|
|
||||||
Call(fun, info);
|
|
||||||
called = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( info_res )
|
if( pfun )
|
||||||
*info_res = info.res;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FunInfo<StreamType> info(*output_stream, item_fun.params, item_fun.params[0]);
|
|
||||||
|
|
||||||
if( Find(item_fun, &fun) )
|
|
||||||
{
|
|
||||||
Call(fun, info);
|
|
||||||
called = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( info_res )
|
|
||||||
*info_res = info.res;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( called && pfun )
|
|
||||||
*pfun = fun;
|
*pfun = fun;
|
||||||
|
|
||||||
return called;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -363,27 +487,13 @@ return called;
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::Call(typename Functions<StreamType>::Function * function, std::vector<std::wstring> & params, bool * info_res)
|
void Generator<StreamType>::Call(typename Functions<StreamType>::Function * function, std::vector<std::wstring> & params, bool * info_res)
|
||||||
{
|
{
|
||||||
if( params.empty() )
|
Call(function, params, *output_stream, empty_stream, info_res);
|
||||||
{
|
|
||||||
FunInfo<StreamType> info(*output_stream, params, empty);
|
|
||||||
Call(function, info);
|
|
||||||
|
|
||||||
if( info_res )
|
|
||||||
*info_res = info.res;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FunInfo<StreamType> info(*output_stream, params, params[0]);
|
|
||||||
Call(function, info);
|
|
||||||
|
|
||||||
if( info_res )
|
|
||||||
*info_res = info.res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
wchar_t Generator<StreamType>::CreateSpecialChar(wchar_t c)
|
wchar_t Generator<StreamType>::CreateSpecialChar(wchar_t c)
|
||||||
{
|
{
|
||||||
|
@ -540,12 +650,20 @@ return res;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::CreateMsg(StreamType & out, const wchar_t * type, const wchar_t * arg)
|
||||||
|
{
|
||||||
|
pattern->CreateMsg(temp_msg, type, arg);
|
||||||
|
out.write(temp_msg.c_str(), temp_msg.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::CreateMsg(const wchar_t * type, const wchar_t * arg)
|
void Generator<StreamType>::CreateMsg(const wchar_t * type, const wchar_t * arg)
|
||||||
{
|
{
|
||||||
pattern->CreateMsg(temp_msg, type, arg);
|
CreateMsg(*output_stream, type, arg);
|
||||||
output_stream->write(temp_msg.c_str(), temp_msg.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -896,7 +1014,7 @@ void Generator<StreamType>::MakeTextDefine(Item & item)
|
||||||
{
|
{
|
||||||
if( !functions )
|
if( !functions )
|
||||||
{
|
{
|
||||||
CreateMsg(L"def statement is not available when used without functions set");
|
CreateMsg(L"[def] statement is not available when used without functions set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -930,6 +1048,40 @@ void Generator<StreamType>::MakeTextDefine(Item & item)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::MakeTextFilter(Item & item)
|
||||||
|
{
|
||||||
|
if( item.functions.size() != 1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
typename Functions<StreamType>::Function * function;
|
||||||
|
|
||||||
|
if( !Find(item.functions[0], &function) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( filter_index >= filter_tab.size() )
|
||||||
|
{
|
||||||
|
CreateMsg(L"Generator exceeded allowed number of filters");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamType * old_stream = output_stream;
|
||||||
|
output_stream = filter_tab[filter_index];
|
||||||
|
ClearStream(*output_stream);
|
||||||
|
|
||||||
|
filter_index += 1;
|
||||||
|
|
||||||
|
if( !item.item_tab.empty() )
|
||||||
|
MakeText( *item.item_tab[0] ); // should be only one item - item_container
|
||||||
|
|
||||||
|
Call(function, item.functions[0].params, *old_stream, *output_stream);
|
||||||
|
|
||||||
|
output_stream = old_stream;
|
||||||
|
filter_index -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::MakeText(Item & item)
|
void Generator<StreamType>::MakeText(Item & item)
|
||||||
{
|
{
|
||||||
|
@ -957,6 +1109,7 @@ void Generator<StreamType>::MakeText(Item & item)
|
||||||
else if( item.type == Item::item_isno ) MakeTextIsno(item);
|
else if( item.type == Item::item_isno ) MakeTextIsno(item);
|
||||||
else if( item.type == Item::item_for ) MakeTextFor(item);
|
else if( item.type == Item::item_for ) MakeTextFor(item);
|
||||||
else if( item.type == Item::item_def ) MakeTextDefine(item);
|
else if( item.type == Item::item_def ) MakeTextDefine(item);
|
||||||
|
else if( item.type == Item::item_filter ) MakeTextFilter(item);
|
||||||
else if( item.type == Item::item_err )
|
else if( item.type == Item::item_err )
|
||||||
CreateMsg(L"a wrong directive");
|
CreateMsg(L"a wrong directive");
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2010, Tomasz Sowa
|
* Copyright (c) 2007-2011, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -55,7 +55,7 @@ struct Item
|
||||||
{
|
{
|
||||||
item_none, item_container, item_text, item_normal, item_is, item_isno,
|
item_none, item_container, item_text, item_normal, item_is, item_isno,
|
||||||
item_if, item_ifno, item_ifany, item_ifone, item_ifanyno, item_ifoneno, item_ifindex,
|
item_if, item_ifno, item_ifany, item_ifone, item_ifanyno, item_ifoneno, item_ifindex,
|
||||||
item_for, item_else, item_end, item_err, item_include, item_comment, item_def
|
item_for, item_else, item_end, item_err, item_include, item_comment, item_def, item_filter
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Function
|
struct Function
|
||||||
|
|
|
@ -827,6 +827,17 @@ void Pattern::ReadDirectiveDef(Item & item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Pattern::ReadDirectiveFilter(Item & item)
|
||||||
|
{
|
||||||
|
item.type = Item::item_filter;
|
||||||
|
ReadFunctions(item);
|
||||||
|
|
||||||
|
if( item.functions.size() != 1 )
|
||||||
|
item.type = Item::item_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// user defined directive
|
// user defined directive
|
||||||
void Pattern::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
void Pattern::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
||||||
{
|
{
|
||||||
|
@ -860,6 +871,7 @@ std::wstring name;
|
||||||
else if( name == L"for" ) ReadDirectiveFor(item);
|
else if( name == L"for" ) ReadDirectiveFor(item);
|
||||||
else if( name == L"include" ) ReadDirectiveInclude(item);
|
else if( name == L"include" ) ReadDirectiveInclude(item);
|
||||||
else if( name == L"def" ) ReadDirectiveDef(item);
|
else if( name == L"def" ) ReadDirectiveDef(item);
|
||||||
|
else if( name == L"filter" ) ReadDirectiveFilter(item);
|
||||||
else if( name == L"#" ) ReadDirectiveComment(item);
|
else if( name == L"#" ) ReadDirectiveComment(item);
|
||||||
else
|
else
|
||||||
ReadDirectiveNormal(name, item);
|
ReadDirectiveNormal(name, item);
|
||||||
|
@ -1009,7 +1021,8 @@ void Pattern::CreateTree(Item & item)
|
||||||
pitem->type == Item::item_isno )
|
pitem->type == Item::item_isno )
|
||||||
CreateTreeReadIf(*pitem);
|
CreateTreeReadIf(*pitem);
|
||||||
|
|
||||||
if( pitem->type == Item::item_for )
|
if( pitem->type == Item::item_for ||
|
||||||
|
pitem->type == Item::item_filter )
|
||||||
CreateTreeReadFor(*pitem);
|
CreateTreeReadFor(*pitem);
|
||||||
|
|
||||||
if( pitem->type == Item::item_include )
|
if( pitem->type == Item::item_include )
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2010, Tomasz Sowa
|
* Copyright (c) 2007-2011, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -199,6 +199,7 @@ private:
|
||||||
void ReadDirectiveComment(Item & item);
|
void ReadDirectiveComment(Item & item);
|
||||||
void ReadDirectiveInclude(Item & item);
|
void ReadDirectiveInclude(Item & item);
|
||||||
void ReadDirectiveDef(Item & item);
|
void ReadDirectiveDef(Item & item);
|
||||||
|
void ReadDirectiveFilter(Item & item);
|
||||||
void ReadDirectiveNormal(const std::wstring & name, Item & item);
|
void ReadDirectiveNormal(const std::wstring & name, Item & item);
|
||||||
|
|
||||||
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
||||||
|
|
Loading…
Reference in New Issue