added: possibility to generate output to more than one stream
Generate() methods can take std::vector with pointers to streams added: 'ezc' keyword -- currently only for selecting streams e.g. [ezc stream "0" "3"] - after now the output is generated to streams 0 and 3 git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@445 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
23ce3e83df
commit
9215130b9d
359
src/generator.h
359
src/generator.h
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2012, Tomasz Sowa
|
* Copyright (c) 2007-2013, 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
|
||||||
|
@ -95,19 +95,54 @@ public:
|
||||||
// default stack size: 300
|
// default stack size: 300
|
||||||
void SetStackSize(size_t new_stack_size);
|
void SetStackSize(size_t new_stack_size);
|
||||||
|
|
||||||
|
// do not print anything to stream stream_index
|
||||||
|
// useful when using Generate() method with StreamType tables
|
||||||
|
// this is a small optimization if we know that a stream with stream_index will not be used later
|
||||||
|
// set stream_index to -1 to turn off (default)
|
||||||
|
void SkipStream(int stream_index);
|
||||||
|
|
||||||
// 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);
|
||||||
|
void Generate(std::vector<StreamType> & o, Pattern & p, Functions<StreamType> & f);
|
||||||
|
void Generate(std::vector<StreamType*> & o, Pattern & p, Functions<StreamType> & f);
|
||||||
// this method is used only if the pattern has cached functions
|
// this method is used only if the pattern has cached functions
|
||||||
void Generate(StreamType & o, Pattern & p);
|
void Generate(StreamType & o, Pattern & p);
|
||||||
|
void Generate(std::vector<StreamType> & o, Pattern & p);
|
||||||
|
void Generate(std::vector<StreamType*> & o, Pattern & p);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// current output stream
|
||||||
|
// if we are printing only to one stream e.g. [put stream "3"]
|
||||||
|
// then output_stream is pointing directly to that stream
|
||||||
|
// but if we are printing to more than one stream e.g. [put stream "0" "2" "5"]
|
||||||
|
// then output_stream is pointing to tmp_stream and at the end
|
||||||
|
// tmp_stream is copied to the correct streams
|
||||||
|
// output_stream can be null e.g. [put stream] without arguments
|
||||||
|
// in such a case we do not print anything
|
||||||
StreamType * output_stream;
|
StreamType * output_stream;
|
||||||
Pattern * pattern;
|
Pattern * pattern;
|
||||||
Functions<StreamType> * functions;
|
Functions<StreamType> * functions;
|
||||||
|
|
||||||
|
// tmp_stream is used when outputting to more than one stream
|
||||||
|
// (first we output to tmp_stream and then the content is copied
|
||||||
|
// to the correct streams)
|
||||||
|
StreamType tmp_stream;
|
||||||
|
|
||||||
|
// pointers to the output streams
|
||||||
|
std::vector<StreamType*> output_stream_tab;
|
||||||
|
|
||||||
|
// indices to output_stream_tab
|
||||||
|
// they are set by [put stream ...] keyword
|
||||||
|
// at the beginning there is only one index created automatically - "0"
|
||||||
|
std::vector<size_t> output_stream_index;
|
||||||
|
|
||||||
|
// if has_skip_stream_index is true then when reading stream indices from [put stream ...]
|
||||||
|
// a stream with skip_stream_index index will be ignored
|
||||||
|
bool has_skip_stream_index;
|
||||||
|
size_t skip_stream_index;
|
||||||
|
|
||||||
// temporary error messages
|
// temporary error messages
|
||||||
std::wstring temp_msg;
|
std::wstring temp_msg;
|
||||||
|
|
||||||
|
@ -130,6 +165,7 @@ private:
|
||||||
const StreamType empty_stream;
|
const StreamType empty_stream;
|
||||||
|
|
||||||
// temporary streams used in [if..] [is...] or [for...]
|
// temporary streams used in [if..] [is...] or [for...]
|
||||||
|
// or if output_stream is null and an ezc function should be called
|
||||||
StreamType stream_temp1, stream_temp2;
|
StreamType stream_temp1, stream_temp2;
|
||||||
|
|
||||||
// whether last function has put its content in case_sensitive (set FunInfo::case_sensitive)
|
// whether last function has put its content in case_sensitive (set FunInfo::case_sensitive)
|
||||||
|
@ -188,10 +224,11 @@ private:
|
||||||
void PrintNormalText(const wchar_t * start, const wchar_t * end);
|
void PrintNormalText(const wchar_t * start, const wchar_t * end);
|
||||||
void TrimWhite(const wchar_t *& start, const wchar_t *& end);
|
void TrimWhite(const wchar_t *& start, const wchar_t *& end);
|
||||||
void SkipWhite(const wchar_t *& str);
|
void SkipWhite(const wchar_t *& str);
|
||||||
size_t StrToSize(const wchar_t * str, const wchar_t ** str_end);
|
size_t StrToSize(const wchar_t * str, const wchar_t ** str_end = 0);
|
||||||
bool LookForLastForStatement(size_t & last_for_index);
|
bool LookForLastForStatement(size_t & last_for_index);
|
||||||
|
|
||||||
void CreateMsg(StreamType & out, const wchar_t * type, const wchar_t * arg = 0);
|
|
||||||
|
void WriteTmpStreamToStreams();
|
||||||
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);
|
||||||
|
@ -217,9 +254,14 @@ private:
|
||||||
void MakeTextIsno(Item & item);
|
void MakeTextIsno(Item & item);
|
||||||
void MakeTextDefine(Item & item);
|
void MakeTextDefine(Item & item);
|
||||||
void MakeTextFilter(Item & item);
|
void MakeTextFilter(Item & item);
|
||||||
|
void MakeTextEzc(Item & item);
|
||||||
void MakeText(Item & item);
|
void MakeText(Item & item);
|
||||||
|
|
||||||
void Generate(StreamType * o, Pattern * p, Functions<StreamType> * f);
|
void MakeEzcStream(Item::Function & fun);
|
||||||
|
|
||||||
|
void Generate(Pattern * p, Functions<StreamType> * f);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}; // class Generator
|
}; // class Generator
|
||||||
|
|
||||||
|
@ -243,6 +285,7 @@ Generator<StreamType>::Generator() : empty_stream()
|
||||||
skip_new_line = false;
|
skip_new_line = false;
|
||||||
is_generator_working = false;
|
is_generator_working = false;
|
||||||
stack_size = 300;
|
stack_size = 300;
|
||||||
|
has_skip_stream_index = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,15 +300,20 @@ Generator<StreamType>::Generator(const Generator<StreamType> & n)
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamType> & n)
|
Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamType> & n)
|
||||||
{
|
{
|
||||||
output_stream = n.output_stream;
|
// !! CHECK ME may output_streams should not be copied?
|
||||||
|
output_stream_tab = n.output_stream_tab;
|
||||||
|
output_stream_index = n.output_stream_index;
|
||||||
|
output_tmp_stream = n.output_tmp_stream;
|
||||||
|
output_stream = n.output_stream;
|
||||||
|
|
||||||
pattern = n.pattern;
|
pattern = n.pattern;
|
||||||
functions = n.functions;
|
functions = n.functions;
|
||||||
|
|
||||||
max_items = n.max_items;
|
max_items = n.max_items;
|
||||||
max_for_items = n.max_for_items;
|
max_for_items = n.max_for_items;
|
||||||
special_chars = n.special_chars;
|
special_chars = n.special_chars;
|
||||||
trim_white = n.trim_white;
|
trim_white = n.trim_white;
|
||||||
skip_new_line = n.skip_new_line;
|
skip_new_line = n.skip_new_line;
|
||||||
|
has_skip_stream_index = n.has_skip_stream_index;
|
||||||
|
|
||||||
// filter and stack will be auto resized after next call to Generate() method
|
// filter and stack will be auto resized after next call to Generate() method
|
||||||
filter_size = n.filter_size;
|
filter_size = n.filter_size;
|
||||||
|
@ -372,6 +420,21 @@ void Generator<StreamType>::RemoveStackFunData(Stack & s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::SkipStream(int stream_index)
|
||||||
|
{
|
||||||
|
if( stream_index < 0 )
|
||||||
|
{
|
||||||
|
has_skip_stream_index = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
has_skip_stream_index = true;
|
||||||
|
skip_stream_index = stream_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
template<class CharType>
|
template<class CharType>
|
||||||
|
@ -463,21 +526,31 @@ void Generator<StreamType>::SetStackSize(size_t new_stack_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::Generate(StreamType * o, Pattern * p, Functions<StreamType> * f)
|
void Generator<StreamType>::Generate(Pattern * p, Functions<StreamType> * f)
|
||||||
{
|
{
|
||||||
if( is_generator_working )
|
if( is_generator_working )
|
||||||
{
|
{
|
||||||
if( o )
|
CreateMsg(L"generator busy");
|
||||||
CreateMsg(*o, L"generator busy");
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
output_stream = o;
|
output_stream = 0;
|
||||||
pattern = p;
|
output_stream_index.clear();
|
||||||
functions = f;
|
ClearStream(tmp_stream);
|
||||||
|
|
||||||
|
if( !output_stream_tab.empty() )
|
||||||
|
{
|
||||||
|
if( !has_skip_stream_index || skip_stream_index != 0 )
|
||||||
|
{
|
||||||
|
output_stream_index.push_back(0);
|
||||||
|
output_stream = output_stream_tab[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern = p;
|
||||||
|
functions = f;
|
||||||
break_generating = false;
|
break_generating = false;
|
||||||
current_item = 0;
|
current_item = 0;
|
||||||
|
|
||||||
|
@ -491,12 +564,16 @@ void Generator<StreamType>::Generate(StreamType * o, Pattern * p, Functions<Stre
|
||||||
filter_index = 0;
|
filter_index = 0;
|
||||||
stack_index = 0;
|
stack_index = 0;
|
||||||
|
|
||||||
if( output_stream && pattern )
|
if( pattern )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
is_generator_working = true;
|
is_generator_working = true;
|
||||||
MakeText( pattern->item_root );
|
MakeText( pattern->item_root );
|
||||||
|
|
||||||
|
if( output_stream_index.size() > 1 )
|
||||||
|
WriteTmpStreamToStreams();
|
||||||
|
|
||||||
is_generator_working = false;
|
is_generator_working = false;
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -508,23 +585,77 @@ void Generator<StreamType>::Generate(StreamType * o, Pattern * p, Functions<Stre
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::Generate(StreamType & o, Pattern & p, Functions<StreamType> & f)
|
void Generator<StreamType>::Generate(StreamType & o, Pattern & p, Functions<StreamType> & f)
|
||||||
{
|
{
|
||||||
Generate(&o, &p, &f);
|
output_stream_tab.resize(1);
|
||||||
|
output_stream_tab[0] = &o;
|
||||||
|
|
||||||
|
Generate(&p, &f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::Generate(std::vector<StreamType> & o, Pattern & p, Functions<StreamType> & f)
|
||||||
|
{
|
||||||
|
output_stream_tab.resize(o.size());
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<o.size() ; ++i)
|
||||||
|
output_stream_tab[i] = &o[i];
|
||||||
|
|
||||||
|
Generate(&p, &f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::Generate(std::vector<StreamType*> & o, Pattern & p, Functions<StreamType> & f)
|
||||||
|
{
|
||||||
|
output_stream_tab.resize(o.size());
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<o.size() ; ++i)
|
||||||
|
output_stream_tab[i] = o[i];
|
||||||
|
|
||||||
|
Generate(&p, &f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::Generate(StreamType & o, Pattern & p)
|
void Generator<StreamType>::Generate(StreamType & o, Pattern & p)
|
||||||
{
|
{
|
||||||
Generate(&o, &p, 0);
|
output_stream_tab.resize(1);
|
||||||
|
output_stream_tab[0] = &o;
|
||||||
|
|
||||||
|
Generate(&p, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::Generate(std::vector<StreamType> & o, Pattern & p)
|
||||||
|
{
|
||||||
|
output_stream_tab.resize(o.size());
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<o.size() ; ++i)
|
||||||
|
output_stream_tab[i] = &o[i];
|
||||||
|
|
||||||
|
Generate(&p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::Generate(std::vector<StreamType*> & o, Pattern & p)
|
||||||
|
{
|
||||||
|
output_stream_tab.resize(o.size());
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<o.size() ; ++i)
|
||||||
|
output_stream_tab[i] = o[i];
|
||||||
|
|
||||||
|
Generate(&p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -637,7 +768,6 @@ bool Generator<StreamType>::Call(Item::Function & item_fun)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
wchar_t Generator<StreamType>::CreateSpecialChar(wchar_t c)
|
wchar_t Generator<StreamType>::CreateSpecialChar(wchar_t c)
|
||||||
{
|
{
|
||||||
|
@ -695,25 +825,28 @@ return start;
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::PrintSpecialText(const wchar_t * start, const wchar_t * end)
|
void Generator<StreamType>::PrintSpecialText(const wchar_t * start, const wchar_t * end)
|
||||||
{
|
{
|
||||||
while( start != end )
|
if( output_stream )
|
||||||
{
|
{
|
||||||
const wchar_t * end2 = start;
|
while( start != end )
|
||||||
|
{
|
||||||
|
const wchar_t * end2 = start;
|
||||||
|
|
||||||
// looking for a first new line character or a special char
|
// looking for a first new line character or a special char
|
||||||
// (for new line only if skip_new_line is true)
|
// (for new line only if skip_new_line is true)
|
||||||
while( end2 != end && *end2 != '\\' && (!skip_new_line || *end2 != 10) )
|
while( end2 != end && *end2 != '\\' && (!skip_new_line || *end2 != 10) )
|
||||||
end2 += 1;
|
end2 += 1;
|
||||||
|
|
||||||
// printing the first part of the text
|
// printing the first part of the text
|
||||||
if( start != end2 )
|
if( start != end2 )
|
||||||
output_stream->write(start, end2 - start);
|
output_stream->write(start, end2 - start);
|
||||||
|
|
||||||
start = end2;
|
start = end2;
|
||||||
|
|
||||||
// skipping one or more new line characters or special chars
|
// skipping one or more new line characters or special chars
|
||||||
// (new lines only if skip_new_line is true)
|
// (new lines only if skip_new_line is true)
|
||||||
while( start != end && (*start == '\\' || (skip_new_line && *start == 10)) )
|
while( start != end && (*start == '\\' || (skip_new_line && *start == 10)) )
|
||||||
start = PrintSpecialChar(start, end);
|
start = PrintSpecialChar(start, end);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,31 +854,34 @@ void Generator<StreamType>::PrintSpecialText(const wchar_t * start, const wchar_
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::PrintNormalText(const wchar_t * start, const wchar_t * end)
|
void Generator<StreamType>::PrintNormalText(const wchar_t * start, const wchar_t * end)
|
||||||
{
|
{
|
||||||
if( skip_new_line )
|
if( output_stream )
|
||||||
{
|
{
|
||||||
while( start != end )
|
if( skip_new_line )
|
||||||
{
|
{
|
||||||
const wchar_t * end2 = start;
|
while( start != end )
|
||||||
|
{
|
||||||
|
const wchar_t * end2 = start;
|
||||||
|
|
||||||
// looking for a first new line character
|
// looking for a first new line character
|
||||||
while( end2 != end && *end2 != 10 )
|
while( end2 != end && *end2 != 10 )
|
||||||
end2 += 1;
|
end2 += 1;
|
||||||
|
|
||||||
// printing the first part of the text (until the new line)
|
// printing the first part of the text (until the new line)
|
||||||
if( start != end2 )
|
if( start != end2 )
|
||||||
output_stream->write(start, end2 - start);
|
output_stream->write(start, end2 - start);
|
||||||
|
|
||||||
start = end2;
|
start = end2;
|
||||||
|
|
||||||
// skipping one or more new line characters
|
// skipping one or more new line characters
|
||||||
while( start != end && *start == 10 )
|
while( start != end && *start == 10 )
|
||||||
start += 1;
|
start += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( start != end )
|
||||||
|
output_stream->write(start, end - start);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( start != end )
|
|
||||||
output_stream->write(start, end-start);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,18 +924,35 @@ size_t res = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkipWhite(str);
|
SkipWhite(str);
|
||||||
*str_end = str;
|
|
||||||
|
if( str_end )
|
||||||
|
*str_end = str;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
void Generator<StreamType>::CreateMsg(StreamType & out, const wchar_t * type, const wchar_t * arg)
|
void Generator<StreamType>::WriteTmpStreamToStreams()
|
||||||
{
|
{
|
||||||
pattern->CreateMsg(temp_msg, type, arg);
|
#ifdef EZC_HAS_SPECIAL_STREAM
|
||||||
out.write(temp_msg.c_str(), temp_msg.size());
|
const std::wstring & str = tmp_stream.Str();
|
||||||
|
#else
|
||||||
|
const std::wstring & str = tmp_stream.str();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if( !str.empty() )
|
||||||
|
{
|
||||||
|
for(size_t s = 0 ; s < output_stream_index.size() ; ++s)
|
||||||
|
{
|
||||||
|
size_t i = output_stream_index[s];
|
||||||
|
|
||||||
|
if( i < output_stream_tab.size() )
|
||||||
|
output_stream_tab[i]->write(str.c_str(), str.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearStream(tmp_stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -808,7 +961,11 @@ void Generator<StreamType>::CreateMsg(StreamType & out, const wchar_t * type, co
|
||||||
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)
|
||||||
{
|
{
|
||||||
CreateMsg(*output_stream, type, arg);
|
if( output_stream )
|
||||||
|
{
|
||||||
|
pattern->CreateMsg(temp_msg, type, arg);
|
||||||
|
output_stream->write(temp_msg.c_str(), temp_msg.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -871,7 +1028,16 @@ void Generator<StreamType>::MakeTextNormal(Item & item)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
is_generating_normal = true;
|
is_generating_normal = true;
|
||||||
Call(item.functions[0], *output_stream, false);
|
|
||||||
|
if( output_stream )
|
||||||
|
{
|
||||||
|
Call(item.functions[0], *output_stream, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Call(item.functions[0], stream_temp1, false);
|
||||||
|
ClearStream(stream_temp1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1240,6 +1406,7 @@ void Generator<StreamType>::MakeTextFilter(Item & item)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StreamType * old_stream = output_stream;
|
StreamType * old_stream = output_stream;
|
||||||
output_stream = filter_tab[filter_index];
|
output_stream = filter_tab[filter_index];
|
||||||
ClearStream(*output_stream);
|
ClearStream(*output_stream);
|
||||||
|
@ -1250,13 +1417,80 @@ void Generator<StreamType>::MakeTextFilter(Item & item)
|
||||||
MakeText( *item.item_tab[0] ); // should be only one item - item_container
|
MakeText( *item.item_tab[0] ); // should be only one item - item_container
|
||||||
|
|
||||||
is_generating_filter = true;
|
is_generating_filter = true;
|
||||||
Call(function, item.functions[0].params, *old_stream, false, *output_stream);
|
|
||||||
|
|
||||||
|
if( old_stream )
|
||||||
|
{
|
||||||
|
Call(function, item.functions[0].params, *old_stream, false, *output_stream);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Call(function, item.functions[0].params, stream_temp1, true, *output_stream);
|
||||||
|
ClearStream(stream_temp1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearStream(*output_stream);
|
||||||
output_stream = old_stream;
|
output_stream = old_stream;
|
||||||
filter_index -= 1;
|
filter_index -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::MakeEzcStream(Item::Function & fun)
|
||||||
|
{
|
||||||
|
if( output_stream_index.size() > 1 )
|
||||||
|
WriteTmpStreamToStreams();
|
||||||
|
|
||||||
|
output_stream_index.clear();
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<fun.params.size() ; ++i)
|
||||||
|
{
|
||||||
|
size_t index = StrToSize(fun.params[i].c_str());
|
||||||
|
|
||||||
|
if( index < output_stream_tab.size() )
|
||||||
|
{
|
||||||
|
if( !has_skip_stream_index || skip_stream_index != index )
|
||||||
|
output_stream_index.push_back(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we do not print any information if the index is out of range
|
||||||
|
// because we do not know to which stream is should be printed
|
||||||
|
}
|
||||||
|
|
||||||
|
if( output_stream_index.size() > 1 )
|
||||||
|
{
|
||||||
|
ClearStream(tmp_stream);
|
||||||
|
output_stream = &tmp_stream;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( output_stream_index.size() == 1 )
|
||||||
|
{
|
||||||
|
size_t index = output_stream_index[0];
|
||||||
|
output_stream = output_stream_tab[index];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output_stream = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Generator<StreamType>::MakeTextEzc(Item & item)
|
||||||
|
{
|
||||||
|
for(size_t i=0 ; i<item.functions.size() ; ++i)
|
||||||
|
{
|
||||||
|
if( item.functions[i].name == L"stream" )
|
||||||
|
MakeEzcStream(item.functions[i]);
|
||||||
|
else
|
||||||
|
CreateMsg(L"incorrect argument to [ezc] statement");
|
||||||
|
|
||||||
|
// in the future we can use more builtin functions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class StreamType>
|
template<class StreamType>
|
||||||
bool Generator<StreamType>::LimitAchieved()
|
bool Generator<StreamType>::LimitAchieved()
|
||||||
{
|
{
|
||||||
|
@ -1310,6 +1544,7 @@ void Generator<StreamType>::MakeText(Item & 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_for ) MakeTextFor(item);
|
else if( item.type == Item::item_for ) MakeTextFor(item);
|
||||||
else if( item.type == Item::item_filter ) MakeTextFilter(item);
|
else if( item.type == Item::item_filter ) MakeTextFilter(item);
|
||||||
|
else if( item.type == Item::item_ezc ) MakeTextEzc(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-2011, Tomasz Sowa
|
* Copyright (c) 2007-2013, 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,8 @@ 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_filter
|
item_for, item_else, item_end, item_err, item_include, item_comment, item_def, item_filter,
|
||||||
|
item_ezc
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Function
|
struct Function
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2012, Tomasz Sowa
|
* Copyright (c) 2007-2013, 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
|
||||||
|
@ -837,6 +837,13 @@ void Pattern::ReadDirectiveFilter(Item & item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Pattern::ReadDirectiveEzc(Item & item)
|
||||||
|
{
|
||||||
|
item.type = Item::item_ezc;
|
||||||
|
ReadFunctions(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// user defined directive
|
// user defined directive
|
||||||
void Pattern::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
void Pattern::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
||||||
|
@ -872,6 +879,7 @@ std::wstring name;
|
||||||
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"filter" ) ReadDirectiveFilter(item);
|
||||||
|
else if( name == L"ezc" ) ReadDirectiveEzc(item);
|
||||||
else if( name == L"#" ) ReadDirectiveComment(item);
|
else if( name == L"#" ) ReadDirectiveComment(item);
|
||||||
else
|
else
|
||||||
ReadDirectiveNormal(name, item);
|
ReadDirectiveNormal(name, item);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2012, Tomasz Sowa
|
* Copyright (c) 2007-2013, 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
|
||||||
|
@ -200,6 +200,7 @@ private:
|
||||||
void ReadDirectiveInclude(Item & item);
|
void ReadDirectiveInclude(Item & item);
|
||||||
void ReadDirectiveDef(Item & item);
|
void ReadDirectiveDef(Item & item);
|
||||||
void ReadDirectiveFilter(Item & item);
|
void ReadDirectiveFilter(Item & item);
|
||||||
|
void ReadDirectiveEzc(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