added: support for UTF-8 (files utf8.h utf8.cpp)
they can be even used without the rest library as only a library for converting between wide characters and UTF-8 changed: everywhere we use std::wstring instead of std::string changed: Generator and Functions are templates now they take a stream type renamed: Info to FunInfo and it is a template too taking a stream type now you can use other kind of streams with the library previous was only std::ostringstream git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@326 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
b5ea2514e2
commit
8f94937ed1
|
@ -1,3 +1,9 @@
|
|||
# DO NOT DELETE
|
||||
|
||||
edanticezc.o: ezc.h /home/tomek/roboczy/winix/core/log.h
|
||||
edanticitem.o: item.h
|
||||
edanticpattern.o: pattern.h item.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
|
||||
edanticstringconv.o: stringconv.h
|
||||
edanticutf8.o: utf8.h
|
||||
|
|
|
@ -1 +1 @@
|
|||
o = ezc.o
|
||||
o = item.o pattern.o stringconv.o utf8.o
|
||||
|
|
1669
src/ezc.cpp
1669
src/ezc.cpp
File diff suppressed because it is too large
Load Diff
330
src/ezc.h
330
src/ezc.h
|
@ -36,334 +36,12 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef headerfileezc
|
||||
#define headerfileezc
|
||||
#ifndef headerfile_ezc_ezc
|
||||
#define headerfile_ezc_ezc
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
class Pattern
|
||||
{
|
||||
public:
|
||||
|
||||
Pattern();
|
||||
|
||||
void ParseFile(const std::string & file_name);
|
||||
void ParseFile(const char * file_name);
|
||||
void ParseString(const std::string & str);
|
||||
void ParseString(const char * str);
|
||||
|
||||
// first we're trying to read a file from directory dir
|
||||
// if there is no such a file there then we try read from dir2
|
||||
// (the second dir2 can be empty - it will not be used)
|
||||
void Directory(const char * dir, const char * dir2 = 0);
|
||||
void Directory(const std::string & dir);
|
||||
void Directory(const std::string & dir, const std::string & dir2);
|
||||
|
||||
void AllowInclude(bool allow);
|
||||
void DeleteWhiteTextItems(bool del);
|
||||
|
||||
void SetCommentary(const char * com_start, const char * com_stop);
|
||||
void SetCommentary(const std::string & com_start, const std::string & com_stop);
|
||||
|
||||
void SetIncludeMax(int include_max);
|
||||
|
||||
void Clear();
|
||||
|
||||
|
||||
void CreateMsg(std::ostringstream & o, const char * type, const char * arg = 0);
|
||||
std::string CreateMsg(const char * type, const char * arg = 0);
|
||||
|
||||
bool IsWhite(int c);
|
||||
|
||||
|
||||
|
||||
struct Item
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
struct Function
|
||||
{
|
||||
std::string name; // function name
|
||||
std::vector<std::string> params; // function parameters
|
||||
};
|
||||
|
||||
Type type;
|
||||
std::string text; // used in: item_text, item_include (as a file name)
|
||||
std::vector<Item*> item_tab; // !! zamienic na 'items'?
|
||||
std::vector<Function> functions;
|
||||
|
||||
Item();
|
||||
Item(const Item & i);
|
||||
Item & operator=(const Item & i);
|
||||
void CopyItemTable(const Item & i);
|
||||
~Item();
|
||||
|
||||
Item * AddItem(const Item * porg = 0);
|
||||
Item * AddItem(const Item & porg);
|
||||
void ClearItems();
|
||||
Type LastItemType();
|
||||
void DeleteLastItem();
|
||||
void Clear();
|
||||
};
|
||||
|
||||
Item item_root;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
const char * itext;
|
||||
|
||||
// allowing include tag
|
||||
// default: true
|
||||
bool allow_include;
|
||||
|
||||
// if true all text-items which have only white characters (with new lines as well)
|
||||
// will be deleted - useful in *.txt templates
|
||||
// this not actually delete the whole item but only the string
|
||||
// the item will be present with an empty string
|
||||
// default: false
|
||||
bool delete_white_text_items;
|
||||
|
||||
// first we're trying to read a file from 'directory'
|
||||
// if there is no such a file there then we try read from 'directory2'
|
||||
// we read from these directories only if they are not empty
|
||||
std::string directory, directory2;
|
||||
|
||||
int include_level, include_level_max;
|
||||
|
||||
|
||||
|
||||
std::string commentary_start, commentary_stop;
|
||||
|
||||
|
||||
|
||||
|
||||
std::string ReadFile(const std::string & name);
|
||||
std::string ReadFile(const char * name);
|
||||
bool HasFileAtBeginning(const char * path, const char * file);
|
||||
bool IsFileCorrect(const char * name);
|
||||
bool ReadFileFromDir(const std::string & dir, const char * name, std::string & result);
|
||||
|
||||
int ReadCharInText();
|
||||
void SkipWhite();
|
||||
void CheckWhiteAndDelete(std::string & s);
|
||||
|
||||
bool IsNameChar(int c);
|
||||
bool IsDigit(int c);
|
||||
bool IsPositiveNumber(const std::string & str);
|
||||
|
||||
bool ReadName(std::string & name);
|
||||
bool ReadString(std::string & str);
|
||||
bool ReadFunction(Item::Function & function);
|
||||
bool ReadParams(Item::Function & function);
|
||||
bool ReadFunctions(Item & item);
|
||||
|
||||
void ReadDirectiveIf(Item & item);
|
||||
void ReadDirectiveIfno(Item & item);
|
||||
void ReadDirectiveIfany(Item & item);
|
||||
void ReadDirectiveIfone(Item & item);
|
||||
void ReadDirectiveIfanyno(Item & item);
|
||||
void ReadDirectiveIfoneno(Item & item);
|
||||
void ReadDirectiveIs(Item & item);
|
||||
void ReadDirectiveIsno(Item & item);
|
||||
void ReadDirectiveIfindex(Item & item);
|
||||
void ReadDirectiveFor(Item & item);
|
||||
void ReadDirectiveComment(Item & item);
|
||||
void ReadDirectiveInclude(Item & item);
|
||||
void ReadDirectiveDef(Item & item);
|
||||
void ReadDirectiveNormal(const std::string & name, Item & item);
|
||||
|
||||
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
||||
void CreateTreeReadItemDirective(Item & item);
|
||||
void CreateTreeReadItemText(Item & item);
|
||||
bool CreateTreeReadItem(Item & item);
|
||||
void CreateTreeReadIf(Item & item);
|
||||
void CreateTreeReadFor(Item & item);
|
||||
void CreateTree(Item & item);
|
||||
void CreateTreeReadInclude(Item & item);
|
||||
void CreateTreeReadIncludeSkipAllowFlag(Item & item);
|
||||
|
||||
}; // class Pattern
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct Info
|
||||
{
|
||||
// output stream
|
||||
std::ostringstream & out;
|
||||
|
||||
// table of parameters
|
||||
std::vector<std::string> & params;
|
||||
|
||||
// the first parameter
|
||||
// you can always use it even if there is not any parameters
|
||||
// in such a way the reference points to an empty valid string
|
||||
const std::string & par;
|
||||
|
||||
// this is set by Generator
|
||||
// normally is 0
|
||||
// in a [for] statement it indicates the number of the current iteration (the first is 0)
|
||||
int iter;
|
||||
|
||||
// return value from a user function (default false if not set directly by the user function)
|
||||
// for a variable it is set to true if the variable is not empty
|
||||
bool res;
|
||||
|
||||
// arguments: output_stream, table_of_parameters, the_first_parameter
|
||||
Info(std::ostringstream & o, std::vector<std::string> & pars, const std::string & p);
|
||||
void Clear();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// functions or variables
|
||||
class Functions
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void (*UserFunction)(Info &);
|
||||
enum Type { function, variable };
|
||||
|
||||
struct Function
|
||||
{
|
||||
Type type;
|
||||
|
||||
UserFunction user_function; // used when type is 'function'
|
||||
std::string variable; // used when type is 'variable'
|
||||
|
||||
int iter;
|
||||
bool is_for; // true if is used by a [for] statement
|
||||
bool is_running; // true if this function is currently executed
|
||||
|
||||
Function();
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
bool Find(const std::string & key, Function ** fun);
|
||||
void Clear();
|
||||
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, Function> FunctionsTable;
|
||||
FunctionsTable functions_tab;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Generator
|
||||
{
|
||||
public:
|
||||
|
||||
Generator();
|
||||
Generator(std::ostringstream & o, Pattern & p, Functions & f);
|
||||
|
||||
void Set(std::ostringstream & o, Pattern & p, Functions & f);
|
||||
void Set(std::ostringstream & o);
|
||||
void Set(Pattern & p);
|
||||
void Set(Functions & f);
|
||||
void SetMax(int max_items_, int max_for_items_);
|
||||
|
||||
// recognizing some special characters in text patterns (item_text in Patterns)
|
||||
// \r will be a carriage return (13)
|
||||
// \n will be a new line (10)
|
||||
// \t will be a tabulator (9)
|
||||
// \s will be a space
|
||||
// \\ will be one '\'
|
||||
// default: false
|
||||
void RecognizeSpecialChars(bool spec);
|
||||
|
||||
// trimming white characters (at the beginning and at the end of an item_text)
|
||||
// (special char \s if enabled is not treated as a white character here)
|
||||
// default: false
|
||||
void TrimWhite(bool trim);
|
||||
|
||||
// skipping new line characters (from the whole string in an item_text)
|
||||
// but you can use a new line character written as "\n" (if special chars are turn on)
|
||||
// default: false
|
||||
void SkipNewLine(bool skip);
|
||||
|
||||
|
||||
void Generate();
|
||||
|
||||
private:
|
||||
|
||||
std::ostringstream * output_stream;
|
||||
Pattern * pattern;
|
||||
Functions * functions;
|
||||
|
||||
bool break_generating;
|
||||
int current_item;
|
||||
int max_items;
|
||||
int max_for_items;
|
||||
bool special_chars;
|
||||
bool trim_white;
|
||||
bool skip_new_line;
|
||||
|
||||
// an empty string for info objects
|
||||
const std::string empty;
|
||||
|
||||
bool Find(const std::string & key, Functions::Function ** function);
|
||||
|
||||
void Call(Functions::Function * function, Info & info);
|
||||
bool Call(const std::string & name, Info & info, Functions::Function ** pfun = 0);
|
||||
bool Call(Pattern::Item::Function & function, bool * info_res = 0, Functions::Function ** pfun = 0);
|
||||
|
||||
void CallUserFunction(Functions::Function * function, Info & info);
|
||||
void CallVariable(Functions::Function * function, Info & info);
|
||||
|
||||
char CreateSpecialChar(char c);
|
||||
void PrintSpecialText(const char * start, const char * end);
|
||||
void PrintNormalText(const char * start, const char * end);
|
||||
void TrimWhite(const char *& start, const char *& end);
|
||||
|
||||
void MakeTextIf_go(Pattern::Item & item, bool result);
|
||||
bool MakeTextIfindexnumber(Pattern::Item & item, Functions::Function * function, bool & result);
|
||||
void MakeTextIf(Pattern::Item & item);
|
||||
void MakeTextIfno(Pattern::Item & item);
|
||||
void MakeTextIfany(Pattern::Item & item);
|
||||
void MakeTextIfone(Pattern::Item & item);
|
||||
void MakeTextIfanyno(Pattern::Item & item);
|
||||
void MakeTextIfoneno(Pattern::Item & item);
|
||||
void MakeTextIfindex(Pattern::Item & item);
|
||||
void MakeTextForLoop(Pattern::Item & item, Functions::Function * function);
|
||||
void MakeTextFor(Pattern::Item & item);
|
||||
void MakeItemText(Pattern::Item & item);
|
||||
void MakeTextContainer(Pattern::Item & item);
|
||||
void MakeTextNormal(Pattern::Item & item);
|
||||
void MakeTextIs(Pattern::Item & item);
|
||||
void MakeTextIsno(Pattern::Item & item);
|
||||
void MakeTextDefine(Pattern::Item & item);
|
||||
void MakeText(Pattern::Item & item);
|
||||
|
||||
}; // class Generator
|
||||
|
||||
} // namespace Ezc
|
||||
#include "utf8.h"
|
||||
#include "generator.h"
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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_functions
|
||||
#define headerfile_ezc_functions
|
||||
|
||||
#include <map>
|
||||
#include "funinfo.h"
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
|
||||
// functions or variables
|
||||
template<class StreamType>
|
||||
class Functions
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void (*UserFunction)(FunInfo<StreamType> &);
|
||||
enum Type { function, variable };
|
||||
|
||||
struct Function
|
||||
{
|
||||
Type type;
|
||||
|
||||
UserFunction user_function; // used when type is 'function'
|
||||
std::wstring variable; // used when type is 'variable'
|
||||
|
||||
int iter;
|
||||
bool is_for; // true if is used by a [for] statement
|
||||
bool is_running; // true if this function is currently executed
|
||||
|
||||
Function();
|
||||
};
|
||||
|
||||
|
||||
|
||||
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 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);
|
||||
void Clear();
|
||||
|
||||
|
||||
private:
|
||||
typedef std::map<std::wstring, Function> FunctionsTable;
|
||||
FunctionsTable functions_tab;
|
||||
std::wstring temp_key;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
Functions<StreamType>::Function::Function()
|
||||
{
|
||||
type = Functions::variable;
|
||||
user_function = 0;
|
||||
iter = 0;
|
||||
is_for = false;
|
||||
is_running = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
Insert(key.c_str(), ufunction);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Insert(const std::string & key, const char * var)
|
||||
{
|
||||
Insert(key.c_str(), var);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 FunctionsTable::iterator i = functions_tab.find( key );
|
||||
|
||||
if( i == functions_tab.end() )
|
||||
return false;
|
||||
|
||||
*fun = &(i->second);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Functions<StreamType>::Clear()
|
||||
{
|
||||
functions_tab.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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_info
|
||||
#define headerfile_ezc_info
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
struct FunInfo
|
||||
{
|
||||
// output stream
|
||||
StreamType & out;
|
||||
|
||||
// table of parameters
|
||||
std::vector<std::wstring> & params;
|
||||
|
||||
// the first parameter
|
||||
// you can always use it even if there is not any parameters
|
||||
// in such a way the reference points to an empty string
|
||||
const std::wstring & par;
|
||||
|
||||
// this is set by Generator
|
||||
// normally is 0
|
||||
// in a [for] statement it indicates the number of the current iteration (the first is 0)
|
||||
int iter;
|
||||
|
||||
// return value from a user function (default false if not set directly by the user function)
|
||||
// for a variable it is set to true if the variable is not empty
|
||||
bool res;
|
||||
|
||||
// arguments: output_stream, table_of_parameters, the_first_parameter
|
||||
FunInfo(StreamType & o, std::vector<std::wstring> & pars, const std::wstring & p) : out(o), params(pars), par(p)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
res = false; // false by default
|
||||
iter = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,996 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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_generator
|
||||
#define headerfile_ezc_generator
|
||||
|
||||
#include "pattern.h"
|
||||
#include "functions.h"
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
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)
|
||||
// \r will be a carriage return (13)
|
||||
// \n will be a new line (10)
|
||||
// \t will be a tabulator (9)
|
||||
// \s will be a space
|
||||
// \\ will be one '\'
|
||||
// default: false
|
||||
void RecognizeSpecialChars(bool spec);
|
||||
|
||||
// trimming white characters (at the beginning and at the end of an item_text)
|
||||
// (special char \s if enabled is not treated as a white character here)
|
||||
// default: false
|
||||
void TrimWhite(bool trim);
|
||||
|
||||
// skipping new line characters (from the whole string in an item_text)
|
||||
// but you can use a new line character written as "\n" (if special chars are turn on)
|
||||
// default: false
|
||||
void SkipNewLine(bool skip);
|
||||
|
||||
|
||||
void Generate();
|
||||
|
||||
private:
|
||||
|
||||
StreamType * output_stream;
|
||||
Pattern * pattern;
|
||||
Functions<StreamType> * functions;
|
||||
|
||||
// temporary error messages
|
||||
std::wstring temp_msg;
|
||||
|
||||
bool break_generating;
|
||||
int current_item;
|
||||
int max_items;
|
||||
int max_for_items;
|
||||
bool special_chars;
|
||||
bool trim_white;
|
||||
bool skip_new_line;
|
||||
|
||||
// an empty string for info objects
|
||||
// when there is no any parameters
|
||||
const std::wstring empty;
|
||||
|
||||
|
||||
void PutChar(wchar_t z, StreamType & out);
|
||||
void PutStringGeneric(const wchar_t * start, size_t len, StreamType & out);
|
||||
|
||||
|
||||
// !! tu bedzie chyba problem z kompilacja
|
||||
// kiedy typ strumienia to bedzie std::ostream
|
||||
// chwilowo zostawiam jak jest
|
||||
|
||||
/*
|
||||
void PutString(const wchar_t * start, const wchar_t * end, std::ostream & out)
|
||||
{
|
||||
PutStringGeneric(start, end-start, out);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PutString(const wchar_t * start, const wchar_t * end, std::iostream & out)
|
||||
{
|
||||
PutStringGeneric(start, end-start, out);
|
||||
}
|
||||
|
||||
|
||||
void PutString(const wchar_t * start, const wchar_t * end, std::ofstream & out)
|
||||
{
|
||||
PutStringGeneric(start, end-start, out);
|
||||
}
|
||||
|
||||
|
||||
void PutString(const wchar_t * start, const wchar_t * end, std::fstream & out)
|
||||
{
|
||||
PutStringGeneric(start, end-start, out);
|
||||
}
|
||||
|
||||
|
||||
void PutString(const wchar_t * start, const wchar_t * end, std::ostringstream & out)
|
||||
{
|
||||
PutStringGeneric(start, end-start, out);
|
||||
}
|
||||
|
||||
|
||||
void PutString(const wchar_t * start, const wchar_t * end, std::stringstream & out)
|
||||
{
|
||||
PutStringGeneric(start, end-start, out);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void PutString(const std::wstring & str, StreamType & out)
|
||||
{
|
||||
PutString(str.c_str(), str.c_str() + str.size(), out);
|
||||
}
|
||||
|
||||
void PutString(const wchar_t * start, const wchar_t * end, StreamType & out)
|
||||
{
|
||||
out.write(start, end-start);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Find(const std::wstring & key, 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);
|
||||
|
||||
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);
|
||||
void PrintSpecialText(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 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 MakeTextIf_go(Item & item, bool result);
|
||||
bool MakeTextIfindexnumber(Item & item, typename Functions<StreamType>::Function * function, bool & result);
|
||||
void MakeTextIf(Item & item);
|
||||
void MakeTextIfno(Item & item);
|
||||
void MakeTextIfany(Item & item);
|
||||
void MakeTextIfone(Item & item);
|
||||
void MakeTextIfanyno(Item & item);
|
||||
void MakeTextIfoneno(Item & item);
|
||||
void MakeTextIfindex(Item & item);
|
||||
void MakeTextForLoop(Item & item, typename Functions<StreamType>::Function * function);
|
||||
void MakeTextFor(Item & item);
|
||||
void MakeItemText(Item & item);
|
||||
void MakeTextContainer(Item & item);
|
||||
void MakeTextNormal(Item & item);
|
||||
void MakeTextIs(Item & item);
|
||||
void MakeTextIsno(Item & item);
|
||||
void MakeTextDefine(Item & item);
|
||||
void MakeText(Item & item);
|
||||
|
||||
}; // class Generator
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::PutChar(wchar_t z, StreamType & out)
|
||||
{
|
||||
typedef typename StreamType::char_type CharType;
|
||||
|
||||
out << static_cast<CharType>(z);
|
||||
}
|
||||
|
||||
/*
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::PutString(const wchar_t * start, const wchar_t * end, StreamType & out)
|
||||
{
|
||||
out.write(start, end-start);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::PutString(const std::wstring & str, StreamType & out)
|
||||
{
|
||||
PutString(str.c_str(), str.c_str() + str.size(), out);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::PutStringGeneric(const wchar_t * start, size_t len, StreamType & out)
|
||||
{
|
||||
typedef typename StreamType::char_type CharType;
|
||||
|
||||
for(size_t i=0 ; i<len ; ++i)
|
||||
out << static_cast<CharType>(start[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
Generator<StreamType>::Generator()
|
||||
{
|
||||
output_stream = 0;
|
||||
pattern = 0;
|
||||
functions = 0;
|
||||
|
||||
max_items = 50000;
|
||||
max_for_items = 5000;
|
||||
special_chars = false;
|
||||
trim_white = false;
|
||||
skip_new_line = false;
|
||||
}
|
||||
|
||||
|
||||
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>
|
||||
void Generator<StreamType>::SetMax(int max_items_, int max_for_items_)
|
||||
{
|
||||
max_items = max_items_;
|
||||
max_for_items = max_for_items_;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::RecognizeSpecialChars(bool spec)
|
||||
{
|
||||
special_chars = spec;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::TrimWhite(bool trim)
|
||||
{
|
||||
trim_white = trim;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::SkipNewLine(bool skip)
|
||||
{
|
||||
skip_new_line = skip;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::Generate()
|
||||
{
|
||||
if( !output_stream || !pattern || !functions )
|
||||
return;
|
||||
|
||||
break_generating = false;
|
||||
current_item = 0;
|
||||
|
||||
MakeText( pattern->item_root );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::Find(const std::wstring & key, typename Functions<StreamType>::Function ** function)
|
||||
{
|
||||
if( !functions->Find(key, function) )
|
||||
{
|
||||
CreateMsg(*output_stream, L"can't find", key.c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
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");
|
||||
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>
|
||||
void Generator<StreamType>::Call(typename Functions<StreamType>::Function * function, FunInfo<StreamType> & info)
|
||||
{
|
||||
info.Clear();
|
||||
info.iter = function->iter;
|
||||
|
||||
if( function->type == Functions<StreamType>::function )
|
||||
CallUserFunction(function, info);
|
||||
else
|
||||
CallVariable(function, info);
|
||||
}
|
||||
|
||||
|
||||
// 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 called;
|
||||
|
||||
if( function.params.empty() )
|
||||
{
|
||||
FunInfo<StreamType> info(*output_stream, function.params, empty);
|
||||
called = Call(function.name, info, pfun);
|
||||
|
||||
if( info_res )
|
||||
*info_res = info.res;
|
||||
}
|
||||
else
|
||||
{
|
||||
FunInfo<StreamType> info(*output_stream, function.params, function.params[0]);
|
||||
called = Call(function.name, info, pfun);
|
||||
|
||||
if( info_res )
|
||||
*info_res = info.res;
|
||||
}
|
||||
|
||||
return called;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
wchar_t Generator<StreamType>::CreateSpecialChar(wchar_t c)
|
||||
{
|
||||
wchar_t res = 0;
|
||||
|
||||
if( c == 'r' )
|
||||
res = '\r';
|
||||
else
|
||||
if( c == 'n' )
|
||||
res = '\n';
|
||||
else
|
||||
if( c == 't' )
|
||||
res = '\t';
|
||||
else
|
||||
if( c == 's' )
|
||||
res = ' ';
|
||||
else
|
||||
if( c == '\\' )
|
||||
res = '\\';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::PrintSpecialText(const wchar_t * start, const wchar_t * end)
|
||||
{
|
||||
wchar_t special;
|
||||
|
||||
while( start != end )
|
||||
{
|
||||
special = 0;
|
||||
|
||||
if( *start == '\\' && (start+1) != end )
|
||||
special = CreateSpecialChar(*(start+1));
|
||||
|
||||
if( special )
|
||||
{
|
||||
*output_stream << special;
|
||||
start += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !(skip_new_line && *start == 10) )
|
||||
*output_stream << *start;
|
||||
|
||||
start += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::PrintNormalText(const wchar_t * start, const wchar_t * end)
|
||||
{
|
||||
if( skip_new_line )
|
||||
{
|
||||
for( ; start != end ; ++start)
|
||||
{
|
||||
if( *start != 10 )
|
||||
PutChar(*start, *output_stream);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( start != end )
|
||||
PutString(start, end, *output_stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::TrimWhite(const wchar_t *& start, const wchar_t *& end)
|
||||
{
|
||||
while( start != end && pattern->IsWhite(*start) )
|
||||
++start;
|
||||
|
||||
while( start != end && pattern->IsWhite(*(end-1)) )
|
||||
--end;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::SkipWhite(const wchar_t *& str)
|
||||
{
|
||||
while( pattern->IsWhite(*str) )
|
||||
str += 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
int Generator<StreamType>::StrToInt(const wchar_t * str, const wchar_t ** str_end)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
SkipWhite(str);
|
||||
|
||||
// overflow is not checked
|
||||
|
||||
while( *str>='0' && *str<='9' )
|
||||
{
|
||||
res *= 10;
|
||||
res += *str - '0';
|
||||
str += 1;
|
||||
}
|
||||
|
||||
SkipWhite(str);
|
||||
*str_end = str;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CreateMsg(StreamType & o, const wchar_t * type, const wchar_t * arg)
|
||||
{
|
||||
pattern->CreateMsg(temp_msg, type, arg);
|
||||
PutString(temp_msg, o);
|
||||
temp_msg.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CreateMsg(StreamType & o, const std::wstring & type, const std::wstring & arg)
|
||||
{
|
||||
CreateMsg(o, type.c_str(), arg.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CreateMsg(StreamType & o, const std::wstring & type)
|
||||
{
|
||||
CreateMsg(o, type.c_str());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeItemText(Item & item)
|
||||
{
|
||||
const wchar_t * start = item.text.c_str();
|
||||
const wchar_t * end = item.text.c_str() + item.text.size();
|
||||
|
||||
if( trim_white )
|
||||
TrimWhite(start, end);
|
||||
|
||||
if( special_chars )
|
||||
PrintSpecialText(start, end);
|
||||
else
|
||||
PrintNormalText(start, end);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextContainer(Item & item)
|
||||
{
|
||||
std::vector<Item*>::iterator i = item.item_tab.begin();
|
||||
|
||||
for( ; i != item.item_tab.end() && !break_generating ; ++i )
|
||||
MakeText(**i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextNormal(Item & item)
|
||||
{
|
||||
if( item.functions.size() != 1 )
|
||||
return;
|
||||
|
||||
typename Functions<StreamType>::Function * pfun;
|
||||
bool called = Call(item.functions[0], 0, &pfun);
|
||||
|
||||
if( called && pfun->type == Functions<StreamType>::variable )
|
||||
PutString(pfun->variable, *output_stream);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIf_go(Item & item, bool result)
|
||||
{
|
||||
if( result )
|
||||
{
|
||||
if( item.item_tab.size() > 0 )
|
||||
MakeText( *item.item_tab[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
// second element can be (or not -- it's from [else])
|
||||
if( item.item_tab.size() > 1 )
|
||||
MakeText( *item.item_tab[1] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIf(Item & item)
|
||||
{
|
||||
bool info_res;
|
||||
|
||||
if( item.functions.size() != 1 )
|
||||
return;
|
||||
|
||||
if( !Call(item.functions[0], &info_res) )
|
||||
return;
|
||||
|
||||
MakeTextIf_go(item, info_res);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIfno(Item & item)
|
||||
{
|
||||
bool info_res;
|
||||
|
||||
if( item.functions.size() != 1 )
|
||||
return;
|
||||
|
||||
if( !Call(item.functions[0], &info_res) )
|
||||
return;
|
||||
|
||||
MakeTextIf_go(item, !info_res);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIfany(Item & item)
|
||||
{
|
||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_true = 0;
|
||||
bool info_res;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( !Call(*d, &info_res) )
|
||||
return;
|
||||
|
||||
if( info_res )
|
||||
++how_many_true;
|
||||
}
|
||||
|
||||
MakeTextIf_go(item, how_many_true == item.functions.size());
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIfone(Item & item)
|
||||
{
|
||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_true = 0;
|
||||
bool info_res;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( Call(*d, &info_res) && info_res )
|
||||
{
|
||||
// there is no sense to go through all functions
|
||||
++how_many_true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MakeTextIf_go(item, how_many_true > 0);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIfanyno(Item & item)
|
||||
{
|
||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_true = 0;
|
||||
bool info_res;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( !Call(*d, &info_res) )
|
||||
return;
|
||||
|
||||
if( info_res )
|
||||
++how_many_true;
|
||||
}
|
||||
|
||||
MakeTextIf_go(item, how_many_true == 0);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIfoneno(Item & item)
|
||||
{
|
||||
std::vector<typename Item::Function>::iterator d = item.functions.begin();
|
||||
unsigned how_many_false = 0;
|
||||
bool info_res;
|
||||
|
||||
for( ; d != item.functions.end() ; ++d )
|
||||
{
|
||||
if( Call(*d, &info_res) && !info_res )
|
||||
++how_many_false;
|
||||
}
|
||||
|
||||
MakeTextIf_go(item, how_many_false > 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIs(Item & item)
|
||||
{
|
||||
bool info_res1, info_res2;
|
||||
|
||||
if( item.functions.size() != 2 )
|
||||
return;
|
||||
|
||||
if( !Call(item.functions[0], &info_res1) )
|
||||
return;
|
||||
|
||||
if( !Call(item.functions[1], &info_res2) )
|
||||
return;
|
||||
|
||||
MakeTextIf_go(item, info_res1 == info_res2);
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIsno(Item & item)
|
||||
{
|
||||
bool info_res1, info_res2;
|
||||
|
||||
if( item.functions.size() != 2 )
|
||||
return;
|
||||
|
||||
if( !Call(item.functions[0], &info_res1) )
|
||||
return;
|
||||
|
||||
if( !Call(item.functions[1], &info_res2) )
|
||||
return;
|
||||
|
||||
MakeTextIf_go(item, info_res1 != info_res2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::MakeTextIfindexnumber(Item & item, typename Functions<StreamType>::Function * function, bool & result)
|
||||
{
|
||||
if( item.functions.size() != 2 )
|
||||
return false;
|
||||
|
||||
const wchar_t * number_text = item.functions[1].name.c_str();
|
||||
const wchar_t * last_char;
|
||||
|
||||
int number = StrToInt(number_text, &last_char);
|
||||
|
||||
if( *last_char != '\0' )
|
||||
{
|
||||
CreateMsg(*output_stream, L"if-index: syntax error");
|
||||
return false;
|
||||
}
|
||||
|
||||
result = (function->iter == number);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextIfindex(Item & item)
|
||||
{
|
||||
if( item.functions.size() != 2 )
|
||||
return;
|
||||
|
||||
// we actually don't call a function (or variable) here
|
||||
// but only reading the iterator
|
||||
|
||||
typename Functions<StreamType>::Function * function;
|
||||
|
||||
if( !Find(item.functions[0].name, &function) )
|
||||
return;
|
||||
|
||||
bool result = false;
|
||||
|
||||
|
||||
if( item.functions[1].name == L"odd" )
|
||||
{
|
||||
result = (function->iter & 1) == 1;
|
||||
}
|
||||
else
|
||||
if( item.functions[1].name == L"even" )
|
||||
{
|
||||
result = (function->iter & 1) == 0;
|
||||
}
|
||||
else
|
||||
if( item.functions[1].name == L"first" )
|
||||
{
|
||||
result = function->iter == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !MakeTextIfindexnumber(item, function, result) )
|
||||
return;
|
||||
}
|
||||
|
||||
MakeTextIf_go(item, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextForLoop(Item & item, typename Functions<StreamType>::Function * function)
|
||||
{
|
||||
bool info_res;
|
||||
|
||||
for( ; !break_generating ; function->iter += 1 )
|
||||
{
|
||||
if( function->iter >= max_for_items )
|
||||
{
|
||||
CreateMsg(*output_stream, item.functions[0].name.c_str(),
|
||||
L"function exceeded a limit for a [for] statement");
|
||||
break;
|
||||
}
|
||||
|
||||
Call(item.functions[0], &info_res);
|
||||
|
||||
if( !info_res )
|
||||
break;
|
||||
|
||||
if( !item.item_tab.empty() )
|
||||
MakeText( *item.item_tab[0] ); // should be only one item - item_container
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextFor(Item & item)
|
||||
{
|
||||
if( item.functions.size() != 1 )
|
||||
return;
|
||||
|
||||
typename Functions<StreamType>::Function * function;
|
||||
|
||||
if( !Find(item.functions[0].name, &function) )
|
||||
return;
|
||||
|
||||
if( function->is_for )
|
||||
{
|
||||
CreateMsg(*output_stream, item.functions[0].name.c_str(),
|
||||
L"this function is already used in a [for] statement");
|
||||
return;
|
||||
}
|
||||
|
||||
function->is_for = true;
|
||||
function->iter = 0;
|
||||
|
||||
MakeTextForLoop(item, function);
|
||||
|
||||
function->is_for = false;
|
||||
function->iter = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeTextDefine(Item & item)
|
||||
{
|
||||
if( item.functions.size() == 1 )
|
||||
{
|
||||
// inserting a new variable
|
||||
if( item.functions[0].params.size() == 1 )
|
||||
functions->Insert(item.functions[0].name, item.functions[0].params[0]);
|
||||
}
|
||||
else
|
||||
if( item.functions.size() == 2 )
|
||||
{
|
||||
typename Functions<StreamType>::Function * function;
|
||||
|
||||
if( Find(item.functions[1].name, &function) )
|
||||
{
|
||||
if( function->type == Functions<StreamType>::function )
|
||||
{
|
||||
// inserting a new function
|
||||
functions->Insert(item.functions[0].name, function->user_function);
|
||||
}
|
||||
else
|
||||
{
|
||||
// inserting a new variable (the value is copied)
|
||||
functions->Insert(item.functions[0].name, function->variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::MakeText(Item & item)
|
||||
{
|
||||
if( break_generating )
|
||||
return;
|
||||
|
||||
if( ++current_item > max_items )
|
||||
{
|
||||
break_generating = true;
|
||||
CreateMsg(*output_stream, L"Generator exceeded allowed number of elements");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( item.type == Item::item_text ) MakeItemText(item);
|
||||
else if( item.type == Item::item_container )MakeTextContainer(item);
|
||||
else if( item.type == Item::item_normal ) MakeTextNormal(item);
|
||||
else if( item.type == Item::item_if ) MakeTextIf(item);
|
||||
else if( item.type == Item::item_ifno ) MakeTextIfno(item);
|
||||
else if( item.type == Item::item_ifany ) MakeTextIfany(item);
|
||||
else if( item.type == Item::item_ifone ) MakeTextIfone(item);
|
||||
else if( item.type == Item::item_ifanyno ) MakeTextIfanyno(item);
|
||||
else if( item.type == Item::item_ifoneno ) MakeTextIfoneno(item);
|
||||
else if( item.type == Item::item_ifindex ) MakeTextIfindex(item);
|
||||
else if( item.type == Item::item_is ) MakeTextIs(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_def ) MakeTextDefine(item);
|
||||
else if( item.type == Item::item_err )
|
||||
CreateMsg(*output_stream, L"a wrong directive");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "item.h"
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Item * Item::AddItem(const Item * porg)
|
||||
{
|
||||
Item * pitem;
|
||||
|
||||
if( porg )
|
||||
pitem = new Item(*porg);
|
||||
else
|
||||
pitem = new Item();
|
||||
|
||||
item_tab.push_back(pitem);
|
||||
|
||||
return pitem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item * Item::AddItem(const Item & porg)
|
||||
{
|
||||
return AddItem(&porg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Item::ClearItems()
|
||||
{
|
||||
std::vector<Item*>::iterator i = item_tab.begin();
|
||||
|
||||
for( ; i != item_tab.end() ; ++i )
|
||||
delete *i;
|
||||
|
||||
item_tab.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Item::Clear()
|
||||
{
|
||||
ClearItems();
|
||||
type = item_none;
|
||||
text.clear();
|
||||
file_name.clear();
|
||||
functions.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item::Type Item::LastItemType()
|
||||
{
|
||||
if( item_tab.empty() )
|
||||
return item_none;
|
||||
|
||||
return item_tab.back()->type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Item::DeleteLastItem()
|
||||
{
|
||||
if( item_tab.empty() )
|
||||
return;
|
||||
|
||||
delete item_tab.back();
|
||||
item_tab.pop_back();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item::Item()
|
||||
{
|
||||
type = item_none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item::Item(const Item & i) : type(i.type), text(i.text), functions(i.functions)
|
||||
{
|
||||
CopyItemTable(i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item & Item::operator=(const Item & i)
|
||||
{
|
||||
type = i.type;
|
||||
text = i.text;
|
||||
functions = i.functions;
|
||||
|
||||
CopyItemTable(i);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Item::CopyItemTable(const Item & item)
|
||||
{
|
||||
std::vector<Item*>::const_iterator i = item.item_tab.begin();
|
||||
|
||||
for( ; i != item.item_tab.end() ; ++i)
|
||||
AddItem(*i);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item::~Item()
|
||||
{
|
||||
ClearItems();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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_item
|
||||
#define headerfile_ezc_item
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
|
||||
struct Item
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
struct Function
|
||||
{
|
||||
std::wstring name; // function name
|
||||
std::vector<std::wstring> params; // function parameters
|
||||
};
|
||||
|
||||
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<Function> functions;
|
||||
|
||||
Item();
|
||||
Item(const Item & i);
|
||||
Item & operator=(const Item & i);
|
||||
void CopyItemTable(const Item & i);
|
||||
~Item();
|
||||
|
||||
Item * AddItem(const Item * porg = 0);
|
||||
Item * AddItem(const Item & porg);
|
||||
void ClearItems();
|
||||
Type LastItemType();
|
||||
void DeleteLastItem();
|
||||
void Clear();
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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_pattern
|
||||
#define headerfile_ezc_pattern
|
||||
|
||||
#include <string>
|
||||
#include "item.h"
|
||||
#include "stringconv.h"
|
||||
#include "utf8.h"
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
class Pattern
|
||||
{
|
||||
public:
|
||||
|
||||
Pattern();
|
||||
|
||||
/*!
|
||||
clearing only the tree
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
|
||||
// first we're trying to read a file from directory dir
|
||||
// if there is no such a file there then we try read from dir2
|
||||
// (the second dir2 can be empty - it will not be used)
|
||||
void Directory(const char * dir, const char * dir2 = 0);
|
||||
void Directory(const std::string & dir);
|
||||
void Directory(const std::string & dir, const std::string & dir2);
|
||||
|
||||
void Directory(const wchar_t * dir, const wchar_t * dir2 = 0);
|
||||
void Directory(const std::wstring & dir);
|
||||
void Directory(const std::wstring & dir, const std::wstring & dir2);
|
||||
|
||||
void ParseFile(const char * file_name);
|
||||
void ParseFile(const std::string & file_name);
|
||||
|
||||
void ParseFile(const wchar_t * file_name);
|
||||
void ParseFile(const std::wstring & file_name);
|
||||
|
||||
|
||||
void ParseString(const char * str);
|
||||
void ParseString(const std::string & str);
|
||||
void ParseString(const wchar_t * str);
|
||||
void ParseString(const std::wstring & str);
|
||||
|
||||
void AllowInclude(bool allow);
|
||||
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 SetCommentary(const char * com_start, const char * com_stop);
|
||||
void SetCommentary(const std::string & com_start, const std::string & com_stop);
|
||||
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;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// the main pointer to the parsed text
|
||||
const wchar_t * itext;
|
||||
|
||||
|
||||
// allowing include tag
|
||||
// default: true
|
||||
bool allow_include;
|
||||
|
||||
// if true all text-items which have only white characters (with new lines as well)
|
||||
// will be deleted - useful in *.txt templates
|
||||
// this not actually delete the whole item but only the string
|
||||
// the item will be present with an empty string
|
||||
// default: false
|
||||
bool delete_white_text_items;
|
||||
|
||||
// first we're trying to read a file from 'directory'
|
||||
// if there is no such a file there then we try read from 'directory2'
|
||||
// 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;
|
||||
|
||||
|
||||
|
||||
std::wstring commentary_start, commentary_stop;
|
||||
|
||||
|
||||
// temporary content for ParseString(const char*) method
|
||||
std::wstring string_content;
|
||||
|
||||
// temporary object for a file name
|
||||
std::wstring file_name;
|
||||
|
||||
// temporary object for a file name
|
||||
std::string afile_name;
|
||||
|
||||
// temporary object for a EZC function's parameter
|
||||
std::wstring temp_param;
|
||||
|
||||
// temporary object for a EZC function
|
||||
Item::Function temp_function;
|
||||
|
||||
|
||||
|
||||
void ReadFile(const std::wstring & name, std::wstring & result);
|
||||
void ReadFile(const wchar_t * name, std::wstring & result);
|
||||
bool HasFileAtBeginning(const wchar_t * path, const wchar_t * file);
|
||||
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();
|
||||
void SkipWhite();
|
||||
void CheckWhiteAndDelete(std::wstring & s);
|
||||
|
||||
bool IsNameChar(wchar_t c);
|
||||
bool IsDigit(wchar_t c);
|
||||
bool IsPositiveNumber(const std::wstring & str);
|
||||
|
||||
bool ReadName(std::wstring & name);
|
||||
bool ReadString(std::wstring & str);
|
||||
bool ReadParams(Item::Function & function);
|
||||
bool ReadFunction(Item::Function & function);
|
||||
bool ReadFunctions(Item & item);
|
||||
|
||||
void ReadDirectiveIf(Item & item);
|
||||
void ReadDirectiveIfno(Item & item);
|
||||
void ReadDirectiveIfany(Item & item);
|
||||
void ReadDirectiveIfone(Item & item);
|
||||
void ReadDirectiveIfanyno(Item & item);
|
||||
void ReadDirectiveIfoneno(Item & item);
|
||||
void ReadDirectiveIs(Item & item);
|
||||
void ReadDirectiveIsno(Item & item);
|
||||
void ReadDirectiveIfindex(Item & item);
|
||||
void ReadDirectiveFor(Item & item);
|
||||
void ReadDirectiveComment(Item & item);
|
||||
void ReadDirectiveInclude(Item & item);
|
||||
void ReadDirectiveDef(Item & item);
|
||||
void ReadDirectiveNormal(const std::wstring & name, Item & item);
|
||||
|
||||
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
||||
void CreateTreeReadItemDirective(Item & item);
|
||||
void CreateTreeReadItemText(Item & item);
|
||||
bool CreateTreeReadItem(Item & item);
|
||||
void CreateTreeReadIf(Item & item);
|
||||
void CreateTreeReadFor(Item & item);
|
||||
void CreateTree(Item & item);
|
||||
void CreateTreeReadInclude(Item & item);
|
||||
void CreateTreeReadIncludeSkipAllowFlag(Item & item);
|
||||
|
||||
}; // class Pattern
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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.
|
||||
*/
|
||||
|
||||
#include "stringconv.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
void AssignString(const char * src, std::wstring & dst, bool clear)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if( clear )
|
||||
dst.clear();
|
||||
|
||||
for(len=0 ; src[len] ; ++len){}
|
||||
dst.reserve(len);
|
||||
|
||||
for( ; *src ; ++src )
|
||||
dst += static_cast<unsigned char>(*src);
|
||||
}
|
||||
|
||||
|
||||
void AssignString(const std::string & src, std::wstring & dst, bool clear)
|
||||
{
|
||||
if( clear )
|
||||
dst.clear();
|
||||
|
||||
dst.reserve(src.size());
|
||||
|
||||
for(size_t i=0 ; i<src.size() ; ++i )
|
||||
dst += static_cast<unsigned char>(src[i]);
|
||||
}
|
||||
|
||||
|
||||
void AssignString(const wchar_t * src, std::string & dst, bool clear)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if( clear )
|
||||
dst.clear();
|
||||
|
||||
for(len=0 ; src[len] ; ++len){}
|
||||
dst.reserve(len);
|
||||
|
||||
for( ; *src ; ++src )
|
||||
dst += static_cast<char>(*src);
|
||||
}
|
||||
|
||||
|
||||
void AssignString(const std::wstring & src, std::string & dst, bool clear)
|
||||
{
|
||||
if( clear )
|
||||
dst.clear();
|
||||
|
||||
dst.reserve(src.size());
|
||||
|
||||
for(size_t i=0 ; i<src.size() ; ++i )
|
||||
dst += static_cast<char>(src[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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) 2007-2010, 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_stringconv
|
||||
#define headerfile_ezc_stringconv
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
void AssignString(const char * src, std::wstring & dst, bool clear = true);
|
||||
void AssignString(const std::string & src, std::wstring & dst, bool clear = true);
|
||||
void AssignString(const wchar_t * src, std::string & dst, bool clear = true);
|
||||
void AssignString(const std::wstring & src, std::string & dst, bool clear = true);
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,670 @@
|
|||
/*
|
||||
* 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) 2010, 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.
|
||||
*/
|
||||
|
||||
#include "utf8.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
an auxiliary function for converting from UTF-8 string
|
||||
*/
|
||||
static bool UTF8ToInt_FirstOctet(unsigned char uz, size_t & len, int & res)
|
||||
{
|
||||
for(len=0 ; (uz & 0x80) != 0 ; ++len)
|
||||
uz <<= 1;
|
||||
|
||||
if( len == 1 )
|
||||
return false;
|
||||
|
||||
res = uz;
|
||||
|
||||
if( len > 0 )
|
||||
res >>= len;
|
||||
|
||||
if( res == 0 )
|
||||
return false;
|
||||
|
||||
if( len == 0 )
|
||||
len = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
an auxiliary function for converting from UTF-8 string
|
||||
*/
|
||||
static bool UTF8ToInt_AddNextOctet(unsigned char uz, int & res)
|
||||
{
|
||||
if( (uz & 0xc0) != 0x80 )
|
||||
return false;
|
||||
|
||||
res <<= 6;
|
||||
res |= (uz & 0x3F);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
returns true if 'c' is a correct unicode character
|
||||
*/
|
||||
bool UTF8_CheckRange(int c)
|
||||
{
|
||||
return c>=0 && c<=0x10FFFF && !(c>=0xD800 && c<=0xDFFF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts one UTF-8 character into one wide-character
|
||||
|
||||
input:
|
||||
utf8 - an input UTF-8 string
|
||||
utf8_len - size of the input string,
|
||||
the string should be at least 4 bytes length for correctly
|
||||
recognized the utf-8 sequence
|
||||
|
||||
output:
|
||||
res - an output character
|
||||
correct - true if it is a correct character
|
||||
|
||||
the function returns how many characters have been used from the input string
|
||||
(returns zero only if utf8_len is zero)
|
||||
even if there are errors the functions returns a different from zero value
|
||||
*/
|
||||
size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct)
|
||||
{
|
||||
size_t i, len;
|
||||
|
||||
res = 0;
|
||||
correct = false;
|
||||
|
||||
if( utf8_len == 0 )
|
||||
return 0;
|
||||
|
||||
if( !UTF8ToInt_FirstOctet(utf8[0], len, res) )
|
||||
return 1;
|
||||
|
||||
if( utf8_len < len )
|
||||
return utf8_len;
|
||||
|
||||
for(i=1 ; i<len ; ++i)
|
||||
if( !UTF8ToInt_AddNextOctet(utf8[i], res) )
|
||||
return i;
|
||||
|
||||
if( UTF8_CheckRange(res) )
|
||||
correct = true;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts one UTF-8 character into one wide-character
|
||||
|
||||
input:
|
||||
utf8 - an input UTF-8 string
|
||||
|
||||
output:
|
||||
res - an output character
|
||||
correct - true if it is a correct character
|
||||
|
||||
the function returns how many characters have been used from the input string
|
||||
(returns zero only if utf8 is empty)
|
||||
even if there are errors the functions returns a different from zero value
|
||||
*/
|
||||
size_t UTF8ToInt(const std::string & utf8, int & res, bool & correct)
|
||||
{
|
||||
return UTF8ToInt(utf8.c_str(), utf8.size(), res, correct);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts one UTF-8 character into one wide-character
|
||||
|
||||
input:
|
||||
utf8 - an input UTF-8 stream
|
||||
|
||||
output:
|
||||
res - an output character
|
||||
correct - true if it is a correct character
|
||||
|
||||
the function returns how many characters have been used from the input stream
|
||||
*/
|
||||
size_t UTF8ToInt(std::istream & utf8, int & res, bool & correct)
|
||||
{
|
||||
size_t i, len;
|
||||
unsigned char uz;
|
||||
|
||||
res = 0;
|
||||
correct = false;
|
||||
|
||||
uz = utf8.get();
|
||||
|
||||
if( !utf8 )
|
||||
return 0;
|
||||
|
||||
if( !UTF8ToInt_FirstOctet(uz, len, res) )
|
||||
return 1;
|
||||
|
||||
for(i=1 ; i<len ; ++i)
|
||||
{
|
||||
uz = utf8.get();
|
||||
|
||||
if( !utf8 )
|
||||
return i;
|
||||
|
||||
if( !UTF8ToInt_AddNextOctet(uz, res) )
|
||||
return i;
|
||||
}
|
||||
|
||||
if( UTF8_CheckRange(res) )
|
||||
correct = true;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts an utf8 string into wide string (std::wstring)
|
||||
|
||||
input:
|
||||
utf8 - an input utf8 string
|
||||
utf8_len - size of the input string
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
res - an output wide string
|
||||
|
||||
the function returns false if there were some errors when converting
|
||||
*/
|
||||
bool UTF8ToWide(const char * utf8, size_t utf8_len, std::wstring & res, bool clear, int mode)
|
||||
{
|
||||
int z;
|
||||
size_t len;
|
||||
bool correct, was_error = false;
|
||||
|
||||
if( clear )
|
||||
res.clear();
|
||||
|
||||
while( utf8_len > 0 )
|
||||
{
|
||||
if( (unsigned char)*utf8 <= 0x7f )
|
||||
{
|
||||
// small optimization
|
||||
len = 1;
|
||||
correct = true;
|
||||
z = static_cast<unsigned char>(*utf8);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = UTF8ToInt(utf8, utf8_len, z, correct); // the len will be different from zero
|
||||
}
|
||||
|
||||
if( !correct || (sizeof(wchar_t)==2 && z>0xffff) )
|
||||
{
|
||||
if( mode == 1 )
|
||||
res += 0xFFFD; // U+FFFD "replacement character"
|
||||
|
||||
was_error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
res += static_cast<wchar_t>(z);
|
||||
}
|
||||
|
||||
utf8 += len;
|
||||
utf8_len -= len;
|
||||
}
|
||||
|
||||
return !was_error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts an utf8 string into wide string (std::wstring)
|
||||
|
||||
input:
|
||||
utf8 - an input utf8 null terminated string
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
res - an output wide string
|
||||
|
||||
the function returns false if there were some errors when converting
|
||||
*/
|
||||
bool UTF8ToWide(const char * utf8, std::wstring & res, bool clear, int mode)
|
||||
{
|
||||
size_t utf8_len = 0;
|
||||
|
||||
while( utf8[utf8_len] != 0 )
|
||||
utf8_len += 1;
|
||||
|
||||
return UTF8ToWide(utf8, utf8_len, res, clear, mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts an utf8 string into wide string (std::wstring)
|
||||
|
||||
input:
|
||||
utf8 - an input utf8 string
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
res - an output wide string
|
||||
|
||||
the function returns false if there were some errors when converting
|
||||
*/
|
||||
bool UTF8ToWide(const std::string & utf8, std::wstring & res, bool clear, int mode)
|
||||
{
|
||||
return UTF8ToWide(utf8.c_str(), utf8.size(), res, clear, mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts an utf8 stream into wide string (std::wstring)
|
||||
|
||||
input:
|
||||
utf8 - an input utf8 stream
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
res - an output wide string
|
||||
|
||||
the function returns false if there were some errors when converting
|
||||
*/
|
||||
bool UTF8ToWide(std::istream & utf8, std::wstring & res, bool clear, int mode)
|
||||
{
|
||||
int z;
|
||||
bool correct, was_error = false;
|
||||
|
||||
if( clear )
|
||||
res.clear();
|
||||
|
||||
while( UTF8ToInt(utf8, z, correct) > 0 )
|
||||
{
|
||||
if( !correct || (sizeof(wchar_t)==2 && z>0xffff) )
|
||||
{
|
||||
if( mode == 1 )
|
||||
res += 0xFFFD; // U+FFFD "replacement character"
|
||||
|
||||
was_error = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
res += z;
|
||||
}
|
||||
}
|
||||
|
||||
return !was_error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts one wide character into UTF-8 sequence
|
||||
|
||||
input:
|
||||
z - wide character
|
||||
|
||||
output:
|
||||
utf8 - a buffer for the output sequence
|
||||
utf8_len - the size of the buffer
|
||||
|
||||
the function returns how many characters have been written to the utf8,
|
||||
zero means the utf8 buffer is too small or 'z' is an incorrect unicode character
|
||||
*/
|
||||
size_t IntToUTF8(int z, char * utf8, size_t utf8_max_len)
|
||||
{
|
||||
char buf[10];
|
||||
int i = 0;
|
||||
int mask = 0x3f; // 6 first bits set
|
||||
|
||||
if( utf8_max_len==0 || !UTF8_CheckRange(z) )
|
||||
return 0;
|
||||
|
||||
if( z <= 0x7f )
|
||||
{
|
||||
utf8[0] = static_cast<char>(z);
|
||||
return 1;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
buf[i] = 0x80 | (z & 0x3f);
|
||||
i += 1;
|
||||
z >>= 6;
|
||||
mask >>= 1;
|
||||
}
|
||||
while( (z & (~mask)) != 0 );
|
||||
|
||||
unsigned int first = -1;
|
||||
first <<= (7 - i);
|
||||
first |= (z & mask);
|
||||
|
||||
if( size_t(i+1) > utf8_max_len )
|
||||
return 0;
|
||||
|
||||
utf8[0] = static_cast<char>(first);
|
||||
|
||||
int a = 1;
|
||||
for(--i; i>=0 ; --i, ++a)
|
||||
utf8[a] = buf[i];
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts one wide character into UTF-8 string
|
||||
|
||||
input:
|
||||
z - wide character
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 string for the output sequence (the string is not cleared)
|
||||
|
||||
the function returns how many characters have been written to the utf8 string,
|
||||
zero means that 'z' is an incorrect unicode character
|
||||
*/
|
||||
size_t IntToUTF8(int z, std::string & utf8, bool clear)
|
||||
{
|
||||
char buf[10];
|
||||
|
||||
if( clear )
|
||||
utf8.clear();
|
||||
|
||||
size_t len = IntToUTF8(z, buf, sizeof(buf)/sizeof(char));
|
||||
size_t i;
|
||||
|
||||
for(i=0 ; i<len ; ++i)
|
||||
utf8 += buf[i];
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts one wide character into UTF-8 stream
|
||||
|
||||
input:
|
||||
z - wide character
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 stream for the output sequence
|
||||
|
||||
the function returns how many characters have been written to the utf8 stream,
|
||||
zero means that 'z' is an incorrect unicode character
|
||||
*/
|
||||
size_t IntToUTF8(int z, std::ostream & utf8)
|
||||
{
|
||||
char buf[10];
|
||||
|
||||
size_t len = IntToUTF8(z, buf, sizeof(buf)/sizeof(char));
|
||||
size_t i;
|
||||
|
||||
for(i=0 ; i<len ; ++i)
|
||||
utf8 << buf[i];
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
an auxiliary function for converting from wide characters to UTF-8
|
||||
*/
|
||||
static void WideToUTF8(wchar_t z, std::string & utf8, bool & was_error, int mode)
|
||||
{
|
||||
if( IntToUTF8(z, utf8, false) == 0 )
|
||||
{
|
||||
if( mode == 1 )
|
||||
IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character"
|
||||
|
||||
was_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
an auxiliary function for converting from wide characters to UTF-8
|
||||
*/
|
||||
static void WideToUTF8(wchar_t z, std::ostream & utf8, bool & was_error, int mode)
|
||||
{
|
||||
if( IntToUTF8(z, utf8) == 0 )
|
||||
{
|
||||
if( mode == 1 )
|
||||
IntToUTF8(0xFFFD, utf8); // U+FFFD "replacement character"
|
||||
|
||||
was_error = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this function converts a wide string into UTF-8 string
|
||||
|
||||
input:
|
||||
wide_string - a wide string for converting
|
||||
string_len - the size of the string
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 string for the output sequence (the string is not cleared)
|
||||
|
||||
this function returns false if there were some errors when converting
|
||||
*/
|
||||
bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool clear, int mode)
|
||||
{
|
||||
bool was_error = false;
|
||||
|
||||
if( clear )
|
||||
utf8.clear();
|
||||
|
||||
for(size_t i=0 ; i<string_len ; ++i)
|
||||
WideToUTF8(wide_string[i], utf8, was_error, mode);
|
||||
|
||||
return !was_error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts a wide string into UTF-8 string
|
||||
|
||||
input:
|
||||
wide_string - a null terminated wide string for converting
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 string for the output sequence (the string is not cleared)
|
||||
|
||||
this function returns false if there were some errors when converting
|
||||
*/
|
||||
bool WideToUTF8(const wchar_t * wide_string, std::string & utf8, bool clear, int mode)
|
||||
{
|
||||
bool was_error = false;
|
||||
|
||||
if( clear )
|
||||
utf8.clear();
|
||||
|
||||
for( ; *wide_string != 0 ; ++wide_string )
|
||||
WideToUTF8(*wide_string, utf8, was_error, mode);
|
||||
|
||||
return !was_error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts a wide string (std::wstring) into UTF-8 string
|
||||
|
||||
input:
|
||||
wide_string - a wide string for converting
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 string for the output sequence (the string is not cleared)
|
||||
|
||||
this function returns false if there were some errors when converting
|
||||
*/
|
||||
bool WideToUTF8(const std::wstring & wide_string, std::string & utf8, bool clear, int mode)
|
||||
{
|
||||
return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, clear, mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts a wide string into UTF-8 stream
|
||||
|
||||
input:
|
||||
wide_string - a wide string for converting
|
||||
string_len - size of the string
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 stream for the output sequence
|
||||
|
||||
this function returns false if there were some errors when converting
|
||||
*/
|
||||
bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::ostream & utf8, int mode)
|
||||
{
|
||||
bool was_error = false;
|
||||
|
||||
for(size_t i=0 ; i<string_len ; ++i)
|
||||
WideToUTF8(wide_string[i], utf8, was_error, mode);
|
||||
|
||||
return !was_error;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
this function converts a wide string into UTF-8 stream
|
||||
|
||||
input:
|
||||
wide_string - a null terminated wide string for converting
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 stream for the output sequence
|
||||
|
||||
this function returns false if there were some errors when converting
|
||||
*/
|
||||
bool WideToUTF8(const wchar_t * wide_string, std::ostream & utf8, int mode)
|
||||
{
|
||||
bool was_error = false;
|
||||
|
||||
for( ; *wide_string != 0 ; ++wide_string )
|
||||
WideToUTF8(*wide_string, utf8, was_error, mode);
|
||||
|
||||
return !was_error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this function converts a wide string (std::wstring) into UTF-8 stream
|
||||
|
||||
input:
|
||||
wide_string - a wide string for converting
|
||||
mode - what to do with errors when converting
|
||||
0: skip an invalid character
|
||||
1: put U+FFFD "replacement character" istead of the invalid character (default)
|
||||
|
||||
output:
|
||||
utf8 - a UTF-8 stream for the output sequence
|
||||
|
||||
this function returns false if there were some errors when converting
|
||||
*/
|
||||
bool WideToUTF8(const std::wstring & wide_string, std::ostream & utf8, int mode)
|
||||
{
|
||||
return WideToUTF8(wide_string.c_str(), wide_string.size(), utf8, mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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) 2010, 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_utf8
|
||||
#define headerfile_ezc_utf8
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Ezc
|
||||
{
|
||||
|
||||
/*!
|
||||
UTF-8, a transformation format of ISO 10646
|
||||
http://tools.ietf.org/html/rfc3629
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
returns true if 'c' is a correct unicode character
|
||||
*/
|
||||
bool UTF8_CheckRange(int c);
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
converting one character from UTF-8 to an int
|
||||
*/
|
||||
size_t UTF8ToInt(const char * utf8, size_t utf8_len, int & res, bool & correct);
|
||||
size_t UTF8ToInt(const std::string & utf8, int & res, bool & correct);
|
||||
size_t UTF8ToInt(std::istream & utf8, int & res, bool & correct);
|
||||
|
||||
|
||||
/*!
|
||||
converting UTF-8 string to a wide string
|
||||
|
||||
warning: current limitation
|
||||
on MS Windows wide characters consist of two bytes only
|
||||
and we tread them as UCS-2 (not UTF-16 with surrogate pairs as it should be trated)
|
||||
so unicode characters above 0xffff value are ignored (depending on 'mode' parameter)
|
||||
*/
|
||||
bool UTF8ToWide(const char * utf8, size_t utf8_len, std::wstring & res, bool clear = true, int mode = 1);
|
||||
bool UTF8ToWide(const char * utf8, std::wstring & res, bool clear = true, int mode = 1);
|
||||
bool UTF8ToWide(const std::string & utf8, std::wstring & res, bool clear = true, int mode = 1);
|
||||
bool UTF8ToWide(std::istream & utf8, std::wstring & res, bool clear = true, int mode = 1);
|
||||
|
||||
|
||||
/*!
|
||||
converting one int character to UTF-8
|
||||
*/
|
||||
size_t IntToUTF8(int z, char * utf8, size_t utf8_max_len);
|
||||
size_t IntToUTF8(int z, std::string & utf8, bool clear = true );
|
||||
size_t IntToUTF8(int z, std::ostream & utf8);
|
||||
|
||||
|
||||
/*!
|
||||
converting a wide string to UTF-8 string
|
||||
|
||||
warning: current limitation
|
||||
on MS Windows wide characters consist of two bytes only
|
||||
and we tread them as UCS-2 (not UTF-16 with surrogate pairs as it should be trated)
|
||||
so unicode characters above 0xffff value are ignored (depending on 'mode' parameter)
|
||||
*/
|
||||
bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool clear = true, int mode = 1);
|
||||
bool WideToUTF8(const wchar_t * wide_string, std::string & utf8, bool clear = true, int mode = 1);
|
||||
bool WideToUTF8(const std::wstring & wide_string, std::string & utf8, bool clear = true, int mode = 1);
|
||||
bool WideToUTF8(const wchar_t * wide_string, size_t string_len, std::ostream & utf8, int mode = 1);
|
||||
bool WideToUTF8(const wchar_t * wide_string, std::ostream & utf8, int mode = 1);
|
||||
bool WideToUTF8(const std::wstring & wide_string, std::ostream & utf8, int mode = 1);
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Ezc
|
||||
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue