added: possibility to define a block
changed: in Functions Functions are only for user-defined functions now (before they could remember a string variable too) added: class Vars for variables a variable can be a string or an alias to an other function or block added: now we can have nested functions calls e.g.: [function1 [function2]] in the above example an output (stream) from function2 will be passed as the first argument to funcion1 (will be passed as a string) removed: UTF8() method from PatternParser now it is treated that when we have only std::string (or char*) that this is an UTF-8 string git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@970 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
b5faf171e3
commit
71c5bd11d5
|
@ -1,8 +1,9 @@
|
|||
# DO NOT DELETE
|
||||
|
||||
item.o: item.h funinfo.h
|
||||
pattern.o: pattern.h item.h funinfo.h functions.h stringconv.h
|
||||
pattern.o: ../../pikotools/utf8/utf8.h
|
||||
patternparser.o: patternparser.h pattern.h item.h funinfo.h functions.h
|
||||
patternparser.o: stringconv.h ../../pikotools/utf8/utf8.h
|
||||
blocks.o: blocks.h item.h funinfo.h functions.h ../../pikotools/utf8/utf8.h
|
||||
item.o: item.h funinfo.h functions.h ../../pikotools/utf8/utf8.h
|
||||
pattern.o: pattern.h item.h funinfo.h functions.h ../../pikotools/utf8/utf8.h
|
||||
patternparser.o: patternparser.h blocks.h item.h funinfo.h functions.h
|
||||
patternparser.o: ../../pikotools/utf8/utf8.h pattern.h
|
||||
stringconv.o: stringconv.h
|
||||
vars.o: vars.h
|
||||
|
|
|
@ -1 +1 @@
|
|||
o = item.o pattern.o patternparser.o stringconv.o
|
||||
o = blocks.o item.o pattern.o patternparser.o stringconv.o vars.o
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#include "blocks.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
void Blocks::Insert(const std::wstring & name, const Item & item)
|
||||
{
|
||||
blocks_tab[name] = item;
|
||||
}
|
||||
|
||||
|
||||
Blocks::Iterator Blocks::Find(const std::wstring & name)
|
||||
{
|
||||
return blocks_tab.find(name);
|
||||
}
|
||||
|
||||
|
||||
Blocks::Iterator Blocks::Begin()
|
||||
{
|
||||
return blocks_tab.begin();
|
||||
}
|
||||
|
||||
|
||||
Blocks::Iterator Blocks::End()
|
||||
{
|
||||
return blocks_tab.end();
|
||||
}
|
||||
|
||||
|
||||
size_t Blocks::Size()
|
||||
{
|
||||
return blocks_tab.size();
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* This file is a part of EZC -- Easy templating in C++
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef headerfile_ezc_blocks
|
||||
#define headerfile_ezc_blocks
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "item.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
|
||||
class Blocks
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<std::wstring, Item> BlocksTable;
|
||||
typedef BlocksTable::iterator Iterator;
|
||||
|
||||
void Insert(const std::wstring & name, const Item & item);
|
||||
|
||||
Iterator Find(const std::wstring & name);
|
||||
|
||||
Iterator Begin();
|
||||
Iterator End();
|
||||
size_t Size();
|
||||
|
||||
private:
|
||||
|
||||
BlocksTable blocks_tab;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
146
src/functions.h
146
src/functions.h
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2012, Tomasz Sowa
|
||||
* Copyright (c) 2007-2014, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -39,8 +39,9 @@
|
|||
#define headerfile_ezc_functions
|
||||
|
||||
#include <map>
|
||||
#include "utf8/utf8.h"
|
||||
#include "funinfo.h"
|
||||
#include "stringconv.h"
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
|
@ -55,95 +56,43 @@ class Functions
|
|||
public:
|
||||
|
||||
typedef void (*UserFunction)(FunInfo<StreamType> &);
|
||||
enum Type { function, variable };
|
||||
|
||||
struct Function
|
||||
{
|
||||
Function();
|
||||
|
||||
Type type;
|
||||
UserFunction user_function; // used when type is 'function'
|
||||
std::wstring variable; // used when type is 'variable'
|
||||
};
|
||||
|
||||
typedef std::map<std::wstring, Function> FunctionsTable;
|
||||
typedef std::map<std::wstring, UserFunction> FunctionsTable;
|
||||
typedef typename FunctionsTable::iterator Iterator;
|
||||
|
||||
|
||||
void Insert(const char * key, UserFunction ufunction); // inserting a function
|
||||
void Insert(const char * key, const char * var); // inserting a variable
|
||||
void Insert(const char * key, const std::string & var); // inserting a variable
|
||||
void Insert(const std::string & key, UserFunction ufunction); // inserting a function
|
||||
void Insert(const std::string & key, const char * var); // inserting a variable
|
||||
void Insert(const std::string & key, const std::string & var); // inserting a variable
|
||||
void Insert(const char * key, UserFunction ufunction);
|
||||
void Insert(const std::string & key, UserFunction ufunction);
|
||||
void Insert(const wchar_t * key, UserFunction ufunction);
|
||||
void Insert(const std::wstring & key, UserFunction ufunction);
|
||||
void Insert(const std::wstring & key, const wchar_t * var);
|
||||
void Insert(const std::wstring & key, const std::wstring & var);
|
||||
|
||||
bool Find(const std::string & key, Function ** fun);
|
||||
bool Find(const std::wstring & key, Function ** fun);
|
||||
typename Iterator Find(const std::wstring & key);
|
||||
|
||||
Iterator Begin();
|
||||
Iterator End();
|
||||
size_t Size() const;
|
||||
void Clear();
|
||||
size_t Size() const;
|
||||
void Clear();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
FunctionsTable functions_tab;
|
||||
std::wstring temp_key;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
Functions<StreamType>::Function::Function()
|
||||
{
|
||||
type = Functions::variable;
|
||||
user_function = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const char * key, UserFunction ufunction)
|
||||
{
|
||||
Function f;
|
||||
f.type = function;
|
||||
f.user_function = ufunction;
|
||||
|
||||
AssignString(key, temp_key);
|
||||
functions_tab[temp_key] = f;
|
||||
PT::UTF8ToWide(key, temp_key);
|
||||
functions_tab[temp_key] = ufunction;
|
||||
temp_key.clear();
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const char * key, const char * var)
|
||||
{
|
||||
Function f;
|
||||
f.type = variable;
|
||||
AssignString(var, f.variable);
|
||||
|
||||
AssignString(key, temp_key);
|
||||
functions_tab[temp_key] = f;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const char * key, const std::string & var)
|
||||
{
|
||||
Function f;
|
||||
f.type = variable;
|
||||
AssignString(var, f.variable);
|
||||
|
||||
AssignString(key, temp_key);
|
||||
functions_tab[temp_key] = f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const std::string & key, UserFunction ufunction)
|
||||
{
|
||||
|
@ -152,54 +101,18 @@ void Functions<StreamType>::Insert(const std::string & key, UserFunction ufuncti
|
|||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const std::string & key, const char * var)
|
||||
void Functions<StreamType>::Insert(const wchar_t * key, UserFunction ufunction)
|
||||
{
|
||||
Insert(key.c_str(), var);
|
||||
temp_key = key;
|
||||
functions_tab[temp_key] = ufunction;
|
||||
temp_key.clear();
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const std::string & key, const std::string & var)
|
||||
{
|
||||
Insert(key.c_str(), var);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const std::wstring & key, UserFunction ufunction)
|
||||
{
|
||||
Function f;
|
||||
f.type = function;
|
||||
f.user_function = ufunction;
|
||||
|
||||
functions_tab[key] = f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const std::wstring & key, const wchar_t * var)
|
||||
{
|
||||
Function f;
|
||||
f.type = variable;
|
||||
f.variable = var;
|
||||
|
||||
functions_tab[key] = f;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const std::wstring & key, const std::wstring & var)
|
||||
{
|
||||
Function f;
|
||||
f.type = variable;
|
||||
f.variable = var;
|
||||
|
||||
functions_tab[key] = f;
|
||||
functions_tab[key] = ufunction;
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,25 +120,12 @@ void Functions<StreamType>::Insert(const std::wstring & key, const std::wstring
|
|||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Functions<StreamType>::Find(const std::string & key, Function ** fun)
|
||||
{
|
||||
AssignString(key, temp_key);
|
||||
return Find(temp_key, fun);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Functions<StreamType>::Find(const std::wstring & key, Function ** fun)
|
||||
typename Functions<StreamType>::Iterator Functions<StreamType>::Find(const std::wstring & key)
|
||||
{
|
||||
typename FunctionsTable::iterator i = functions_tab.find( key );
|
||||
|
||||
if( i == functions_tab.end() )
|
||||
return false;
|
||||
|
||||
*fun = &(i->second);
|
||||
|
||||
return true;
|
||||
return functions_tab.find(key);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -90,6 +90,15 @@ struct Stack
|
|||
Clear();
|
||||
}
|
||||
|
||||
~Stack()
|
||||
{
|
||||
if( fun_data && remove )
|
||||
{
|
||||
delete fun_data;
|
||||
fun_data = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
iter = 0;
|
||||
|
@ -107,17 +116,12 @@ struct FunInfo
|
|||
// output stream
|
||||
StreamType & out;
|
||||
|
||||
// the out stream is treated in case sensitive
|
||||
// used only in [is...] statements
|
||||
// default: true
|
||||
bool case_sensitive;
|
||||
|
||||
// table of parameters
|
||||
// the table can be empty
|
||||
std::vector<std::wstring> & params;
|
||||
|
||||
// the first parameter
|
||||
// you can always use it even if there is not any parameters (params is empty)
|
||||
// you can always use it even if there are not any parameters (params is empty)
|
||||
// in such a way the reference points to an empty string
|
||||
const std::wstring & par;
|
||||
|
||||
|
@ -129,7 +133,7 @@ struct FunInfo
|
|||
bool is_for;
|
||||
|
||||
// indicates that this function is from [if ...] statement
|
||||
// is true for all kind of if's: if-one, if-any, if-no....
|
||||
// it 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
|
||||
|
@ -141,28 +145,26 @@ struct FunInfo
|
|||
// indicates that this function is from a filter statement [filter ...]
|
||||
bool is_filter;
|
||||
|
||||
// a pointer to a stack's item from generator's stack
|
||||
// it is never null
|
||||
// a stack's item from generator's stack
|
||||
// each function has a new stack item
|
||||
// on this stack you have iter (description below) and fun_data pointer
|
||||
// you can assign to it your own object derived from FunData
|
||||
Stack * stack;
|
||||
Stack & stack;
|
||||
|
||||
// the same as stack->iter (this is mainly for backward compatibility)
|
||||
// the same as stack.iter (this is mainly for backward compatibility)
|
||||
// it indicates the number of a current iteration for the [for] statement (the first iteration is 0)
|
||||
// for other statements than [for] this is always zero
|
||||
size_t iter;
|
||||
|
||||
// return value from a user's function (default false if not set directly by the 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,
|
||||
const std::wstring & first_par,
|
||||
const StreamType & i) : out(o), params(pars), par(first_par), in(i)
|
||||
const StreamType & input_stream,
|
||||
Stack & s) : out(o), params(pars), par(first_par), in(input_stream), stack(s)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
@ -176,9 +178,7 @@ struct FunInfo
|
|||
is_is = false;
|
||||
is_normal = false;
|
||||
is_filter = false;
|
||||
stack = 0;
|
||||
iter = 0;
|
||||
case_sensitive = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
678
src/generator.h
678
src/generator.h
File diff suppressed because it is too large
Load Diff
14
src/item.cpp
14
src/item.cpp
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2011, Tomasz Sowa
|
||||
* Copyright (c) 2007-2014, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -161,5 +161,17 @@ Item::~Item()
|
|||
|
||||
|
||||
|
||||
void Item::ClearCache()
|
||||
{
|
||||
for(size_t f = 0; f < functions.size() ; ++f)
|
||||
functions[f].fun_cache = 0;
|
||||
|
||||
for(size_t i = 0; i < item_tab.size() ; ++i)
|
||||
item_tab[i]->ClearCache();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
|
103
src/item.h
103
src/item.h
|
@ -42,6 +42,7 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
#include "funinfo.h"
|
||||
#include "functions.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
|
@ -56,25 +57,79 @@ struct Item
|
|||
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_for, item_else, item_end, item_err, item_include, item_comment, item_def, item_filter,
|
||||
item_ezc
|
||||
item_ezc, item_block
|
||||
};
|
||||
|
||||
|
||||
struct Function
|
||||
{
|
||||
std::wstring name; // function name
|
||||
std::vector<std::wstring> params; // function parameters
|
||||
void * fun_cache;
|
||||
std::wstring name; // function name (can be empty, means there is no any function -- only a text parameter)
|
||||
std::wstring par; // parameter
|
||||
std::vector<Function*> parameters;
|
||||
void * fun_cache; // only valid if name is not empty
|
||||
Item * item_block;
|
||||
int arg; // used if name is numeric (if no then is equal -1)
|
||||
|
||||
|
||||
Function()
|
||||
{
|
||||
fun_cache = 0;
|
||||
fun_cache = 0;
|
||||
item_block = 0;
|
||||
arg = -1;
|
||||
}
|
||||
|
||||
~Function()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
Function(const Function & f)
|
||||
{
|
||||
operator=(f);
|
||||
}
|
||||
|
||||
Function & operator=(const Function & f)
|
||||
{
|
||||
name = f.name;
|
||||
par = f.par;
|
||||
fun_cache = f.fun_cache;
|
||||
item_block = f.item_block;
|
||||
arg = f.arg;
|
||||
|
||||
for(size_t i=0 ; i<f.parameters.size() ; ++i)
|
||||
parameters.push_back(new Function(*f.parameters[i]));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Function & AddNewParam()
|
||||
{
|
||||
parameters.push_back(new Function());
|
||||
|
||||
return *parameters.back();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for(size_t i=0 ; i<parameters.size() ; ++i)
|
||||
delete parameters[i];
|
||||
|
||||
parameters.clear();
|
||||
name.clear();
|
||||
par.clear();
|
||||
fun_cache = 0;
|
||||
item_block = 0;
|
||||
arg = -1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Type type;
|
||||
std::wstring text; // used in: item_text
|
||||
std::wstring file_name; // used in: item_include (as a file name)
|
||||
std::vector<Item*> item_tab; // childs
|
||||
std::vector<Item*> item_tab; // childs
|
||||
std::vector<Function> functions;
|
||||
|
||||
Item();
|
||||
|
@ -89,9 +144,45 @@ struct Item
|
|||
Type LastItemType();
|
||||
void DeleteLastItem();
|
||||
void Clear();
|
||||
|
||||
template<class StreamType>
|
||||
void CacheFunctions(Functions<StreamType> & fun);
|
||||
|
||||
void ClearCache();
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Item::CacheFunctions(Functions<StreamType> & fun)
|
||||
{
|
||||
// one exception (if_index is putting its argument on the functions stack)
|
||||
if( type != Item::item_ifindex )
|
||||
{
|
||||
for(size_t f=0; f < functions.size() ; ++f)
|
||||
{
|
||||
Functions<StreamType>::Iterator i = fun.Find(functions[f].name);
|
||||
|
||||
if( i != fun.End() )
|
||||
{
|
||||
functions[f].fun_cache = i->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
functions[f].fun_cache = 0;
|
||||
// teraz chyba nie trzeba tego logowac
|
||||
// bo mamy zmienne i identyfikator moze byc znaleziony w runtime
|
||||
// #ifdef EZC_USE_WINIX_LOGGER
|
||||
// Winix::log << Winix::log1 << "Ezc: unknown function: " << item.functions[f].name << Winix::logend;
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i=0; i < item_tab.size() ; ++i)
|
||||
item_tab[i]->CacheFunctions(fun);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
|
|
@ -60,22 +60,6 @@ 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]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -132,6 +116,8 @@ void Pattern::CreateMsg(std::wstring & out, const wchar_t * type, const wchar_t
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
|
|
|
@ -80,37 +80,7 @@ private:
|
|||
std::wstring commentary_start, commentary_stop;
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void CacheFunctions(Item & item, Functions<StreamType> & fun)
|
||||
{
|
||||
typename Functions<StreamType>::Function * ezc_fun;
|
||||
|
||||
// one exception (if_index is putting its argument on the functions stack)
|
||||
if( item.type != Item::item_ifindex )
|
||||
{
|
||||
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
|
||||
Winix::log << Winix::log1 << "Ezc: unknown function: " << item.functions[f].name << Winix::logend;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i=0; i < item.item_tab.size() ; ++i)
|
||||
CacheFunctions(*item.item_tab[i], fun);
|
||||
}
|
||||
|
||||
|
||||
void ClearCache(Item & item);
|
||||
|
||||
}; // class Pattern
|
||||
|
||||
|
|
|
@ -48,10 +48,9 @@ namespace Ezc
|
|||
PatternParser::PatternParser()
|
||||
{
|
||||
allow_include = true;
|
||||
input_as_utf8 = true;
|
||||
pblocks = 0;
|
||||
include_level_max = 100;
|
||||
delete_white_text_items = false;
|
||||
|
||||
include_level_max = 100;
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,6 +115,12 @@ void PatternParser::Directory(const std::wstring & dir, const std::wstring & dir
|
|||
|
||||
|
||||
|
||||
void PatternParser::SetBlocks(Blocks & blocks)
|
||||
{
|
||||
pblocks = &blocks;
|
||||
}
|
||||
|
||||
|
||||
void PatternParser::ParseFile(const std::string & file_name, Pattern & pattern)
|
||||
{
|
||||
ParseFile(file_name.c_str(), pattern);
|
||||
|
@ -156,11 +161,7 @@ void PatternParser::ParseFile(const wchar_t * file_name, Pattern & pattern)
|
|||
|
||||
void PatternParser::ParseString(const char * str, Pattern & pattern)
|
||||
{
|
||||
if( input_as_utf8 )
|
||||
PT::UTF8ToWide(str, string_content);
|
||||
else
|
||||
AssignString(str, string_content);
|
||||
|
||||
PT::UTF8ToWide(str, string_content);
|
||||
ParseString(string_content.c_str(), pattern);
|
||||
string_content.clear();
|
||||
}
|
||||
|
@ -218,16 +219,6 @@ void PatternParser::SetIncludeMax(int include_max)
|
|||
|
||||
|
||||
|
||||
void PatternParser::UTF8(bool utf8)
|
||||
{
|
||||
input_as_utf8 = utf8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -343,38 +334,13 @@ return true;
|
|||
|
||||
|
||||
|
||||
|
||||
void PatternParser::ReadFile(std::ifstream & file, std::wstring & result)
|
||||
{
|
||||
if( input_as_utf8 )
|
||||
{
|
||||
PT::UTF8ToWide(file, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadFileContent(file, result);
|
||||
}
|
||||
PT::UTF8ToWide(file, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PatternParser::ReadFileContent(std::ifstream & file, std::wstring & result)
|
||||
{
|
||||
while( true )
|
||||
{
|
||||
int c = file.get();
|
||||
|
||||
if( !file )
|
||||
break;
|
||||
|
||||
result += static_cast<wchar_t>(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int PatternParser::ReadCharInText()
|
||||
{
|
||||
if( *itext==0 || *itext=='[' )
|
||||
|
@ -519,14 +485,38 @@ return true;
|
|||
|
||||
bool PatternParser::ReadParams(Item::Function & function)
|
||||
{
|
||||
function.params.clear();
|
||||
while( true )
|
||||
{
|
||||
SkipWhite();
|
||||
|
||||
while( ReadString(temp_param) )
|
||||
function.params.push_back(temp_param);
|
||||
if( *itext == '[' )
|
||||
{
|
||||
++itext; // skipping '['
|
||||
ReadFunction(function.AddNewParam());
|
||||
|
||||
temp_param.clear();
|
||||
SkipWhite();
|
||||
if( *itext == ']' )
|
||||
++itext;
|
||||
}
|
||||
else
|
||||
if( *itext == '\"' )
|
||||
{
|
||||
if( ReadString(temp_param) )
|
||||
{
|
||||
Item::Function & fun = function.AddNewParam();
|
||||
fun.par = temp_param;
|
||||
// fun.name is empty so it is treated as a text parameter
|
||||
}
|
||||
|
||||
return !function.params.empty();
|
||||
temp_param.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !function.parameters.empty();
|
||||
}
|
||||
|
||||
|
||||
|
@ -534,13 +524,14 @@ return !function.params.empty();
|
|||
bool PatternParser::ReadFunction(Item::Function & function)
|
||||
{
|
||||
SkipWhite();
|
||||
|
||||
function.name.clear();
|
||||
function.params.clear();
|
||||
function.Clear();
|
||||
|
||||
if( !ReadName(function.name) )
|
||||
return false;
|
||||
|
||||
if( IsPositiveNumber(function.name) )
|
||||
function.arg = wcstol(function.name.c_str(), 0, 10);
|
||||
|
||||
ReadParams(function);
|
||||
|
||||
return true;
|
||||
|
@ -556,8 +547,7 @@ bool PatternParser::ReadFunctions(Item & item)
|
|||
while( ReadFunction(temp_function) )
|
||||
item.functions.push_back(temp_function);
|
||||
|
||||
temp_function.name.clear();
|
||||
temp_function.params.clear();
|
||||
temp_function.Clear();
|
||||
|
||||
return !item.functions.empty();
|
||||
}
|
||||
|
@ -667,11 +657,25 @@ void PatternParser::ReadDirectiveIsno(Item & item)
|
|||
|
||||
|
||||
|
||||
void PatternParser::ReadDirectiveEnd(Item & item)
|
||||
{
|
||||
item.type = Item::item_end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PatternParser::ReadDirectiveElse(Item & item)
|
||||
{
|
||||
item.type = Item::item_else;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PatternParser::ReadDirectiveIfindex(Item & item)
|
||||
{
|
||||
item.type = Item::item_err;
|
||||
item.functions.clear();
|
||||
temp_function.params.clear();
|
||||
temp_function.Clear();
|
||||
|
||||
// reading: odd, even, first or a number (without quotes)
|
||||
if( !ReadName(temp_function.name) )
|
||||
|
@ -724,24 +728,23 @@ void PatternParser::ReadDirectiveDef(Item & item)
|
|||
item.type = Item::item_err;
|
||||
ReadFunctions(item);
|
||||
|
||||
if( item.functions.size() == 1 )
|
||||
if( item.functions.size() == 1 && item.functions[0].parameters.size() == 1 )
|
||||
{
|
||||
if( item.functions[0].params.size() == 1 )
|
||||
{
|
||||
// this is: [def variable "value"]
|
||||
item.type = Item::item_def;
|
||||
}
|
||||
// it is [def name "value"]
|
||||
// or [def name [otherfunction]]
|
||||
// or [def name [otherfunction "argument"]] etc.
|
||||
|
||||
item.type = Item::item_def;
|
||||
}
|
||||
else
|
||||
if( item.functions.size() == 2 )
|
||||
if( item.functions.size() == 2 &&
|
||||
item.functions[0].parameters.empty() && item.functions[1].parameters.empty() )
|
||||
{
|
||||
if( item.functions[0].params.empty() && item.functions[1].params.empty())
|
||||
{
|
||||
// this is:
|
||||
// [def variable2 variable1], or
|
||||
// [def function2 function1]
|
||||
item.type = Item::item_def;
|
||||
}
|
||||
// it is an alias:
|
||||
// [def name function]
|
||||
// (name is an alias to a function, to a block or to an other variable)
|
||||
|
||||
item.type = Item::item_def;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -762,14 +765,30 @@ void PatternParser::ReadDirectiveEzc(Item & item)
|
|||
ReadFunctions(item);
|
||||
}
|
||||
|
||||
void PatternParser::ReadDirectiveBlock(Item & item)
|
||||
{
|
||||
item.type = Item::item_block;
|
||||
ReadFunctions(item);
|
||||
|
||||
// only one function without arguments
|
||||
if( item.functions.size() != 1 || !item.functions[0].parameters.empty() )
|
||||
item.type = Item::item_err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// user defined directive
|
||||
void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item)
|
||||
{
|
||||
temp_function.name = name;
|
||||
temp_function.Clear();
|
||||
ReadParams(temp_function);
|
||||
temp_function.name = name;
|
||||
|
||||
if( IsPositiveNumber(name) )
|
||||
temp_function.arg = wcstol(name.c_str(), 0, 10);
|
||||
|
||||
item.functions.clear();
|
||||
|
||||
item.functions.push_back(temp_function);
|
||||
item.type = Item::item_normal;
|
||||
}
|
||||
|
@ -792,13 +811,14 @@ std::wstring name;
|
|||
else if( name == L"if-index" ) ReadDirectiveIfindex(item);
|
||||
else if( name == L"is" ) ReadDirectiveIs(item);
|
||||
else if( name == L"is-no" ) ReadDirectiveIsno(item);
|
||||
else if( name == L"end" ) item.type = Item::item_end;
|
||||
else if( name == L"else" ) item.type = Item::item_else;
|
||||
else if( name == L"end" ) ReadDirectiveEnd(item);
|
||||
else if( name == L"else" ) ReadDirectiveElse(item);
|
||||
else if( name == L"for" ) ReadDirectiveFor(item);
|
||||
else if( name == L"include" ) ReadDirectiveInclude(item);
|
||||
else if( name == L"def" ) ReadDirectiveDef(item);
|
||||
else if( name == L"filter" ) ReadDirectiveFilter(item);
|
||||
else if( name == L"ezc" ) ReadDirectiveEzc(item);
|
||||
else if( name == L"block" ) ReadDirectiveBlock(item);
|
||||
else if( name == L"#" ) ReadDirectiveComment(item);
|
||||
else
|
||||
ReadDirectiveNormal(name, item);
|
||||
|
@ -904,6 +924,21 @@ void PatternParser::CreateTreeReadIf(Item & item)
|
|||
|
||||
|
||||
|
||||
void PatternParser::CreateTreeReadBlock(Item & item)
|
||||
{
|
||||
Item item_block;
|
||||
|
||||
CreateTree(item_block);
|
||||
|
||||
if( item_block.LastItemType() == Item::item_end )
|
||||
item_block.DeleteLastItem();
|
||||
|
||||
if( pblocks && item.functions.size()==1 )
|
||||
pblocks->Insert(item.functions[0].name, item_block);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PatternParser::CreateTreeReadFor(Item & item)
|
||||
{
|
||||
Item * pitem = item.AddItem();
|
||||
|
@ -931,8 +966,12 @@ void PatternParser::CreateTree(Item & item)
|
|||
item.DeleteLastItem();
|
||||
return;
|
||||
}
|
||||
|
||||
if( pitem->type == Item::item_block )
|
||||
CreateTreeReadBlock(*pitem);
|
||||
}
|
||||
while( pitem->type == Item::item_comment );
|
||||
while( pitem->type == Item::item_comment ||
|
||||
pitem->type == Item::item_block );
|
||||
|
||||
if( pitem->type == Item::item_end || pitem->type == Item::item_else )
|
||||
return;
|
||||
|
@ -954,6 +993,8 @@ void PatternParser::CreateTree(Item & item)
|
|||
|
||||
if( pitem->type == Item::item_include )
|
||||
CreateTreeReadInclude(*pitem);
|
||||
|
||||
// item_def is ignored here
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
#ifndef headerfile_ezc_patternparser
|
||||
#define headerfile_ezc_patternparser
|
||||
|
||||
#include "blocks.h"
|
||||
#include "pattern.h"
|
||||
#include "stringconv.h"
|
||||
#include "utf8/utf8.h"
|
||||
|
||||
#ifdef EZC_USE_WINIX_LOGGER
|
||||
|
@ -83,11 +83,7 @@ public:
|
|||
void DeleteWhiteTextItems(bool del);
|
||||
void SetIncludeMax(int include_max);
|
||||
|
||||
// files and strings (only char* and std::string) are treated
|
||||
// as UTF-8
|
||||
void UTF8(bool utf8);
|
||||
|
||||
|
||||
void SetBlocks(Blocks & blocks);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -114,8 +110,7 @@ private:
|
|||
// we read from these directories only if they are not empty
|
||||
std::wstring directory, directory2;
|
||||
|
||||
|
||||
bool input_as_utf8;
|
||||
|
||||
|
||||
int include_level, include_level_max;
|
||||
|
||||
|
@ -135,6 +130,7 @@ private:
|
|||
// temporary object for a EZC function
|
||||
Item::Function temp_function;
|
||||
|
||||
Blocks * pblocks;
|
||||
|
||||
|
||||
void ReadFile(const std::wstring & name, std::wstring & result);
|
||||
|
@ -143,7 +139,6 @@ private:
|
|||
bool IsFileCorrect(const wchar_t * name);
|
||||
bool ReadFileFromDir(const std::wstring & dir, const wchar_t * name, std::wstring & result);
|
||||
void ReadFile(std::ifstream & file, std::wstring & result);
|
||||
void ReadFileContent(std::ifstream & file, std::wstring & result);
|
||||
|
||||
int ReadCharInText();
|
||||
bool IsWhite(wchar_t c);
|
||||
|
@ -168,6 +163,8 @@ private:
|
|||
void ReadDirectiveIfoneno(Item & item);
|
||||
void ReadDirectiveIs(Item & item);
|
||||
void ReadDirectiveIsno(Item & item);
|
||||
void ReadDirectiveEnd(Item & item);
|
||||
void ReadDirectiveElse(Item & item);
|
||||
void ReadDirectiveIfindex(Item & item);
|
||||
void ReadDirectiveFor(Item & item);
|
||||
void ReadDirectiveComment(Item & item);
|
||||
|
@ -175,6 +172,7 @@ private:
|
|||
void ReadDirectiveDef(Item & item);
|
||||
void ReadDirectiveFilter(Item & item);
|
||||
void ReadDirectiveEzc(Item & item);
|
||||
void ReadDirectiveBlock(Item & item);
|
||||
void ReadDirectiveNormal(const std::wstring & name, Item & item);
|
||||
|
||||
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
||||
|
@ -182,6 +180,7 @@ private:
|
|||
void CreateTreeReadItemText(Item & item);
|
||||
bool CreateTreeReadItem(Item & item);
|
||||
void CreateTreeReadIf(Item & item);
|
||||
void CreateTreeReadBlock(Item & item);
|
||||
void CreateTreeReadFor(Item & item);
|
||||
void CreateTree(Item & item);
|
||||
void CreateTreeReadInclude(Item & item);
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
#include "vars.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
void Vars::Insert(const std::wstring & name, VariableType type, const std::wstring & value)
|
||||
{
|
||||
Variable variable;
|
||||
|
||||
variable.type = type;
|
||||
variable.val = value;
|
||||
|
||||
vars_tab[name] = variable;
|
||||
}
|
||||
|
||||
|
||||
Vars::Iterator Vars::Find(const std::wstring & name)
|
||||
{
|
||||
return vars_tab.find(name);
|
||||
}
|
||||
|
||||
|
||||
Vars::Iterator Vars::Begin()
|
||||
{
|
||||
return vars_tab.begin();
|
||||
}
|
||||
|
||||
|
||||
Vars::Iterator Vars::End()
|
||||
{
|
||||
return vars_tab.end();
|
||||
}
|
||||
|
||||
|
||||
size_t Vars::Size()
|
||||
{
|
||||
return vars_tab.size();
|
||||
}
|
||||
|
||||
|
||||
} // namespace
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* This file is a part of EZC -- Easy templating in C++
|
||||
* and is distributed under the (new) BSD licence.
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name Tomasz Sowa nor the names of contributors to this
|
||||
* project may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef headerfile_ezc_vars
|
||||
#define headerfile_ezc_vars
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
|
||||
class Vars
|
||||
{
|
||||
public:
|
||||
|
||||
enum VariableType
|
||||
{
|
||||
variable_string,
|
||||
variable_alias
|
||||
};
|
||||
|
||||
struct Variable
|
||||
{
|
||||
VariableType type;
|
||||
std::wstring val;
|
||||
};
|
||||
|
||||
typedef std::map<std::wstring, Variable> VariablesTable;
|
||||
typedef VariablesTable::iterator Iterator;
|
||||
|
||||
void Insert(const std::wstring & name, VariableType type, const std::wstring & value);
|
||||
|
||||
Iterator Find(const std::wstring & name);
|
||||
|
||||
Iterator Begin();
|
||||
Iterator End();
|
||||
size_t Size();
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
|
||||
VariablesTable vars_tab;
|
||||
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue