// $Id: CxxFile.hh,v 1.29 2004/05/07 06:53:14 christof Exp $ /* glade--: C++ frontend for glade (Gtk+ User Interface Builder) * Copyright (C) 1998 Christof Petig * Copyright (C) 1999-2000 Adolf Petig GmbH & Co. KG, written by Christof Petig * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // 2do: When to push ??? // see also Makefile.hh #ifndef CXXFILE_HH #define CXXFILE_HH #include "SystemFile.hh" #include #include // I'd like to put these in an namespace, but not all compiler support it // yet enum CxxFile_Context { ctx_Outside, // nothing pending, new line ctx_ClassPrivate, // within a class declaration ctx_ClassPublic, ctx_ClassProtected, ctx_Block, // perhaps an alias for Outside ctx_ReturnType, // return type of a function declaration ctx_FunctionName, // name of a function declaration, perhaps call ctx_MidFunctionArgs, // argument of a function ctx_MidConstructor, // constructors ctx_MidConstruction, // 2nd+ constructor ctx_MidCtorArgs, // Arguments to a member constructor ctx_DefineName, // define Name ctx_DefineBody, // define Body ctx_Declaration, // inside a declaration (';' at end of line) ctx_Definition, // perhaps ';' after block (see Global_Context) ctx_Statement, // inside a statement ctx_ShortComment, // inside a short comment ctx_Comment, // inside a comment ctx_ClassName, // just behind 'class ' ctx_RValue, // just behind ' = ' ctx_RValueWritten, // behind ' = something' ctx_Derivation, // just behind 'class X :' ctx_CppIf, // #if ctx_CppIfDef, // #if[n]def ctx_BlockStatement, // for, if, else, while ctx_Namespace, // namespace }; enum CxxFile_Global_Context { gc_start, // start of file gc_include, // includes gc_declaration, // variable, class or function declaration gc_statement, // statement or function call gc_class, // class/struct/union definition gc_function, // function definition }; // this @$%& C++ standard does not allow this enum inside CxxFile // if you want to use this operation inside inline declared functions!!! // namespaces cure this (sort of) extern std::ostream &operator<<(std::ostream &,const CxxFile_Context &ctx); extern std::ostream &operator<<(std::ostream &,const CxxFile_Global_Context &ctx); class CxxFile : public SystemFile { public: typedef CxxFile_Global_Context Global_Context; typedef CxxFile_Context Context; static UniqueValue element_types; static const UniqueValue::value_t v_IncludeBracket; static const UniqueValue::value_t v_IncludeQuote; struct element_t { UniqueValue::value_t type; std::string identifier; element_t(UniqueValue::value_t v,const std::string &i) : type(v), identifier(i) {} bool operator==(const element_t &b) const { return type==b.type && identifier==b.identifier; } bool operator<(const element_t &b) const { return type t_statestack; t_statestack pushed; std::set elements; bool empty_line:1; bool indent_pending:1; void push(Context c,int indent_delta=0); void pop(); void new_context(Context c); SystemFile &Output(); void SomethingShiftingLeft(); void init() { empty_line=true; indent_pending=true; } public: CxxFile() : empty_line(true), indent_pending(true) {} protected: CxxFile(CxxFile *fp,unsigned int stage=0) : SystemFile(fp,stage) { fp->EndLine(); init(); state=fp->state; } public: CxxFile(std::ofstream &str, const std::string &name="") : SystemFile(str, name) { init(); } #if 0 // not portable ! CxxFile(int fd, const std::string &name="") : SystemFile(fd, name) { init(); } #endif CxxFile(const std::string &name) : SystemFile(name) { init(); } ~CxxFile() { close(); } // perhaps shadow open to clear some variables, done by close? void close(); CxxFile &GlobalContext(Global_Context new_gc,bool stay_inside=false); CxxFile &ToOutside(); CxxFile &Include(const std::string &name,bool local=false); CxxFile &FunctionArg(); CxxFile &Funct_ReturnType(); CxxFile &Funct_Storage() { return Funct_ReturnType(); } CxxFile &FunctionName(); CxxFile &StartBlock(); CxxFile &EndBlock(); CxxFile &BlockStatement(); // if(), else, while(), for() CxxFile &TypeDefinition(); // ?? CxxFile &EndType(); CxxFile &Private(); CxxFile &Protected(); CxxFile &Public(); CxxFile_Context Visibility(); // !const, calls ToOutside() CxxFile &Visibility(CxxFile_Context ctx); CxxFile &NewLine(bool end_this_line=true); CxxFile &Statement(); CxxFile &Declaration(); CxxFile &Definition(); CxxFile &Class(); CxxFile &EndLine(bool endBlock=false); CxxFile &ShortComment(); CxxFile &VSpace() { NewLine(false); empty_line=false; return NewLine(false); } CxxFile &DefineName(); CxxFile &DefineBody(); CxxFile &CppIf(); CxxFile &CppElse(); CxxFile &CppElif(); CxxFile &EndIf(); CxxFile &Constructor(); CxxFile &Assignment(); CxxFile &Derivation(); CxxFile &Namespace(); CxxFile &Construct(const std::string &instance, const std::string ¶ms) { return Constructor() << instance << '(' << params << ')'; } CxxFile &EndIf(const std::string &s) { EndIf() << s; // empty_line=true; // what was this for? return *this; } CxxFile &CppIf(const std::string &s) { return CppIf() << s; } CxxFile &Undef(const std::string &s) { NewLine().NoIndent() << "#undef " << s; NewLine(false); return *this; } CxxFile &FunctionEndArgs(); // convenience Functions: CxxFile &NoIndent() { indent_pending=false; return *this; } CxxFile &FunctionArg(const std::string &s) { return FunctionArg()<= 3 // adaptor template CxxFile &operator<<(const U &t) { SomethingShiftingLeft(); Output() << t; return *this; } #else // older compilers do not work correctly # define op_shl(U) CxxFile &operator<<(const U &t) \ { SomethingShiftingLeft(); \ Output() << t; \ return *this; \ } op_shl(std::string) op_shl(char * const) op_shl(signed int) op_shl(unsigned int) op_shl(unsigned long) op_shl(signed long) op_shl(char) #ifdef __CHAR_UNSIGNED__ op_shl(signed char) #else op_shl(unsigned char) #endif op_shl(float) #undef op_shl #endif }; #endif