1 // $Id: CxxFile.hh,v 1.29 2004/05/07 06:53:14 christof Exp $ 2 /* glade--: C++ frontend for glade (Gtk+ User Interface Builder) 3 * Copyright (C) 1998 Christof Petig 4 * Copyright (C) 1999-2000 Adolf Petig GmbH & Co. KG, written by Christof Petig 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 */ 20 21 // 2do: When to push ??? 22 23 // see also Makefile.hh 24 25 #ifndef CXXFILE_HH 26 #define CXXFILE_HH 27 28 #include "SystemFile.hh" 29 #include <set> 30 #include <UniqueValue.h> 31 32 // I'd like to put these in an namespace, but not all compiler support it 33 // yet 34 35 enum CxxFile_Context 36 { ctx_Outside, // nothing pending, new line 37 ctx_ClassPrivate, // within a class declaration 38 ctx_ClassPublic, 39 ctx_ClassProtected, 40 ctx_Block, // perhaps an alias for Outside 41 ctx_ReturnType, // return type of a function declaration 42 ctx_FunctionName, // name of a function declaration, perhaps call 43 ctx_MidFunctionArgs, // argument of a function 44 ctx_MidConstructor, // constructors 45 ctx_MidConstruction, // 2nd+ constructor 46 ctx_MidCtorArgs, // Arguments to a member constructor 47 ctx_DefineName, // define Name 48 ctx_DefineBody, // define Body 49 ctx_Declaration, // inside a declaration (';' at end of line) 50 ctx_Definition, // perhaps ';' after block (see Global_Context) 51 ctx_Statement, // inside a statement 52 ctx_ShortComment, // inside a short comment 53 ctx_Comment, // inside a comment 54 ctx_ClassName, // just behind 'class ' 55 ctx_RValue, // just behind ' = ' 56 ctx_RValueWritten, // behind ' = something' 57 ctx_Derivation, // just behind 'class X :' 58 ctx_CppIf, // #if 59 ctx_CppIfDef, // #if[n]def 60 ctx_BlockStatement, // for, if, else, while 61 ctx_Namespace, // namespace 62 }; 63 64 enum CxxFile_Global_Context 65 { gc_start, // start of file 66 gc_include, // includes 67 gc_declaration, // variable, class or function declaration 68 gc_statement, // statement or function call 69 gc_class, // class/struct/union definition 70 gc_function, // function definition 71 }; 72 73 // this @$%& C++ standard does not allow this enum inside CxxFile 74 // if you want to use this operation inside inline declared functions!!! 75 // namespaces cure this (sort of) 76 extern std::ostream &operator<<(std::ostream &,const CxxFile_Context &ctx); 77 extern std::ostream &operator<<(std::ostream &,const CxxFile_Global_Context &ctx); 78 79 class CxxFile : public SystemFile 80 { 81 public: 82 typedef CxxFile_Global_Context Global_Context; 83 typedef CxxFile_Context Context; 84 85 static UniqueValue element_types; 86 static const UniqueValue::value_t v_IncludeBracket; 87 static const UniqueValue::value_t v_IncludeQuote; 88 89 struct element_t 90 { UniqueValue::value_t type; 91 std::string identifier; 92 element_tCxxFile::element_t93 element_t(UniqueValue::value_t v,const std::string &i) 94 : type(v), identifier(i) {} operator ==CxxFile::element_t95 bool operator==(const element_t &b) const 96 { return type==b.type && identifier==b.identifier; } operator <CxxFile::element_t97 bool operator<(const element_t &b) const 98 { return type<b.type || (type==b.type && identifier<b.identifier); } 99 }; 100 private: 101 struct t_state 102 { int indentation; 103 int cpp_indentation; 104 Context context; 105 Global_Context global; 106 t_stateCxxFile::t_state107 t_state() : indentation(0), cpp_indentation(0), 108 context(ctx_Outside), global(gc_start) {} 109 } state; 110 111 typedef std::vector<t_state> t_statestack; 112 t_statestack pushed; 113 114 std::set<element_t> elements; 115 116 bool empty_line:1; 117 bool indent_pending:1; 118 119 void push(Context c,int indent_delta=0); 120 void pop(); 121 void new_context(Context c); 122 SystemFile &Output(); 123 void SomethingShiftingLeft(); 124 init()125 void init() 126 { empty_line=true; 127 indent_pending=true; 128 } 129 public: CxxFile()130 CxxFile() : empty_line(true), indent_pending(true) {} 131 protected: CxxFile(CxxFile * fp,unsigned int stage=0)132 CxxFile(CxxFile *fp,unsigned int stage=0) 133 : SystemFile(fp,stage) 134 { fp->EndLine(); init(); state=fp->state; } 135 public: CxxFile(std::ofstream & str,const std::string & name="")136 CxxFile(std::ofstream &str, const std::string &name="") 137 : SystemFile(str, name) { init(); } 138 #if 0 // not portable ! 139 CxxFile(int fd, const std::string &name="") 140 : SystemFile(fd, name) { init(); } 141 #endif CxxFile(const std::string & name)142 CxxFile(const std::string &name) 143 : SystemFile(name) { init(); } ~CxxFile()144 ~CxxFile() { close(); } 145 // perhaps shadow open to clear some variables, done by close? 146 void close(); 147 148 CxxFile &GlobalContext(Global_Context new_gc,bool stay_inside=false); 149 CxxFile &ToOutside(); 150 151 CxxFile &Include(const std::string &name,bool local=false); 152 CxxFile &FunctionArg(); 153 CxxFile &Funct_ReturnType(); Funct_Storage()154 CxxFile &Funct_Storage() 155 { return Funct_ReturnType(); } 156 CxxFile &FunctionName(); 157 CxxFile &StartBlock(); 158 CxxFile &EndBlock(); 159 CxxFile &BlockStatement(); // if(), else, while(), for() 160 CxxFile &TypeDefinition(); // ?? 161 CxxFile &EndType(); 162 CxxFile &Private(); 163 CxxFile &Protected(); 164 CxxFile &Public(); 165 CxxFile_Context Visibility(); // !const, calls ToOutside() 166 CxxFile &Visibility(CxxFile_Context ctx); 167 CxxFile &NewLine(bool end_this_line=true); 168 CxxFile &Statement(); 169 CxxFile &Declaration(); 170 CxxFile &Definition(); 171 CxxFile &Class(); 172 CxxFile &EndLine(bool endBlock=false); 173 CxxFile &ShortComment(); VSpace()174 CxxFile &VSpace() 175 { NewLine(false); 176 empty_line=false; 177 return NewLine(false); 178 } 179 CxxFile &DefineName(); 180 CxxFile &DefineBody(); 181 CxxFile &CppIf(); 182 CxxFile &CppElse(); 183 CxxFile &CppElif(); 184 CxxFile &EndIf(); 185 CxxFile &Constructor(); 186 CxxFile &Assignment(); 187 CxxFile &Derivation(); 188 CxxFile &Namespace(); 189 Construct(const std::string & instance,const std::string & params)190 CxxFile &Construct(const std::string &instance, const std::string ¶ms) 191 { return Constructor() << instance << '(' << params << ')'; 192 } 193 EndIf(const std::string & s)194 CxxFile &EndIf(const std::string &s) 195 { EndIf() << s; 196 // empty_line=true; // what was this for? 197 return *this; 198 } CppIf(const std::string & s)199 CxxFile &CppIf(const std::string &s) 200 { return CppIf() << s; } Undef(const std::string & s)201 CxxFile &Undef(const std::string &s) 202 { NewLine().NoIndent() << "#undef " << s; 203 NewLine(false); 204 return *this; 205 } 206 CxxFile &FunctionEndArgs(); 207 208 // convenience Functions: NoIndent()209 CxxFile &NoIndent() 210 { indent_pending=false; 211 return *this; 212 } FunctionArg(const std::string & s)213 CxxFile &FunctionArg(const std::string &s) 214 { return FunctionArg()<<s; } Funct_Storage(const std::string & s)215 CxxFile &Funct_Storage(const std::string &s) 216 { return Funct_Storage()<<s; } Funct_ReturnType(const std::string & s)217 CxxFile &Funct_ReturnType(const std::string &s) 218 { return Funct_ReturnType()<<s; } FunctionName(const std::string & s)219 CxxFile &FunctionName(const std::string &s) 220 { return FunctionName()<<s; } Statement(const std::string & s)221 CxxFile &Statement(const std::string &s) 222 { return Statement()<<s; } Declaration(const std::string & s)223 CxxFile &Declaration(const std::string &s) 224 { return Declaration()<<s; } Class(const std::string & s)225 CxxFile &Class(const std::string &s) 226 { return Class()<<s; } ShortComment(const std::string & s)227 CxxFile &ShortComment(const std::string &s) 228 { return ShortComment()<<s; } DefineName(const std::string & s)229 CxxFile &DefineName(const std::string &s) 230 { return DefineName()<<s; } DefineBody(const std::string & s)231 CxxFile &DefineBody(const std::string &s) 232 { return DefineBody()<<s; } Assignment(const std::string & s)233 CxxFile &Assignment(const std::string &s) 234 { return Assignment()<<s; } Derive(const std::string & s)235 CxxFile &Derive(const std::string &s) 236 { return Derivation()<<s; } Namespace(const std::string & s)237 CxxFile &Namespace(const std::string &s) 238 { return Namespace()<<s; } 239 240 void InvalidState(const std::string &s="CxxFile.cc"); 241 void dump_context_stack() const; write_remembered(unsigned int stage=0)242 void write_remembered(unsigned int stage=0) 243 { EndLine(); SystemFile::write_remembered(stage); } 244 ElementAlreadyThere(const element_t & e)245 bool ElementAlreadyThere(const element_t &e) 246 { return elements.find(e)!=elements.end(); 247 } AddElement(const element_t & e)248 void AddElement(const element_t &e) 249 { elements.insert(e); 250 } 251 252 /* egcs 1.x issues an error and gcc-2.95 crashes */ 253 #if defined __GNUC__ && __GNUC__ >= 3 254 // adaptor operator <<(const U & t)255 template <class U> CxxFile &operator<<(const U &t) 256 { SomethingShiftingLeft(); 257 Output() << t; 258 return *this; 259 } 260 #else // older compilers do not work correctly 261 # define op_shl(U) CxxFile &operator<<(const U &t) \ 262 { SomethingShiftingLeft(); \ 263 Output() << t; \ 264 return *this; \ 265 } 266 267 op_shl(std::string) 268 op_shl(char * const) 269 op_shl(signed int) 270 op_shl(unsigned int) 271 op_shl(unsigned long) 272 op_shl(signed long) 273 op_shl(char) 274 #ifdef __CHAR_UNSIGNED__ 275 op_shl(signed char) 276 #else 277 op_shl(unsigned char) 278 #endif 279 op_shl(float) 280 #undef op_shl 281 #endif 282 }; 283 284 #endif 285