// $Id: SystemFile.hh,v 1.17 2004/05/07 06:53:14 christof Exp $ /* glade--: C++ frontend for glade (Gtk+ User Interface Builder) * 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. */ #ifndef SYSTEMFILE_HH #define SYSTEMFILE_HH #include #include #include "mystream.h" #include #include /** this is an abstraction of a system file, it knows its own file name and can remember lines for later output */ class SystemFile { /** See Cxx.cc for an explanation of remembered lines 2do: multiple stages (priority fifo?) */ std::string filename; // nice to have at hand std::vector > remembered_lines; bool is_stringstream:1; bool deallocate:1; union { std::ofstream *of; mystream *os; } streamptr; SystemFile *remembered; int mystage; private: void free(); protected: SystemFile(SystemFile *f,unsigned int stage=0) : filename(f->filename), is_stringstream(true), deallocate(true), remembered(f), mystage(stage) { streamptr.os=new mystream(); } public: SystemFile(std::ofstream &str,const std::string &name="") : filename(name), is_stringstream(false), deallocate(false), remembered(0), mystage(0) { streamptr.of=&str; } #if 0 // geht nicht mit libstdc++ 3.0 SystemFile(int fd,const std::string &name="") : filename(name), is_stringstream(false), deallocate(true), remembered(0), mystage(0) { streamptr.of=new std::ofstream(fd); } #endif SystemFile() : is_stringstream(false), deallocate(true), remembered(0), mystage(0) { streamptr.of=0; } SystemFile(const std::string &name,std::ios::openmode mode=std::ios::out, int prot=0664); ~SystemFile(); void close(); void open(const std::string &name,std::ios::openmode mode=std::ios::out, int prot=0664); void prepare_stage(unsigned int stage) throw(); void remember(const std::string &s) throw() { remember(0,s); } void remember(unsigned int stage,const std::string &s) throw(); std::vector &get_remembered(unsigned int stage=0) throw() { prepare_stage(stage); return remembered_lines[stage]; } void write_remembered(unsigned int stage=0); const std::string &FileName() const { return filename; } // debugging output // friend std::ostream &operator<<(std::ostream &,const SystemFile &f); // common routines void Indent(int level); operator std::ostream &() { return is_stringstream ? static_cast(*streamptr.os) : static_cast(*streamptr.of); } operator const std::ostream &() const { return is_stringstream ? static_cast(*streamptr.os) : static_cast(*streamptr.of); } std::ostream &OStream() { return static_cast(*this); } // inherited std::ostream routines /* egcs 1.x issues an error and gcc-2.95 crashes */ // __GNUC_MINOR__ > 95 ? #if defined __GNUC__ && __GNUC__ >= 3 template SystemFile &operator<<(const U &t) { static_cast(*this) << t; return *this; } #else # define op_shl(U) SystemFile &operator<<(const U &t) \ { static_cast(*this) << 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) // op_shl(size_t) #undef op_shl #endif #if 0 // perhaps it's easier to use OStream().fill instead _IO_wchar_t fill() const { return static_cast(*this).fill(); } _IO_wchar_t fill(_IO_wchar_t newf) { return static_cast(*this).fill(newf); } int width() const { return static_cast(*this).width(); } int width(int val) { return static_cast(*this).width(val); } #endif int good() const { return &static_cast(*this)!=0 && static_cast(*this).good(); } }; //extern std::ostream &operator<<(std::ostream &,const SystemFile &f); /* I would like the syntax cxxfile.Remember() << "xyz"; but this is impossible (since Remember() can't return a CxxFile (can't copy std::ios)) so I chose Remember(cxxfile) << "xyz"; as a replacement */ // Remember<>(cxxfile) is not possible (sad?) template class Remember : public Base {public: Remember(Base &b,unsigned int stage=0) : Base(&b,stage) {} }; #endif