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:
Tomasz Sowa 2010-11-22 01:23:32 +00:00
parent b5ea2514e2
commit 8f94937ed1
15 changed files with 3805 additions and 1997 deletions

View File

@ -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

View File

@ -1 +1 @@
o = ezc.o
o = item.o pattern.o stringconv.o utf8.o

File diff suppressed because it is too large Load Diff

330
src/ezc.h
View File

@ -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

252
src/functions.h Executable file
View File

@ -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

93
src/funinfo.h Executable file
View File

@ -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

996
src/generator.h Executable file
View File

@ -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

163
src/item.cpp Executable file
View File

@ -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

91
src/item.h Executable file
View File

@ -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

1033
src/pattern.cpp Executable file

File diff suppressed because it is too large Load Diff

219
src/pattern.h Executable file
View File

@ -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

102
src/stringconv.cpp Executable file
View File

@ -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

60
src/stringconv.h Executable file
View File

@ -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

670
src/utf8.cpp Executable file
View File

@ -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

114
src/utf8.h Executable file
View File

@ -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