Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
c6b4db0aa9 | |||
b4f7d4b8de | |||
542587e5e8 | |||
fb05eb6860 | |||
8df9aa86a0 | |||
2d304a9714 | |||
861269383e | |||
542e50d757 | |||
3c85fa1a75 | |||
fd2194623a | |||
c4f5f79218 | |||
0b09b5454f | |||
5108495540 | |||
33c86d494b | |||
8f94937ed1 | |||
b5ea2514e2 | |||
376fe414f8 | |||
7554630395 | |||
573d241dc1 | |||
c807d1c9b3 | |||
b89c6daa7d | |||
f65178dd0e | |||
bb00f23f29 | |||
31156d33f3 | |||
e71c213ad1 | |||
b2aacc2da3 | |||
dbe91a6d91 | |||
9b4586d7be | |||
141e1f67b3 | |||
f8f55eae77 | |||
0b88257e08 | |||
0760313ec3 | |||
54be9c0489 | |||
bf585d3716 |
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2007, Tomasz Sowa
|
Copyright (c) 2007-2010, Tomasz Sowa
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
26
src/Makefile
Executable file
26
src/Makefile
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
include Makefile.o.dep
|
||||||
|
|
||||||
|
|
||||||
|
all: ezc.a
|
||||||
|
|
||||||
|
ezc.a: $(o)
|
||||||
|
ar rcs ezc.a $(o)
|
||||||
|
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(CXX) -c $(CXXFLAGS) $<
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
depend:
|
||||||
|
makedepend $(CXXFLAGS) -Y. -f- *.cpp > Makefile.dep
|
||||||
|
echo -n "o = " > Makefile.o.dep
|
||||||
|
ls -1 *.cpp | xargs -I foo echo -n foo " " | sed -E "s/([^\.]*)\.cpp[ ]/\1\.o/g" >> Makefile.o.dep
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o
|
||||||
|
rm -f *.a
|
||||||
|
|
||||||
|
|
||||||
|
include Makefile.dep
|
28
src/Makefile.dep
Executable file
28
src/Makefile.dep
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
# DO NOT DELETE
|
||||||
|
|
||||||
|
edanticitem.o: item.h funinfo.h
|
||||||
|
edanticpattern.o: pattern.h item.h funinfo.h functions.h stringconv.h utf8.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/log.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/textstream.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/misc.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/requesttypes.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/logmanipulators.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/slog.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/cur.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/request.h
|
||||||
|
edanticpattern.o: /usr/local/include/fcgiapp.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/error.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/config.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/confparser.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/htmlfilter.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/templates/htmltextstream.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/textstream.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/session.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/user.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/plugindata.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/rebus.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/mount.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/templates/locale.h
|
||||||
|
edanticpattern.o: /home/tomek/roboczy/winix/core/confparser.h
|
||||||
|
edanticstringconv.o: stringconv.h
|
||||||
|
edanticutf8.o: utf8.h
|
1
src/Makefile.o.dep
Executable file
1
src/Makefile.o.dep
Executable file
@@ -0,0 +1 @@
|
|||||||
|
o = item.o pattern.o stringconv.o utf8.o
|
982
src/ezc.cpp
982
src/ezc.cpp
@@ -1,982 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is a part of EZC -- Easy templating in C++
|
|
||||||
* and is distributed under the (new) BSD licence.
|
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2007, 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 "ezc.h"
|
|
||||||
|
|
||||||
namespace Ezc
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
std::string CreateMsg(const char * type, const char * arg)
|
|
||||||
{
|
|
||||||
std::ostringstream buffer;
|
|
||||||
|
|
||||||
buffer << "<!-- ezc: " << type << " ";
|
|
||||||
|
|
||||||
if( arg )
|
|
||||||
buffer << arg << " ";
|
|
||||||
|
|
||||||
buffer << "-->";
|
|
||||||
|
|
||||||
return buffer.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
this method splits the input file name into a directory and a file name
|
|
||||||
e.g
|
|
||||||
if 'name' is "/this/is/dummy/file.ezc"
|
|
||||||
the result will be:
|
|
||||||
dir = "/this/is/dummy"
|
|
||||||
file = "file.ezc"
|
|
||||||
*/
|
|
||||||
void SplitUnixDirectory(const char * name, std::string & dir, std::string & file)
|
|
||||||
{
|
|
||||||
dir.clear();
|
|
||||||
file.clear();
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for( i=0 ; name[i] != 0 ; ++i );
|
|
||||||
|
|
||||||
if( i == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
for( --i ; i>=0 && name[i]!='\\' && name[i]!='/' ; --i );
|
|
||||||
|
|
||||||
if( i < 0 )
|
|
||||||
{
|
|
||||||
file.assign(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( i == 0 )
|
|
||||||
// we're leaving one '/' in the directory
|
|
||||||
// (we have only the root directory)
|
|
||||||
dir.assign(name, 1);
|
|
||||||
else
|
|
||||||
dir.assign(name, i);
|
|
||||||
|
|
||||||
file.assign(name + i + 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SplitUnixDirectory(const std::string & name, std::string & dir, std::string & file)
|
|
||||||
{
|
|
||||||
SplitUnixDirectory(name.c_str(), dir, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Pattern
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Pattern::ParseFile(const std::string & file_name)
|
|
||||||
{
|
|
||||||
ParseFile( file_name.c_str() );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pattern::ParseFile(const char * file_name)
|
|
||||||
{
|
|
||||||
std::string file;
|
|
||||||
|
|
||||||
if( directory.empty() )
|
|
||||||
SplitUnixDirectory(file_name, directory, file);
|
|
||||||
else
|
|
||||||
file = file_name;
|
|
||||||
|
|
||||||
file.insert(file.begin(), '\"');
|
|
||||||
|
|
||||||
item_root.directives.clear();
|
|
||||||
item_root.directives.push_back( file );
|
|
||||||
|
|
||||||
CreateTreeReadInclude(item_root);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::Directory(const char * d)
|
|
||||||
{
|
|
||||||
directory = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pattern::Directory(const std::string & d)
|
|
||||||
{
|
|
||||||
directory = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Pattern::CheckFileName(const char * name)
|
|
||||||
{
|
|
||||||
// very simple testing -- this path 'some..name' is incorrect as well
|
|
||||||
// (in the future it can be changed)
|
|
||||||
|
|
||||||
for( ; *name ; ++name )
|
|
||||||
{
|
|
||||||
if( *name=='.' && *(name+1)=='.' )
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
'name' must be a relative path
|
|
||||||
*/
|
|
||||||
std::string Pattern::ReadFile(const char * name)
|
|
||||||
{
|
|
||||||
// for security reason we can't open a file which has two dots
|
|
||||||
// somewhere in its name '..'
|
|
||||||
if( !CheckFileName(name) )
|
|
||||||
return CreateMsg("incorrect file name:", name);
|
|
||||||
|
|
||||||
std::string file_name(directory);
|
|
||||||
|
|
||||||
if( !file_name.empty() )
|
|
||||||
file_name += '/';
|
|
||||||
|
|
||||||
file_name += name;
|
|
||||||
|
|
||||||
std::ifstream file(file_name.c_str());
|
|
||||||
|
|
||||||
if( !file )
|
|
||||||
return CreateMsg("can't open:", name);
|
|
||||||
// or we can give the whole path here (file_name)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
std::getline(file, result, '\0');
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int Pattern::ReadCharInText()
|
|
||||||
{
|
|
||||||
if( *itext==0 || *itext=='[' )
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if( *itext == '\\' )
|
|
||||||
{
|
|
||||||
if( *(itext+1)=='\\' || *(itext+1)=='[' || *(itext+1)==']' )
|
|
||||||
++itext;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *(itext++);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::SkipWhiteCharacters()
|
|
||||||
{
|
|
||||||
while( *itext==' ' || *itext=='\t' )
|
|
||||||
++itext;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string Pattern::ReadDirective()
|
|
||||||
{
|
|
||||||
std::string directive;
|
|
||||||
|
|
||||||
SkipWhiteCharacters();
|
|
||||||
|
|
||||||
while( (*itext>='a' && *itext<='z') ||
|
|
||||||
(*itext>='A' && *itext<='Z') ||
|
|
||||||
(*itext>='0' && *itext<='9') ||
|
|
||||||
*itext=='_' || *itext=='-' || *itext=='.' || *itext=='#' )
|
|
||||||
{
|
|
||||||
directive += *itext;
|
|
||||||
|
|
||||||
++itext;
|
|
||||||
}
|
|
||||||
|
|
||||||
return directive;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string Pattern::ReadString()
|
|
||||||
{
|
|
||||||
std::string directive;
|
|
||||||
|
|
||||||
SkipWhiteCharacters();
|
|
||||||
|
|
||||||
if( *itext != '\"' )
|
|
||||||
return directive;
|
|
||||||
|
|
||||||
// string is signed by its first character equal (")
|
|
||||||
directive += '\"';
|
|
||||||
|
|
||||||
for( ++itext ; *itext && *itext!='\"' && *itext!='\n' ; ++itext )
|
|
||||||
directive += *itext;
|
|
||||||
|
|
||||||
if( *itext != '\"' )
|
|
||||||
// the second quotation mark (") is missing
|
|
||||||
directive.clear();
|
|
||||||
else
|
|
||||||
++itext;
|
|
||||||
|
|
||||||
// the second quotation mark (") we don't add into the 'directive'
|
|
||||||
|
|
||||||
return directive;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string Pattern::ReadDirectiveOrString()
|
|
||||||
{
|
|
||||||
SkipWhiteCharacters();
|
|
||||||
|
|
||||||
if( *itext == '\"' )
|
|
||||||
{
|
|
||||||
// we've got string
|
|
||||||
return ReadString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ReadDirective();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::CreateTreeReadItemDirectiveCheckEnding(Item & item)
|
|
||||||
{
|
|
||||||
SkipWhiteCharacters();
|
|
||||||
|
|
||||||
if( *itext != ']' )
|
|
||||||
{
|
|
||||||
item.type = Item::item_err;
|
|
||||||
|
|
||||||
while( *itext!=0 && *itext!=']' )
|
|
||||||
++itext;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( *itext == ']' )
|
|
||||||
++itext;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveIfany(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_ifany;
|
|
||||||
|
|
||||||
while( true )
|
|
||||||
{
|
|
||||||
std::string directive = ReadDirective();
|
|
||||||
|
|
||||||
if( directive.empty() )
|
|
||||||
break;
|
|
||||||
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item.directives.empty() )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveIfone(Item & item)
|
|
||||||
{
|
|
||||||
ReadDirectiveIfany(item);
|
|
||||||
|
|
||||||
if( item.type == Item::item_ifany )
|
|
||||||
item.type = Item::item_ifone;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveIs(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_is;
|
|
||||||
std::string directive = ReadDirective();
|
|
||||||
|
|
||||||
if( !directive.empty() )
|
|
||||||
{
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
|
|
||||||
directive = ReadDirectiveOrString();
|
|
||||||
|
|
||||||
if( !directive.empty() )
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item.directives.size() != 2 )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveIfindex(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_ifindex;
|
|
||||||
std::string directive = ReadDirective();
|
|
||||||
|
|
||||||
if( !directive.empty() )
|
|
||||||
{
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
|
|
||||||
directive = ReadDirective();
|
|
||||||
|
|
||||||
if( !directive.empty() )
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( item.directives.size() != 2 )
|
|
||||||
item.type = Item::item_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveFor(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_for;
|
|
||||||
std::string directive = ReadDirective();
|
|
||||||
|
|
||||||
if( !directive.empty() )
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
else
|
|
||||||
item.type = Item::item_err;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveComment(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_comment;
|
|
||||||
|
|
||||||
while( *itext && *itext!=']' && *itext!='\n' )
|
|
||||||
++itext;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::ReadDirectiveInclude(Item & item)
|
|
||||||
{
|
|
||||||
item.type = Item::item_include;
|
|
||||||
std::string directive = ReadString();
|
|
||||||
|
|
||||||
if( !directive.empty() )
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
else
|
|
||||||
item.type = Item::item_err;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::CreateTreeReadItemDirective(Item & item)
|
|
||||||
{
|
|
||||||
++itext;
|
|
||||||
|
|
||||||
std::string directive = ReadDirective();
|
|
||||||
|
|
||||||
if( directive == "if-any" )
|
|
||||||
ReadDirectiveIfany(item);
|
|
||||||
else
|
|
||||||
if( directive == "if-one" )
|
|
||||||
ReadDirectiveIfone(item);
|
|
||||||
else
|
|
||||||
if( directive == "is" )
|
|
||||||
ReadDirectiveIs(item);
|
|
||||||
else
|
|
||||||
if( directive == "if-index" )
|
|
||||||
ReadDirectiveIfindex(item);
|
|
||||||
else
|
|
||||||
if( directive == "end" )
|
|
||||||
item.type = Item::item_end;
|
|
||||||
else
|
|
||||||
if( directive == "else" )
|
|
||||||
item.type = Item::item_else;
|
|
||||||
else
|
|
||||||
if( directive == "for" )
|
|
||||||
ReadDirectiveFor(item);
|
|
||||||
else
|
|
||||||
if( directive == "include" )
|
|
||||||
ReadDirectiveInclude(item);
|
|
||||||
else
|
|
||||||
if( directive == "#" )
|
|
||||||
ReadDirectiveComment(item);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// user defined
|
|
||||||
item.directives.push_back(directive);
|
|
||||||
item.type = Item::item_normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
CreateTreeReadItemDirectiveCheckEnding(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::CreateTreeReadItemText(Item & item)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
while( (c = ReadCharInText()) != -1 )
|
|
||||||
item.text += c;
|
|
||||||
|
|
||||||
item.type = Item::item_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Pattern::CreateTreeReadItem(Item & item)
|
|
||||||
{
|
|
||||||
item.Clear();
|
|
||||||
|
|
||||||
if( *itext == '[' )
|
|
||||||
{
|
|
||||||
CreateTreeReadItemDirective(item);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( *itext )
|
|
||||||
{
|
|
||||||
CreateTreeReadItemText(item);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the end of the string
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::CreateTreeReadInclude(Item & item)
|
|
||||||
{
|
|
||||||
if( item.directives.empty() || item.directives[0].empty() || item.directives[0][0]!='\"' )
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string file_text = ReadFile( item.directives[0].c_str()+1 );
|
|
||||||
|
|
||||||
const char * itext_copy = itext;
|
|
||||||
itext = file_text.c_str();
|
|
||||||
CreateTree(item);
|
|
||||||
itext = itext_copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::CreateTreeReadIf(Item & item)
|
|
||||||
{
|
|
||||||
Item * pitem = item.AddItem();
|
|
||||||
CreateTree(*pitem);
|
|
||||||
|
|
||||||
if( pitem->LastItemType() == Item::item_else )
|
|
||||||
{
|
|
||||||
pitem->DeleteLastItem();
|
|
||||||
|
|
||||||
pitem = item.AddItem();
|
|
||||||
CreateTree(*pitem);
|
|
||||||
}
|
|
||||||
|
|
||||||
pitem->DeleteLastItem(); // it deletes [end] from the tree
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::CreateTreeReadFor(Item & item)
|
|
||||||
{
|
|
||||||
Item * pitem = item.AddItem();
|
|
||||||
CreateTree(*pitem);
|
|
||||||
|
|
||||||
pitem->DeleteLastItem(); // it deletes [end] from the tree
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::CreateTree(Item & item)
|
|
||||||
{
|
|
||||||
item.Clear();
|
|
||||||
item.type = Item::item_container;
|
|
||||||
|
|
||||||
Item item_temp;
|
|
||||||
|
|
||||||
while( CreateTreeReadItem(item_temp) )
|
|
||||||
{
|
|
||||||
if( item_temp.type == Item::item_comment )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Item * pitem = item.AddItem(item_temp);
|
|
||||||
|
|
||||||
if( item_temp.type==Item::item_end || item_temp.type==Item::item_else )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( pitem->type == Item::item_ifany ||
|
|
||||||
pitem->type == Item::item_ifone ||
|
|
||||||
pitem->type == Item::item_ifindex ||
|
|
||||||
pitem->type == Item::item_is )
|
|
||||||
CreateTreeReadIf(*pitem);
|
|
||||||
|
|
||||||
if( pitem->type == Item::item_for )
|
|
||||||
CreateTreeReadFor(*pitem);
|
|
||||||
|
|
||||||
if( pitem->type == Item::item_include )
|
|
||||||
CreateTreeReadInclude(*pitem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Pattern::Item
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
Pattern::Item * Pattern::Item::AddItem(const Pattern::Item * porg)
|
|
||||||
{
|
|
||||||
Item * pitem;
|
|
||||||
|
|
||||||
if( porg )
|
|
||||||
pitem = new Item(*porg);
|
|
||||||
else
|
|
||||||
pitem = new Item();
|
|
||||||
|
|
||||||
item_table.push_back(pitem);
|
|
||||||
|
|
||||||
return pitem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Pattern::Item * Pattern::Item::AddItem(const Pattern::Item & porg)
|
|
||||||
{
|
|
||||||
return AddItem(&porg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pattern::Item::ClearItems()
|
|
||||||
{
|
|
||||||
std::vector<Item*>::iterator i = item_table.begin();
|
|
||||||
|
|
||||||
for( ; i != item_table.end() ; ++i )
|
|
||||||
delete *i;
|
|
||||||
|
|
||||||
item_table.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pattern::Item::Clear()
|
|
||||||
{
|
|
||||||
ClearItems();
|
|
||||||
type = item_none;
|
|
||||||
text.clear();
|
|
||||||
directives.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Pattern::Item::ItemType Pattern::Item::LastItemType()
|
|
||||||
{
|
|
||||||
if( item_table.empty() )
|
|
||||||
return item_none;
|
|
||||||
|
|
||||||
return item_table.back()->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pattern::Item::DeleteLastItem()
|
|
||||||
{
|
|
||||||
if( item_table.empty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
delete item_table.back();
|
|
||||||
|
|
||||||
item_table.erase( item_table.end() - 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Pattern::Item::Item()
|
|
||||||
{
|
|
||||||
type = item_none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Pattern::Item::Item(const Pattern::Item & i) : type(i.type), text(i.text), directives(i.directives)
|
|
||||||
{
|
|
||||||
CopyItemTable(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Pattern::Item & Pattern::Item::operator=(const Pattern::Item & i)
|
|
||||||
{
|
|
||||||
type = i.type;
|
|
||||||
text = i.text;
|
|
||||||
directives = i.directives;
|
|
||||||
|
|
||||||
CopyItemTable(i);
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Pattern::Item::CopyItemTable(const Pattern::Item & item)
|
|
||||||
{
|
|
||||||
std::vector<Item*>::const_iterator i = item.item_table.begin();
|
|
||||||
|
|
||||||
for( ; i != item.item_table.end() ; ++i)
|
|
||||||
AddItem( *i );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Pattern::Item::~Item()
|
|
||||||
{
|
|
||||||
ClearItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Info
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
Info::Info()
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
iter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Generator
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::string & Generator::Generate(Pattern & data)
|
|
||||||
{
|
|
||||||
otext.clear();
|
|
||||||
MakeText( data.item_root );
|
|
||||||
|
|
||||||
return otext;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string & Generator::String()
|
|
||||||
{
|
|
||||||
return otext;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Generator::Insert(const std::string & key, UserFunction ufunction)
|
|
||||||
{
|
|
||||||
UserInfo ui;
|
|
||||||
ui.user_function = ufunction;
|
|
||||||
ui.iter = 0;
|
|
||||||
|
|
||||||
user_info_table.insert( std::make_pair(key, ui) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextContainer(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
std::vector<Pattern::Item*>::iterator i = item.item_table.begin();
|
|
||||||
|
|
||||||
for( ; i != item.item_table.end() ; ++i )
|
|
||||||
MakeText(**i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Generator::Find(const std::string & key, UserInfo ** user_info)
|
|
||||||
{
|
|
||||||
UserInfoTable::iterator i = user_info_table.find( key );
|
|
||||||
|
|
||||||
if( i == user_info_table.end() )
|
|
||||||
{
|
|
||||||
otext += CreateMsg("can't find", key.c_str() );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*user_info = &(i->second);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextNormal(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
if( item.directives.size() != 1 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
UserInfo * user_info;
|
|
||||||
|
|
||||||
if( Find(item.directives[0], &user_info) )
|
|
||||||
{
|
|
||||||
Info info;
|
|
||||||
(user_info->user_function)(info);
|
|
||||||
|
|
||||||
otext += info.text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextIf_go(Pattern::Item & item, bool result)
|
|
||||||
{
|
|
||||||
if( result )
|
|
||||||
{
|
|
||||||
if( item.item_table.size() > 0 )
|
|
||||||
MakeText( *item.item_table[0] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// second element can be (or not -- it's from [else])
|
|
||||||
if( item.item_table.size() > 1 )
|
|
||||||
MakeText( *item.item_table[1] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextIfany(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
std::vector<std::string>::iterator d = item.directives.begin();
|
|
||||||
unsigned how_many_true = 0;
|
|
||||||
|
|
||||||
for( ; d != item.directives.end() ; ++d )
|
|
||||||
{
|
|
||||||
UserInfo * user_info;
|
|
||||||
|
|
||||||
if( !Find(*d, &user_info) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
Info info;
|
|
||||||
(user_info->user_function)(info);
|
|
||||||
|
|
||||||
if( !info.text.empty() || info.result )
|
|
||||||
++how_many_true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, how_many_true == item.directives.size() );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextIfone(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
std::vector<std::string>::iterator d = item.directives.begin();
|
|
||||||
int how_many_true = 0;
|
|
||||||
|
|
||||||
for( ; d != item.directives.end() ; ++d )
|
|
||||||
{
|
|
||||||
UserInfo * user_info;
|
|
||||||
|
|
||||||
if( !Find(*d, &user_info) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
Info info;
|
|
||||||
(user_info->user_function)(info);
|
|
||||||
|
|
||||||
if( !info.text.empty() || info.result )
|
|
||||||
++how_many_true;
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, how_many_true > 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextIs(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
if( item.directives.size() != 2 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
UserInfo * user_info;
|
|
||||||
|
|
||||||
if( !Find(item.directives[0], &user_info) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool result = false;
|
|
||||||
Info info1, info2;
|
|
||||||
(user_info->user_function)(info1);
|
|
||||||
|
|
||||||
if( !item.directives[1].empty() && item.directives[1][0]=='\"' )
|
|
||||||
{
|
|
||||||
if( std::strcmp(info1.text.c_str(), item.directives[1].c_str()+1) == 0 )
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( Find(item.directives[1], &user_info) )
|
|
||||||
{
|
|
||||||
(user_info->user_function)(info2);
|
|
||||||
|
|
||||||
if( info1.result==info2.result && info1.text==info2.text )
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Generator::MakeTextIfindexnumber(Pattern::Item & item, UserInfo * user_info, bool & result)
|
|
||||||
{
|
|
||||||
if( item.directives.size() != 2 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char * number_text = item.directives[1].c_str();
|
|
||||||
char * last_char;
|
|
||||||
|
|
||||||
int number = (int)strtol(number_text, &last_char, 10);
|
|
||||||
|
|
||||||
if( *last_char == '\0' )
|
|
||||||
{
|
|
||||||
if( user_info->iter == number )
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
otext += CreateMsg("if-index: syntax error");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextIfindex(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
if( item.directives.size() != 2 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
UserInfo * user_info;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if( !Find(item.directives[0], &user_info) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
if( item.directives[1] == "odd" )
|
|
||||||
{
|
|
||||||
if( ( user_info->iter & 1) == 1 )
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( item.directives[1] == "even" )
|
|
||||||
{
|
|
||||||
if( ( user_info->iter & 1) == 0 )
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if( item.directives[1] == "first" )
|
|
||||||
{
|
|
||||||
if( user_info->iter == 0 )
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( !MakeTextIfindexnumber(item, user_info, result) )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeTextIf_go(item, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeTextFor(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
if( item.directives.size() != 1 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
UserInfo * user_info;
|
|
||||||
|
|
||||||
if( !Find(item.directives[0], &user_info) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
Info info;
|
|
||||||
user_info->iter = 0;
|
|
||||||
|
|
||||||
while( true )
|
|
||||||
{
|
|
||||||
(user_info->user_function)(info);
|
|
||||||
|
|
||||||
if( info.text.empty() && !info.result )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if( item.item_table.size() > 0 )
|
|
||||||
MakeText( *item.item_table[0] );
|
|
||||||
|
|
||||||
++info.iter;
|
|
||||||
user_info->iter = info.iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::MakeText(Pattern::Item & item)
|
|
||||||
{
|
|
||||||
switch( item.type )
|
|
||||||
{
|
|
||||||
case Pattern::Item::item_text:
|
|
||||||
otext += item.text;
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_container:
|
|
||||||
MakeTextContainer(item);
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_normal:
|
|
||||||
MakeTextNormal(item);
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_ifany:
|
|
||||||
MakeTextIfany(item);
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_ifone:
|
|
||||||
MakeTextIfone(item);
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_ifindex:
|
|
||||||
MakeTextIfindex(item);
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_is:
|
|
||||||
MakeTextIs(item);
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_for:
|
|
||||||
MakeTextFor(item);
|
|
||||||
break;
|
|
||||||
case Pattern::Item::item_err:
|
|
||||||
otext += CreateMsg("a wrong directive");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Generator::Clear()
|
|
||||||
{
|
|
||||||
user_info_table.clear();
|
|
||||||
otext.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Ezc
|
|
||||||
|
|
161
src/ezc.h
161
src/ezc.h
@@ -1,11 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* This file is a part of EZC -- Easy templating in C++
|
* This file is a part of EZC -- Easy templating in C++
|
||||||
* and is distributed under the (new) BSD licence.
|
* and is distributed under the (new) BSD licence.
|
||||||
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007, Tomasz Sowa
|
* Copyright (c) 2007-2010, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -35,160 +35,13 @@
|
|||||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* version 0.9.0
|
#ifndef headerfile_ezc_ezc
|
||||||
*
|
#define headerfile_ezc_ezc
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef headerfileezc
|
#include "utf8.h"
|
||||||
#define headerfileezc
|
#include "generator.h"
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <fstream>
|
|
||||||
#include <vector>
|
|
||||||
#include <map>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Ezc
|
|
||||||
{
|
|
||||||
|
|
||||||
std::string CreateMsg(const char * type, const char * arg = 0);
|
|
||||||
void SplitUnixDirectory(const char * name, std::string & dir, std::string & file);
|
|
||||||
void SplitUnixDirectory(const std::string & name, std::string & dir, std::string & file);
|
|
||||||
|
|
||||||
|
|
||||||
class Pattern
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void ParseFile(const std::string & file_name);
|
|
||||||
void ParseFile(const char * file_name);
|
|
||||||
void Directory(const char * d);
|
|
||||||
void Directory(const std::string & d);
|
|
||||||
|
|
||||||
struct Item
|
|
||||||
{
|
|
||||||
enum ItemType
|
|
||||||
{
|
|
||||||
item_none, item_container, item_text, item_ifany, item_for,
|
|
||||||
item_else, item_end, item_err, item_normal, item_ifindex,
|
|
||||||
item_include, item_is, item_ifone, item_comment
|
|
||||||
};
|
|
||||||
|
|
||||||
ItemType type;
|
|
||||||
std::string text;
|
|
||||||
std::vector<Item*> item_table;
|
|
||||||
std::vector<std::string> directives;
|
|
||||||
|
|
||||||
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();
|
|
||||||
ItemType LastItemType();
|
|
||||||
void DeleteLastItem();
|
|
||||||
void Clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
Item item_root;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char * itext;
|
|
||||||
std::string directory;
|
|
||||||
|
|
||||||
|
|
||||||
bool CheckFileName(const char * name);
|
|
||||||
std::string ReadFile(const char * name);
|
|
||||||
|
|
||||||
int ReadCharInText();
|
|
||||||
void SkipWhiteCharacters();
|
|
||||||
|
|
||||||
std::string ReadDirective();
|
|
||||||
std::string ReadString();
|
|
||||||
std::string ReadDirectiveOrString();
|
|
||||||
|
|
||||||
void CreateTreeReadItemDirectiveCheckEnding(Item & item);
|
|
||||||
|
|
||||||
void ReadDirectiveIfany(Item & item);
|
|
||||||
void ReadDirectiveIfone(Item & item);
|
|
||||||
void ReadDirectiveIs(Item & item);
|
|
||||||
void ReadDirectiveIfindex(Item & item);
|
|
||||||
void ReadDirectiveFor(Item & item);
|
|
||||||
void ReadDirectiveComment(Item & item);
|
|
||||||
void ReadDirectiveInclude(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);
|
|
||||||
|
|
||||||
}; // Pattern
|
|
||||||
|
|
||||||
|
|
||||||
struct Info
|
|
||||||
{
|
|
||||||
std::string text;
|
|
||||||
bool result;
|
|
||||||
int iter;
|
|
||||||
|
|
||||||
Info();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Generator
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef void (*UserFunction)(Info &);
|
|
||||||
|
|
||||||
struct UserInfo
|
|
||||||
{
|
|
||||||
UserFunction user_function;
|
|
||||||
int iter;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<std::string, UserInfo> UserInfoTable;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void Insert(const std::string & key, UserFunction ufunction);
|
|
||||||
std::string & Generate(Pattern & data);
|
|
||||||
std::string & String();
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
UserInfoTable user_info_table;
|
|
||||||
std::string otext;
|
|
||||||
|
|
||||||
bool Find(const std::string & key, UserInfo ** user_info);
|
|
||||||
void MakeTextIf_go(Pattern::Item & item, bool result);
|
|
||||||
bool MakeTextIfindexnumber(Pattern::Item & item, UserInfo * user_info, bool & result);
|
|
||||||
void MakeTextIfany(Pattern::Item & item);
|
|
||||||
void MakeTextIfone(Pattern::Item & item);
|
|
||||||
void MakeTextIfindex(Pattern::Item & item);
|
|
||||||
void MakeTextFor(Pattern::Item & item);
|
|
||||||
void MakeTextContainer(Pattern::Item & item);
|
|
||||||
void MakeTextNormal(Pattern::Item & item);
|
|
||||||
void MakeTextIs(Pattern::Item & item);
|
|
||||||
void MakeText(Pattern::Item & item);
|
|
||||||
|
|
||||||
}; // Generator
|
|
||||||
|
|
||||||
} // namespace Ezc
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
265
src/functions.h
Executable file
265
src/functions.h
Executable file
@@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* 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-2012, 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"
|
||||||
|
#include "stringconv.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ezc
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// functions or variables
|
||||||
|
template<class StreamType>
|
||||||
|
class Functions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef void (*UserFunction)(FunInfo<StreamType> &);
|
||||||
|
enum Type { function, variable };
|
||||||
|
|
||||||
|
struct Function
|
||||||
|
{
|
||||||
|
Function();
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
UserFunction user_function; // used when type is 'function'
|
||||||
|
std::wstring variable; // used when type is 'variable'
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<std::wstring, Function> FunctionsTable;
|
||||||
|
typedef typename FunctionsTable::iterator Iterator;
|
||||||
|
|
||||||
|
|
||||||
|
void Insert(const char * key, UserFunction ufunction); // inserting a function
|
||||||
|
void Insert(const char * key, const char * var); // inserting a variable
|
||||||
|
void Insert(const char * key, const std::string & var); // inserting a variable
|
||||||
|
void Insert(const std::string & key, UserFunction ufunction); // inserting a function
|
||||||
|
void Insert(const std::string & key, const char * var); // inserting a variable
|
||||||
|
void Insert(const std::string & key, const std::string & var); // inserting a variable
|
||||||
|
void Insert(const 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);
|
||||||
|
|
||||||
|
Iterator Begin();
|
||||||
|
Iterator End();
|
||||||
|
size_t Size() const;
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FunctionsTable functions_tab;
|
||||||
|
std::wstring temp_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
Functions<StreamType>::Function::Function()
|
||||||
|
{
|
||||||
|
type = Functions::variable;
|
||||||
|
user_function = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void Functions<StreamType>::Insert(const char * key, UserFunction ufunction)
|
||||||
|
{
|
||||||
|
Function f;
|
||||||
|
f.type = function;
|
||||||
|
f.user_function = ufunction;
|
||||||
|
|
||||||
|
AssignString(key, temp_key);
|
||||||
|
functions_tab[temp_key] = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
typename Functions<StreamType>::Iterator Functions<StreamType>::Begin()
|
||||||
|
{
|
||||||
|
return functions_tab.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
typename Functions<StreamType>::Iterator Functions<StreamType>::End()
|
||||||
|
{
|
||||||
|
return functions_tab.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
size_t Functions<StreamType>::Size() const
|
||||||
|
{
|
||||||
|
return functions_tab.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Ezc
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
107
src/funinfo.h
Executable file
107
src/funinfo.h
Executable file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* 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-2011, 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_funinfo
|
||||||
|
#define headerfile_ezc_funinfo
|
||||||
|
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Ezc
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
struct FunInfo
|
||||||
|
{
|
||||||
|
// output stream
|
||||||
|
StreamType & out;
|
||||||
|
|
||||||
|
// the out stream is treated in case sensitive
|
||||||
|
// used only in [is...] statements
|
||||||
|
// default: true
|
||||||
|
bool case_sensitive;
|
||||||
|
|
||||||
|
// table of parameters
|
||||||
|
// the table can be empty
|
||||||
|
std::vector<std::wstring> & params;
|
||||||
|
|
||||||
|
// the first parameter
|
||||||
|
// you can always use it even if there is not any parameters (params is empty)
|
||||||
|
// in such a way the reference points to an empty string
|
||||||
|
const std::wstring & par;
|
||||||
|
|
||||||
|
// an input stream used in [filter] statement
|
||||||
|
// if there is other statement than [filter] then this is an empty stream
|
||||||
|
const StreamType & in;
|
||||||
|
|
||||||
|
// this is set by Generator
|
||||||
|
// it indicates the number of a current iteration in the last [for] statement (the first is 0)
|
||||||
|
// if there was not any [for] before the value is zero
|
||||||
|
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 & first_par,
|
||||||
|
const StreamType & i) : out(o), params(pars), par(first_par), in(i)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Clear()
|
||||||
|
{
|
||||||
|
res = false; // false by default
|
||||||
|
iter = 0;
|
||||||
|
case_sensitive = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Ezc
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
1195
src/generator.h
Executable file
1195
src/generator.h
Executable file
File diff suppressed because it is too large
Load Diff
165
src/item.cpp
Executable file
165
src/item.cpp
Executable file
@@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* 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-2011, 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), file_name(i.file_name), functions(i.functions)
|
||||||
|
{
|
||||||
|
CopyItemTable(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Item & Item::operator=(const Item & i)
|
||||||
|
{
|
||||||
|
type = i.type;
|
||||||
|
text = i.text;
|
||||||
|
file_name = i.file_name;
|
||||||
|
functions = i.functions;
|
||||||
|
|
||||||
|
ClearItems();
|
||||||
|
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
|
||||||
|
|
98
src/item.h
Executable file
98
src/item.h
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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-2011, 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>
|
||||||
|
#include "funinfo.h"
|
||||||
|
|
||||||
|
|
||||||
|
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, item_filter
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Function
|
||||||
|
{
|
||||||
|
std::wstring name; // function name
|
||||||
|
std::vector<std::wstring> params; // function parameters
|
||||||
|
void * fun_cache;
|
||||||
|
|
||||||
|
Function()
|
||||||
|
{
|
||||||
|
fun_cache = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
1041
src/pattern.cpp
Executable file
1041
src/pattern.cpp
Executable file
File diff suppressed because it is too large
Load Diff
261
src/pattern.h
Executable file
261
src/pattern.h
Executable file
@@ -0,0 +1,261 @@
|
|||||||
|
/*
|
||||||
|
* 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-2011, 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 "functions.h"
|
||||||
|
#include "stringconv.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
#ifdef EZC_USE_WINIX_LOGGER
|
||||||
|
#include "core/log.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
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 wchar_t * type, const wchar_t * arg = 0);
|
||||||
|
static bool IsWhite(wchar_t c);
|
||||||
|
|
||||||
|
Item item_root;
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void CacheFunctions(Functions<StreamType> & fun)
|
||||||
|
{
|
||||||
|
CacheFunctions(item_root, fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearCache();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// 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 ReadDirectiveFilter(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);
|
||||||
|
|
||||||
|
|
||||||
|
template<class StreamType>
|
||||||
|
void CacheFunctions(Item & item, Functions<StreamType> & fun)
|
||||||
|
{
|
||||||
|
typename Functions<StreamType>::Function * ezc_fun;
|
||||||
|
|
||||||
|
// one exception (if_index is putting its argument on the functions stack)
|
||||||
|
if( item.type != Item::item_ifindex )
|
||||||
|
{
|
||||||
|
for(size_t f=0; f < item.functions.size() ; ++f)
|
||||||
|
{
|
||||||
|
if( fun.Find(item.functions[f].name, &ezc_fun) )
|
||||||
|
{
|
||||||
|
item.functions[f].fun_cache = ezc_fun;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.functions[f].fun_cache = 0;
|
||||||
|
|
||||||
|
#ifdef EZC_USE_WINIX_LOGGER
|
||||||
|
log << log1 << "Ezc: unknown function: " << item.functions[f].name << logend;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i=0; i < item.item_tab.size() ; ++i)
|
||||||
|
CacheFunctions(*item.item_tab[i], fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ClearCache(Item & item);
|
||||||
|
|
||||||
|
}; // class Pattern
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Ezc
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
108
src/stringconv.cpp
Executable file
108
src/stringconv.cpp
Executable file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* 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){}
|
||||||
|
|
||||||
|
if( dst.capacity() < dst.size() + len )
|
||||||
|
dst.reserve(dst.size() + len + 128);
|
||||||
|
|
||||||
|
for( ; *src ; ++src )
|
||||||
|
dst += static_cast<unsigned char>(*src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AssignString(const std::string & src, std::wstring & dst, bool clear)
|
||||||
|
{
|
||||||
|
if( clear )
|
||||||
|
dst.clear();
|
||||||
|
|
||||||
|
if( dst.capacity() < dst.size() + src.size() )
|
||||||
|
dst.reserve(dst.size() + src.size() + 128);
|
||||||
|
|
||||||
|
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){}
|
||||||
|
|
||||||
|
if( dst.capacity() < dst.size() + len )
|
||||||
|
dst.reserve(dst.size() + len + 128);
|
||||||
|
|
||||||
|
for( ; *src ; ++src )
|
||||||
|
dst += static_cast<char>(*src);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AssignString(const std::wstring & src, std::string & dst, bool clear)
|
||||||
|
{
|
||||||
|
if( clear )
|
||||||
|
dst.clear();
|
||||||
|
|
||||||
|
if( dst.capacity() < dst.size() + src.size() )
|
||||||
|
dst.reserve(dst.size() + src.size() + 128);
|
||||||
|
|
||||||
|
for(size_t i=0 ; i<src.size() ; ++i )
|
||||||
|
dst += static_cast<char>(src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Ezc
|
||||||
|
|
60
src/stringconv.h
Executable file
60
src/stringconv.h
Executable 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
|
896
src/utf8.cpp
Executable file
896
src/utf8.cpp
Executable file
@@ -0,0 +1,896 @@
|
|||||||
|
/*
|
||||||
|
* 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-2011, 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 (null terminated)
|
||||||
|
|
||||||
|
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 the string has '\0' at the first character)
|
||||||
|
even if there are errors the functions returns a different from zero value
|
||||||
|
*/
|
||||||
|
size_t UTF8ToInt(const char * utf8, int & res, bool & correct)
|
||||||
|
{
|
||||||
|
size_t i, len;
|
||||||
|
|
||||||
|
res = 0;
|
||||||
|
correct = false;
|
||||||
|
|
||||||
|
if( *utf8 == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( !UTF8ToInt_FirstOctet(utf8[0], len, res) )
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for(i=1 ; i<len ; ++i)
|
||||||
|
{
|
||||||
|
if( utf8[i] == 0 )
|
||||||
|
return 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
*/
|
||||||
|
static void IntToWide(int c, std::wstring & res)
|
||||||
|
{
|
||||||
|
if( sizeof(wchar_t)==2 && c>0xffff )
|
||||||
|
{
|
||||||
|
c -= 0x10000;
|
||||||
|
res += static_cast<wchar_t>(((c >> 10) & 0x3FF) + 0xD800);
|
||||||
|
res += static_cast<wchar_t>((c & 0x3FF) + 0xDC00);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res += static_cast<wchar_t>(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
if( mode == 1 )
|
||||||
|
res += 0xFFFD; // U+FFFD "replacement character"
|
||||||
|
|
||||||
|
was_error = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntToWide(z, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
if( mode == 1 )
|
||||||
|
res += 0xFFFD; // U+FFFD "replacement character"
|
||||||
|
|
||||||
|
was_error = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntToWide(z, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
converting a wide character into one int
|
||||||
|
|
||||||
|
returns how many wide characters were used
|
||||||
|
if string_len is greater than 0 then the return value is always greater than zero too
|
||||||
|
*/
|
||||||
|
static size_t WideToInt(const wchar_t * wide_string, size_t string_len, int & z, bool & correct)
|
||||||
|
{
|
||||||
|
if( string_len == 0 )
|
||||||
|
{
|
||||||
|
z = 0;
|
||||||
|
correct = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
z = static_cast<int>(*wide_string);
|
||||||
|
correct = true;
|
||||||
|
|
||||||
|
if( sizeof(wchar_t) == 2 && (z>=0xD800 && z<=0xDFFF) )
|
||||||
|
{
|
||||||
|
if( z>=0xD800 && z<=0xDBFF && string_len>1 )
|
||||||
|
{
|
||||||
|
int z2 = *(wide_string+1);
|
||||||
|
|
||||||
|
if( z2>=0xDC00 && z2<=0xDFFF )
|
||||||
|
{
|
||||||
|
z = 0x10000 + (((z & 0x3FF) << 10) | (z2 & 0x3FF));
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
correct = false;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
correct = false;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
an auxiliary function for converting from wide characters to UTF-8
|
||||||
|
converting a wide character into one int
|
||||||
|
|
||||||
|
returns how many wide characters were used
|
||||||
|
if wide_string has at least one character then the return value is always greater than zero too
|
||||||
|
*/
|
||||||
|
static size_t WideToInt(const wchar_t * wide_string, int & z, bool & correct)
|
||||||
|
{
|
||||||
|
size_t min_str_len = 1;
|
||||||
|
|
||||||
|
if( *wide_string == 0 )
|
||||||
|
{
|
||||||
|
z = 0;
|
||||||
|
correct = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *(wide_string+1) != 0 )
|
||||||
|
min_str_len = 2;
|
||||||
|
|
||||||
|
return WideToInt(wide_string, min_str_len, z, correct);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary function for converting from wide characters to UTF-8
|
||||||
|
|
||||||
|
returns how many wide characters were used
|
||||||
|
if string_len is greater than 0 then the return value is always greater than zero too
|
||||||
|
*/
|
||||||
|
static size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::string & utf8, bool & was_error, int mode)
|
||||||
|
{
|
||||||
|
int z;
|
||||||
|
bool correct;
|
||||||
|
size_t chars;
|
||||||
|
|
||||||
|
chars = WideToInt(wide_string, string_len, z, correct);
|
||||||
|
|
||||||
|
if( correct )
|
||||||
|
correct = IntToUTF8(z, utf8, false) != 0;
|
||||||
|
|
||||||
|
if( !correct )
|
||||||
|
{
|
||||||
|
if( mode == 1 )
|
||||||
|
IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character"
|
||||||
|
|
||||||
|
was_error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary function for converting from wide characters to UTF-8
|
||||||
|
|
||||||
|
returns how many wide characters were used
|
||||||
|
if wide_string has at least one character then the return value is always greater than zero too
|
||||||
|
*/
|
||||||
|
static size_t WideOneToUTF8(const wchar_t * wide_string, std::string & utf8, bool & was_error, int mode)
|
||||||
|
{
|
||||||
|
int z;
|
||||||
|
bool correct;
|
||||||
|
size_t chars;
|
||||||
|
|
||||||
|
chars = WideToInt(wide_string, z, correct);
|
||||||
|
|
||||||
|
if( correct )
|
||||||
|
correct = IntToUTF8(z, utf8, false) != 0;
|
||||||
|
|
||||||
|
if( !correct )
|
||||||
|
{
|
||||||
|
if( mode == 1 )
|
||||||
|
IntToUTF8(0xFFFD, utf8, false); // U+FFFD "replacement character"
|
||||||
|
|
||||||
|
was_error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary function for converting from wide characters to UTF-8
|
||||||
|
|
||||||
|
returns how many wide characters were used
|
||||||
|
if string_len is greater than 0 then the return value is always greater than zero too
|
||||||
|
*/
|
||||||
|
static size_t WideOneToUTF8(const wchar_t * wide_string, size_t string_len, std::ostream & utf8, bool & was_error, int mode)
|
||||||
|
{
|
||||||
|
int z;
|
||||||
|
bool correct;
|
||||||
|
size_t chars;
|
||||||
|
|
||||||
|
chars = WideToInt(wide_string, string_len, z, correct);
|
||||||
|
|
||||||
|
if( correct )
|
||||||
|
correct = IntToUTF8(z, utf8) != 0;
|
||||||
|
|
||||||
|
if( !correct )
|
||||||
|
{
|
||||||
|
if( mode == 1 )
|
||||||
|
IntToUTF8(0xFFFD, utf8); // U+FFFD "replacement character"
|
||||||
|
|
||||||
|
was_error = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary function for converting from wide characters to UTF-8
|
||||||
|
*/
|
||||||
|
static size_t WideOneToUTF8(const wchar_t * wide_string, std::ostream & utf8, bool & was_error, int mode)
|
||||||
|
{
|
||||||
|
size_t min_str_len = 1;
|
||||||
|
|
||||||
|
if( *wide_string == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( *(wide_string+1) != 0 )
|
||||||
|
min_str_len = 2;
|
||||||
|
|
||||||
|
return WideOneToUTF8(wide_string, min_str_len, utf8, was_error, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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;
|
||||||
|
size_t chars;
|
||||||
|
|
||||||
|
if( clear )
|
||||||
|
utf8.clear();
|
||||||
|
|
||||||
|
while( string_len > 0 )
|
||||||
|
{
|
||||||
|
chars = WideOneToUTF8(wide_string, string_len, utf8, was_error, mode);
|
||||||
|
wide_string += chars;
|
||||||
|
string_len -= chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
while( *wide_string )
|
||||||
|
wide_string += WideOneToUTF8(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;
|
||||||
|
size_t chars;
|
||||||
|
|
||||||
|
while( string_len > 0 )
|
||||||
|
{
|
||||||
|
chars = WideOneToUTF8(wide_string, string_len, utf8, was_error, mode);
|
||||||
|
wide_string += chars;
|
||||||
|
string_len -= chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
while( *wide_string )
|
||||||
|
wide_string += WideOneToUTF8(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
|
||||||
|
|
||||||
|
|
||||||
|
|
111
src/utf8.h
Executable file
111
src/utf8.h
Executable file
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* 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-2011, 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
|
||||||
|
|
||||||
|
when wchar_t is 4 bytes length we use UTF-32
|
||||||
|
when wchar_t is 2 bytes length we use UTF-16 (with surrogate pairs)
|
||||||
|
|
||||||
|
UTF-16
|
||||||
|
http://www.ietf.org/rfc/rfc2781.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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 char * utf8, 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
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
|
Reference in New Issue
Block a user