/* * This file is a part of EZC -- Easy templating in C++ * and is distributed under the (new) BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2007-2008, 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 headerfileezc #define headerfileezc #include #include #include #include #include #include #include namespace Ezc { void CreateMsg(std::ostringstream & o, const char * type, const char * arg = 0); 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: Pattern(); void ParseFile(const std::string & file_name); void ParseFile(const char * file_name); void ParseString(const std::string & str); void ParseString(const char * str); void Directory(const char * d); void Directory(const std::string & d); struct Item { // change the name to 'Type' enum ItemType { item_none, item_container, item_text, item_ifany, item_ifno, item_for, item_else, item_end, item_err, item_normal, item_ifindex, item_include, item_is, item_ifone, item_comment, item_def }; struct Directive { bool is_text; // if true that means a directive in quotes "static text" std::string name; }; ItemType type; std::string text; std::vector item_table; std::vector 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; // 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_all_white; private: const char * itext; std::string directory; bool CheckFileName(const char * name); std::string ReadFile(const std::string & name); std::string ReadFile(const char * name); int ReadCharInText(); bool IsWhite(int c); void SkipWhiteCharacters(); void CheckWhiteAndDelete(std::string & s); Item::Directive ReadDirective(); Item::Directive ReadString(); Item::Directive ReadDirectiveOrString(); void CreateTreeReadItemDirectiveCheckEnding(Item & item); void ReadDirectiveIfany(Item & item); void ReadDirectiveIfno(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 ReadDirectiveDef(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 { // this variables you can set in your function std::ostringstream & out; //std::string out_string; bool result; // in a [is function "text"] statement this is the pointer to "text" object // otherwise this is null pointer const std::string * is; // this is set by Generator // normally is 0 // in a [for] statement it indicates the number of the current iteration (the first is 0) int iter; Info(std::ostringstream & o); void Clear(); }; // functions or variables class Functions { public: typedef void (*UserFunction)(Info &); enum Type { function, variable }; struct Function { Type type; UserFunction user_function; std::string variable; int iter; bool is_for; // true if is used by a [for] statement bool is_running; // true if this function (if is) is currently running Function(); }; void Insert(const std::string & key, UserFunction ufunction); // inserting a function void Insert(const std::string & key, const char * var); // inserting a variable void Insert(const std::string & key, const std::string & var); // inserting a variable bool Find(const std::string & key, Function ** fun); void Clear(); private: typedef std::map FunctionsTable; FunctionsTable functions_table; }; class Generator { public: Generator(std::ostringstream &, Pattern & data, Functions & functions); void Generate(); private: std::ostringstream & output_stream; Pattern & pattern; Functions & functions; Info info1, info2; int loop; bool Find(const std::string & key, Functions::Function ** function); void Call(Functions::Function * function, Info & info, const std::string * is = 0); bool Call(const std::string & name, Info & info, Functions::Function ** pfun = 0, const std::string * is = 0); void CallUserFunction(Functions::Function * function, Info & info); void CallVariable(Functions::Function * function, Info & info); void MakeTextIf_go(Pattern::Item & item, bool result); bool MakeTextIfindexnumber(Pattern::Item & item, Functions::Function * function, bool & result); void MakeTextIfany(Pattern::Item & item); void MakeTextIfno(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); bool MakeTextIsFunText(const std::string & fun_name, const std::string & text, bool & res); bool MakeTextIsFunFun(const std::string & fun_name1, const std::string & fun_name2, bool & res); void MakeTextIs(Pattern::Item & item); void MakeTextDefine(Pattern::Item & item); void MakeText(Pattern::Item & item); }; // Generator } // namespace Ezc #endif