added: Pattern::CacheFunctions(Functions<StreamType> & fun)
you can cache all functions (their addresses) in the pattern changed: now we have two methods for generating content: Generator<>::Generate(StreamType & o, Pattern & p, Functions<StreamType> & f); similar like previous -- Set(...) methods were removed as well as the second ctor and a second one: Generate(StreamType & o, Pattern & p); without functions, the functions should be cached beforehand in the pattern by calling CacheFunctions() method on the pattern this gives O(1) complexity when looking for a specific function previously was O(log n) git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@329 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
5108495540
commit
0b09b5454f
|
@ -1,7 +1,7 @@
|
|||
# DO NOT DELETE
|
||||
|
||||
edanticitem.o: item.h
|
||||
edanticpattern.o: pattern.h item.h stringconv.h utf8.h
|
||||
edanticitem.o: item.h funinfo.h
|
||||
edanticpattern.o: pattern.h item.h funinfo.h functions.h stringconv.h utf8.h
|
||||
edanticpattern.o: /home/tomek/roboczy/winix/core/log.h
|
||||
edanticpattern.o: /home/tomek/roboczy/winix/core/textstream.h
|
||||
edanticpattern.o: /home/tomek/roboczy/winix/core/misc.h
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#include <map>
|
||||
#include "funinfo.h"
|
||||
|
||||
#include "stringconv.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
|
@ -87,8 +87,7 @@ public:
|
|||
bool Find(const std::string & key, Function ** fun);
|
||||
bool Find(const std::wstring & key, Function ** fun);
|
||||
void Clear();
|
||||
size_t Size();
|
||||
|
||||
size_t Size() const;
|
||||
|
||||
private:
|
||||
typedef std::map<std::wstring, Function> FunctionsTable;
|
||||
|
@ -99,9 +98,6 @@ private:
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
Functions<StreamType>::Function::Function()
|
||||
{
|
||||
|
@ -246,13 +242,15 @@ void Functions<StreamType>::Clear()
|
|||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
size_t Functions<StreamType>::Size()
|
||||
size_t Functions<StreamType>::Size() const
|
||||
{
|
||||
return functions_tab.size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
|
|
206
src/generator.h
206
src/generator.h
|
@ -48,8 +48,7 @@ namespace Ezc
|
|||
{
|
||||
/*
|
||||
StreamType
|
||||
we use method write where the content should not be escaped (html escaping)
|
||||
we use operator<< where the content can be escaped (such as error messages)
|
||||
we use only method write(const wchar_t * str, size_t len) from the stream
|
||||
*/
|
||||
template<class StreamType>
|
||||
class Generator
|
||||
|
@ -57,12 +56,7 @@ class Generator
|
|||
public:
|
||||
|
||||
Generator();
|
||||
Generator(StreamType & o, Pattern & p, Functions<StreamType> & f);
|
||||
|
||||
void Set(StreamType & o, Pattern & p, Functions<StreamType> & f);
|
||||
void Set(StreamType & o);
|
||||
void Set(Pattern & p);
|
||||
void Set(Functions<StreamType> & f);
|
||||
void SetMax(int max_items_, int max_for_items_);
|
||||
|
||||
// recognizing some special characters in text patterns (item_text in Patterns)
|
||||
|
@ -86,8 +80,12 @@ public:
|
|||
// default: false
|
||||
void SkipNewLine(bool skip);
|
||||
|
||||
// the main method for generating
|
||||
void Generate();
|
||||
// the main methods for generating
|
||||
void Generate(StreamType & o, Pattern & p, Functions<StreamType> & f);
|
||||
|
||||
// this method is used only if the pattern has cached functions
|
||||
void Generate(StreamType & o, Pattern & p);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
@ -111,11 +109,10 @@ private:
|
|||
const std::wstring empty;
|
||||
|
||||
|
||||
bool Find(const std::wstring & key, 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);
|
||||
bool Call(const std::wstring & name, FunInfo<StreamType> & info, typename Functions<StreamType>::Function ** pfun = 0);
|
||||
bool Call(typename 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 CallUserFunction(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info);
|
||||
void CallVariable(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info);
|
||||
|
@ -128,9 +125,10 @@ private:
|
|||
void SkipWhite(const wchar_t *& str);
|
||||
int StrToInt(const wchar_t * str, const wchar_t ** str_end);
|
||||
|
||||
void CreateMsg(StreamType & o, const wchar_t * type, const wchar_t * arg = 0);
|
||||
void CreateMsg(StreamType & o, const std::wstring & type, const std::wstring & arg);
|
||||
void CreateMsg(StreamType & o, const std::wstring & type);
|
||||
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);
|
||||
void CreateUnknownMsg(const std::wstring & fun);
|
||||
|
||||
void MakeTextIf_go(Item & item, bool result);
|
||||
bool MakeTextIfindexnumber(Item & item, typename Functions<StreamType>::Function * function, bool & result);
|
||||
|
@ -173,49 +171,6 @@ Generator<StreamType>::Generator()
|
|||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
Generator<StreamType>::Generator(StreamType & o, Pattern & p, Functions<StreamType> & f)
|
||||
{
|
||||
output_stream = &o;
|
||||
pattern = &p;
|
||||
functions = &f;
|
||||
|
||||
max_items = 50000;
|
||||
max_for_items = 5000;
|
||||
special_chars = false;
|
||||
trim_white = false;
|
||||
skip_new_line = false;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::Set(StreamType & o, Pattern & p, Functions<StreamType> & f)
|
||||
{
|
||||
output_stream = &o;
|
||||
pattern = &p;
|
||||
functions = &f;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::Set(StreamType & o)
|
||||
{
|
||||
output_stream = &o;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::Set(Pattern & p)
|
||||
{
|
||||
pattern = &p;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::Set(Functions<StreamType> & f)
|
||||
{
|
||||
functions = &f;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
|
@ -248,10 +203,25 @@ void Generator<StreamType>::SkipNewLine(bool skip)
|
|||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::Generate()
|
||||
void Generator<StreamType>::Generate(StreamType & o, Pattern & p, Functions<StreamType> & f)
|
||||
{
|
||||
if( !output_stream || !pattern || !functions )
|
||||
return;
|
||||
output_stream = &o;
|
||||
pattern = &p;
|
||||
functions = &f;
|
||||
|
||||
break_generating = false;
|
||||
current_item = 0;
|
||||
|
||||
MakeText( pattern->item_root );
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::Generate(StreamType & o, Pattern & p)
|
||||
{
|
||||
output_stream = &o;
|
||||
pattern = &p;
|
||||
functions = 0;
|
||||
|
||||
break_generating = false;
|
||||
current_item = 0;
|
||||
|
@ -263,12 +233,27 @@ void Generator<StreamType>::Generate()
|
|||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::Find(const std::wstring & key, typename Functions<StreamType>::Function ** function)
|
||||
bool Generator<StreamType>::Find(const Item::Function & item_fun, typename Functions<StreamType>::Function ** function)
|
||||
{
|
||||
if( !functions->Find(key, function) )
|
||||
if( !functions )
|
||||
{
|
||||
CreateMsg(*output_stream, L"can't find", key.c_str() );
|
||||
if( item_fun.fun_cache )
|
||||
{
|
||||
*function = reinterpret_cast<typename Functions<StreamType>::Function*>(item_fun.fun_cache);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateUnknownMsg(item_fun.name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( !functions->Find(item_fun.name, function) )
|
||||
{
|
||||
CreateUnknownMsg(item_fun.name);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -276,14 +261,13 @@ 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(*output_stream, L"the function is being executed");
|
||||
CreateMsg(L"the function is being executed");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -315,53 +299,52 @@ void Generator<StreamType>::Call(typename Functions<StreamType>::Function * func
|
|||
}
|
||||
|
||||
|
||||
// return: true if a function or variable was found and called
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::Call(const std::wstring & name, FunInfo<StreamType> & info, typename Functions<StreamType>::Function ** pfun)
|
||||
{
|
||||
typename Functions<StreamType>::Function * function;
|
||||
|
||||
if( Find(name, &function) )
|
||||
{
|
||||
Call(function, info);
|
||||
|
||||
if( pfun )
|
||||
*pfun = function;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// return: true if a function or variable was found and called
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::Call(typename Item::Function & function, bool * info_res, typename Functions<StreamType>::Function ** pfun)
|
||||
bool Generator<StreamType>::Call(Item::Function & item_fun, bool * info_res, typename Functions<StreamType>::Function ** pfun)
|
||||
{
|
||||
bool called;
|
||||
typename Functions<StreamType>::Function * fun;
|
||||
bool called = false;
|
||||
|
||||
if( function.params.empty() )
|
||||
if( item_fun.params.empty() )
|
||||
{
|
||||
FunInfo<StreamType> info(*output_stream, function.params, empty);
|
||||
called = Call(function.name, info, pfun);
|
||||
FunInfo<StreamType> info(*output_stream, item_fun.params, empty);
|
||||
|
||||
if( Find(item_fun, &fun) )
|
||||
{
|
||||
Call(fun, info);
|
||||
called = true;
|
||||
}
|
||||
|
||||
if( info_res )
|
||||
*info_res = info.res;
|
||||
}
|
||||
else
|
||||
{
|
||||
FunInfo<StreamType> info(*output_stream, function.params, function.params[0]);
|
||||
called = Call(function.name, info, pfun);
|
||||
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;
|
||||
|
||||
return called;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
wchar_t Generator<StreamType>::CreateSpecialChar(wchar_t c)
|
||||
{
|
||||
|
@ -520,30 +503,35 @@ return res;
|
|||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CreateMsg(StreamType & o, 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);
|
||||
o << temp_msg;
|
||||
temp_msg.clear();
|
||||
output_stream->write(temp_msg.c_str(), temp_msg.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CreateMsg(StreamType & o, const std::wstring & type, const std::wstring & arg)
|
||||
void Generator<StreamType>::CreateMsg(const std::wstring & type, const std::wstring & arg)
|
||||
{
|
||||
CreateMsg(o, type.c_str(), arg.c_str());
|
||||
CreateMsg(type.c_str(), arg.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CreateMsg(StreamType & o, const std::wstring & type)
|
||||
void Generator<StreamType>::CreateMsg(const std::wstring & type)
|
||||
{
|
||||
CreateMsg(o, type.c_str());
|
||||
CreateMsg(type.c_str());
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CreateUnknownMsg(const std::wstring & fun)
|
||||
{
|
||||
CreateMsg(L"unknown function", fun.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -770,7 +758,7 @@ bool Generator<StreamType>::MakeTextIfindexnumber(Item & item, typename Function
|
|||
|
||||
if( *last_char != '\0' )
|
||||
{
|
||||
CreateMsg(*output_stream, L"if-index: syntax error");
|
||||
CreateMsg(L"if-index: syntax error");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -792,7 +780,7 @@ void Generator<StreamType>::MakeTextIfindex(Item & item)
|
|||
|
||||
typename Functions<StreamType>::Function * function;
|
||||
|
||||
if( !Find(item.functions[0].name, &function) )
|
||||
if( !Find(item.functions[0], &function) )
|
||||
return;
|
||||
|
||||
bool result = false;
|
||||
|
@ -832,7 +820,7 @@ bool info_res;
|
|||
{
|
||||
if( function->iter >= max_for_items )
|
||||
{
|
||||
CreateMsg(*output_stream, item.functions[0].name.c_str(),
|
||||
CreateMsg(item.functions[0].name.c_str(),
|
||||
L"function exceeded a limit for a [for] statement");
|
||||
break;
|
||||
}
|
||||
|
@ -856,12 +844,12 @@ void Generator<StreamType>::MakeTextFor(Item & item)
|
|||
|
||||
typename Functions<StreamType>::Function * function;
|
||||
|
||||
if( !Find(item.functions[0].name, &function) )
|
||||
if( !Find(item.functions[0], &function) )
|
||||
return;
|
||||
|
||||
if( function->is_for )
|
||||
{
|
||||
CreateMsg(*output_stream, item.functions[0].name.c_str(),
|
||||
CreateMsg(item.functions[0].name.c_str(),
|
||||
L"this function is already used in a [for] statement");
|
||||
return;
|
||||
}
|
||||
|
@ -880,6 +868,12 @@ void Generator<StreamType>::MakeTextFor(Item & item)
|
|||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextDefine(Item & item)
|
||||
{
|
||||
if( !functions )
|
||||
{
|
||||
CreateMsg(L"def statement is not available when used without functions set");
|
||||
return;
|
||||
}
|
||||
|
||||
if( item.functions.size() == 1 )
|
||||
{
|
||||
// inserting a new variable
|
||||
|
@ -891,7 +885,7 @@ void Generator<StreamType>::MakeTextDefine(Item & item)
|
|||
{
|
||||
typename Functions<StreamType>::Function * function;
|
||||
|
||||
if( Find(item.functions[1].name, &function) )
|
||||
if( Find(item.functions[1], &function) )
|
||||
{
|
||||
if( function->type == Functions<StreamType>::function )
|
||||
{
|
||||
|
@ -919,7 +913,7 @@ void Generator<StreamType>::MakeText(Item & item)
|
|||
if( ++current_item > max_items )
|
||||
{
|
||||
break_generating = true;
|
||||
CreateMsg(*output_stream, L"Generator exceeded allowed number of elements");
|
||||
CreateMsg(L"Generator exceeded allowed number of elements");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -938,7 +932,7 @@ void Generator<StreamType>::MakeText(Item & 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_err )
|
||||
CreateMsg(*output_stream, L"a wrong directive");
|
||||
CreateMsg(L"a wrong directive");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "funinfo.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
|
@ -61,6 +62,12 @@ struct Item
|
|||
{
|
||||
std::wstring name; // function name
|
||||
std::vector<std::wstring> params; // function parameters
|
||||
void * fun_cache;
|
||||
|
||||
Function()
|
||||
{
|
||||
fun_cache = 0;
|
||||
}
|
||||
};
|
||||
|
||||
Type type;
|
||||
|
|
|
@ -38,9 +38,6 @@
|
|||
|
||||
#include "pattern.h"
|
||||
|
||||
#ifdef EZC_USE_WINIX_LOGGER
|
||||
#include "core/log.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Ezc
|
||||
|
@ -70,6 +67,22 @@ void Pattern::Clear()
|
|||
}
|
||||
|
||||
|
||||
void Pattern::ClearCache()
|
||||
{
|
||||
ClearCache(item_root);
|
||||
}
|
||||
|
||||
|
||||
void Pattern::ClearCache(Item & item)
|
||||
{
|
||||
for(size_t f = 0; f < item.functions.size() ; ++f)
|
||||
item.functions[f].fun_cache = 0;
|
||||
|
||||
for(size_t i = 0; i < item.item_tab.size() ; ++i)
|
||||
ClearCache(*item.item_tab[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Pattern::Directory(const char * dir, const char * dir2)
|
||||
{
|
||||
|
@ -77,17 +90,17 @@ void Pattern::Directory(const char * dir, const char * dir2)
|
|||
directory2.clear();
|
||||
|
||||
if( dir )
|
||||
AssignString(dir, directory);
|
||||
UTF8ToWide(dir, directory);
|
||||
|
||||
if( dir2 )
|
||||
AssignString(dir2, directory2);
|
||||
UTF8ToWide(dir2, directory2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Pattern::Directory(const std::string & dir)
|
||||
{
|
||||
AssignString(dir, directory);
|
||||
UTF8ToWide(dir, directory);
|
||||
directory2.clear();
|
||||
}
|
||||
|
||||
|
@ -95,8 +108,8 @@ void Pattern::Directory(const std::string & dir)
|
|||
|
||||
void Pattern::Directory(const std::string & dir, const std::string & dir2)
|
||||
{
|
||||
AssignString(dir, directory);
|
||||
AssignString(dir2, directory2);
|
||||
UTF8ToWide(dir, directory);
|
||||
UTF8ToWide(dir2, directory2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -141,7 +154,7 @@ void Pattern::ParseFile(const std::string & file_name)
|
|||
|
||||
void Pattern::ParseFile(const char * file_name)
|
||||
{
|
||||
AssignString(file_name, item_root.file_name);
|
||||
UTF8ToWide(file_name, item_root.file_name);
|
||||
include_level = 0;
|
||||
CreateTreeReadIncludeSkipAllowFlag(item_root);
|
||||
}
|
||||
|
@ -169,7 +182,11 @@ void Pattern::ParseFile(const wchar_t * file_name)
|
|||
|
||||
void Pattern::ParseString(const char * str)
|
||||
{
|
||||
AssignString(str, string_content);
|
||||
if( input_as_utf8 )
|
||||
UTF8ToWide(str, string_content);
|
||||
else
|
||||
AssignString(str, string_content);
|
||||
|
||||
ParseString(string_content.c_str());
|
||||
string_content.clear();
|
||||
}
|
||||
|
@ -243,16 +260,16 @@ void Pattern::UTF8(bool utf8)
|
|||
|
||||
void Pattern::SetCommentary(const char * com_start, const char * com_stop)
|
||||
{
|
||||
AssignString(com_start, commentary_start);
|
||||
AssignString(com_stop, commentary_stop);
|
||||
UTF8ToWide(com_start, commentary_start);
|
||||
UTF8ToWide(com_stop, commentary_stop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Pattern::SetCommentary(const std::string & com_start, const std::string & com_stop)
|
||||
{
|
||||
AssignString(com_start, commentary_start);
|
||||
AssignString(com_stop, commentary_stop);
|
||||
UTF8ToWide(com_start, commentary_start);
|
||||
UTF8ToWide(com_stop, commentary_stop);
|
||||
}
|
||||
|
||||
|
||||
|
@ -275,23 +292,6 @@ void Pattern::SetCommentary(const std::wstring & com_start, const std::wstring &
|
|||
|
||||
|
||||
|
||||
|
||||
void Pattern::CreateMsg(std::wstring & out, const char * type, const char * arg)
|
||||
{
|
||||
out = commentary_start;
|
||||
out += L"Ezc: ";
|
||||
AssignString(type, out, false);
|
||||
|
||||
if( arg )
|
||||
{
|
||||
out += ' ';
|
||||
AssignString(arg, out, false);
|
||||
}
|
||||
|
||||
out += commentary_stop;
|
||||
}
|
||||
|
||||
|
||||
void Pattern::CreateMsg(std::wstring & out, const wchar_t * type, const wchar_t * arg)
|
||||
{
|
||||
out = commentary_start;
|
||||
|
@ -409,12 +409,15 @@ bool Pattern::ReadFileFromDir(const std::wstring & dir, const wchar_t * name, st
|
|||
return false;
|
||||
}
|
||||
|
||||
ReadFile(file, result);
|
||||
|
||||
#ifdef EZC_USE_WINIX_LOGGER
|
||||
log << log3 << "Ezc: read pattern: " << afile_name << logend;
|
||||
if( include_level <= 1 )
|
||||
log << log3 << "Ezc: reading pattern: " << afile_name << logend;
|
||||
else
|
||||
log << log3 << " including pattern: " << afile_name << logend;
|
||||
#endif
|
||||
|
||||
ReadFile(file, result);
|
||||
|
||||
file_name.clear();
|
||||
afile_name.clear();
|
||||
|
||||
|
|
|
@ -41,9 +41,13 @@
|
|||
|
||||
#include <string>
|
||||
#include "item.h"
|
||||
#include "functions.h"
|
||||
#include "stringconv.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#ifdef EZC_USE_WINIX_LOGGER
|
||||
#include "core/log.h"
|
||||
#endif
|
||||
|
||||
|
||||
namespace Ezc
|
||||
|
@ -98,14 +102,18 @@ public:
|
|||
void SetCommentary(const wchar_t * com_start, const wchar_t * com_stop);
|
||||
void SetCommentary(const std::wstring & com_start, const std::wstring & com_stop);
|
||||
|
||||
void CreateMsg(std::wstring & out, const char * type, const char * arg = 0);
|
||||
void CreateMsg(std::wstring & out, const wchar_t * type, const wchar_t * arg = 0);
|
||||
static bool IsWhite(wchar_t c);
|
||||
|
||||
|
||||
|
||||
Item item_root;
|
||||
|
||||
template<class StreamType>
|
||||
void CacheFunctions(Functions<StreamType> & fun)
|
||||
{
|
||||
CacheFunctions(item_root, fun);
|
||||
}
|
||||
|
||||
void ClearCache();
|
||||
|
||||
private:
|
||||
|
||||
|
@ -203,6 +211,39 @@ private:
|
|||
void CreateTreeReadInclude(Item & item);
|
||||
void CreateTreeReadIncludeSkipAllowFlag(Item & item);
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void CacheFunctions(Item & item, Functions<StreamType> & fun)
|
||||
{
|
||||
typename Functions<StreamType>::Function * ezc_fun;
|
||||
|
||||
for(size_t f = 0; f < item.functions.size() ; ++f)
|
||||
{
|
||||
if( fun.Find(item.functions[f].name, &ezc_fun) )
|
||||
{
|
||||
item.functions[f].fun_cache = ezc_fun;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.functions[f].fun_cache = 0;
|
||||
|
||||
#ifdef EZC_USE_WINIX_LOGGER
|
||||
log << log1 << "Ezc: unknown function: " << item.functions[f].name << logend;
|
||||
#endif
|
||||
}
|
||||
|
||||
// one exception (if_index is putting its argument on the functions stack)
|
||||
if( item.type == Item::item_ifindex )
|
||||
break;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < item.item_tab.size() ; ++i)
|
||||
CacheFunctions(*item.item_tab[i], fun);
|
||||
}
|
||||
|
||||
|
||||
void ClearCache(Item & item);
|
||||
|
||||
}; // class Pattern
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue