textfile.h

Go to the documentation of this file.
00001 
00002 
00003 
00016 
00017 // Copyright (C) 1997-2010 by Pawel Pilarczyk.
00018 //
00019 // This file is part of the Homology Library.  This library is free software;
00020 // you can redistribute it and/or modify it under the terms of the GNU
00021 // General Public License as published by the Free Software Foundation;
00022 // either version 2 of the License, or (at your option) any later version.
00023 //
00024 // This library is distributed in the hope that it will be useful,
00025 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 // GNU General Public License for more details.
00028 //
00029 // You should have received a copy of the GNU General Public License along
00030 // with this software; see the file "license.txt".  If not, write to the
00031 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00032 // MA 02111-1307, USA.
00033 
00034 // Started in July 1997. Last revision: March 5, 2008.
00035 
00036 
00037 #ifndef _CHOMP_SYSTEM_TEXTFILE_H_
00038 #define _CHOMP_SYSTEM_TEXTFILE_H_
00039 
00040 #include "chomp/system/config.h"
00041 
00042 #include <ctime>
00043 #include <iostream>
00044 #include <fstream>
00045 #include <sstream>
00046 #include <iomanip>
00047 
00048 namespace chomp {
00049 namespace homology {
00050 
00051 
00052 // classes defined within this header file:
00053 class textfile;
00054 class outputstream;
00055 
00056 
00057 // --------------------------------------------------
00058 // ----------------- OUTPUT STREAM ------------------
00059 // --------------------------------------------------
00060 
00064 class outputstream
00065 {
00066 public:
00068         outputstream (std::ostream &_out = std::cout,
00069                 bool _show = true, bool _flush = false);
00070 
00072         ~outputstream ();
00073 
00076         void logfile (const char *filename);
00077 
00079         void logfile (const outputstream &other);
00080 
00085         bool show;
00086 
00089         bool log;
00090 
00095         bool flush;
00096 
00099         std::ofstream *getlogstream (void);
00100 
00102         std::ostream &out;
00103 
00107         void keepforever (void);
00108 
00113         struct mute
00114         {
00115                 mute (outputstream &_stream): stream (_stream),
00116                         show (_stream. show), log (_stream. log)
00117                         {stream. show = false; stream. log = false; return;}
00118                 ~mute () {stream. show = show;
00119                         stream. log = log; return;}
00120                 outputstream &stream;
00121                 bool show;
00122                 bool log;
00123         };
00124 
00125 protected:
00127         std::ofstream *logstream;
00128 
00132         bool copied;
00133 
00134 }; /* class outputstream */
00135 
00136 // --------------------------------------------------
00137 
00138 inline outputstream::outputstream (std::ostream &_out, bool _show,
00139         bool _flush): out (_out)
00140 {
00141         show = _show;
00142         flush = _flush;
00143         log = false;
00144         logstream = NULL;
00145         copied = false;
00146         return;
00147 } /* outputstream::outputstream */
00148 
00149 inline void outputstream::logfile (const char *filename)
00150 {
00151         if (logstream && !copied)
00152                 delete logstream;
00153         copied = false;
00154         logstream = new std::ofstream (filename);
00155         if (!logstream || !*logstream)
00156         {
00157                 out << "WARNING: Can't create '" << filename <<
00158                         "'. Logging to a file has been turned off." <<
00159                         std::endl;
00160                 if (logstream)
00161                         delete logstream;
00162                 logstream = NULL;
00163         }
00164         else
00165                 log = true;
00166         return;
00167 } /* outputstream::logfile */
00168 
00169 inline void outputstream::logfile (const outputstream &other)
00170 {
00171         if (!copied && logstream)
00172                 delete logstream;
00173         logstream = other. logstream;
00174         if (logstream)
00175         {
00176                 copied = true;
00177                 log = true;
00178         }
00179         return;
00180 } /* outputstream::logfile */
00181 
00182 inline outputstream::~outputstream ()
00183 {
00184         if (!copied && logstream)
00185                 delete logstream;
00186         return;
00187 } /* outputstream::~outputstream */
00188 
00189 inline std::ofstream *outputstream::getlogstream (void)
00190 {
00191         return logstream;
00192 } /* outputstream::getlogstream */
00193 
00194 inline void outputstream::keepforever (void)
00195 {
00196         copied = true;
00197         return;
00198 } /* outputstream::getlogstream */
00199 
00202 template<typename type>
00203 inline outputstream &operator << (outputstream &out, const type &object)
00204 {
00205         if (out. flush)
00206         {
00207                 if (out. show)
00208                         out. out << object << std::flush;
00209                 if (out. log && out. getlogstream ())
00210                         (*(out. getlogstream ())) << object << std::flush;
00211         }
00212         else
00213         {
00214                 if (out. show)
00215                         out. out << object;
00216                 if (out. log && out. getlogstream ())
00217                         (*(out. getlogstream ())) << object;
00218         }
00219         return out;
00220 } /* operator << */
00221 
00224 inline outputstream &operator << (outputstream &out, const char *object)
00225 {
00226         if (out. flush)
00227         {
00228                 if (out. show)
00229                         out. out << object << std::flush;
00230                 if (out. log && out. getlogstream ())
00231                         (*(out. getlogstream ())) << object << std::flush;
00232         }
00233         else
00234         {
00235                 if (out. show)
00236                         out. out << object;
00237                 if (out. log && out. getlogstream ())
00238                         (*(out. getlogstream ())) << object;
00239         }
00240         return out;
00241 } /* operator << */
00242 
00245 inline outputstream &operator << (outputstream &out,
00246         std::ostream& (*object)(std::ostream&))
00247 {
00248         if (out. flush)
00249         {
00250                 if (out. show)
00251                         out. out << object << std::flush;
00252                 if (out. log && out. getlogstream ())
00253                         (*(out. getlogstream ())) << object << std::flush;
00254         }
00255         else
00256         {
00257                 if (out. show)
00258                         out. out << object;
00259                 if (out. log && out. getlogstream ())
00260                         (*(out. getlogstream ())) << object;
00261         }
00262         return out;
00263 } /* operator << */
00264 
00265 // --------------------------------------------------
00266 
00267 #ifndef OUTPUTSTREAM
00268 
00269 
00270 #define OUTPUTSTREAM
00271 #endif
00272 
00275 extern outputstream sout;
00276 
00279 extern outputstream scon;
00280 
00282 extern outputstream serr;
00283 
00287 extern outputstream slog;
00288 
00291 extern outputstream sbug;
00292 
00295 extern outputstream sseq;
00296 
00297 
00298 // --------------------------------------------------
00299 // ----------------- various tools ------------------
00300 // --------------------------------------------------
00301 
00304 template <class type>
00305 inline void swapelements (type &x, type &y)
00306 {
00307         type z = x;
00308         x = y;
00309         y = z;
00310         return;
00311 } /* swapelements */
00312 
00315 template <class type>
00316 inline int sortelements (type *tab, int n)
00317 {
00318         switch (n)
00319         {
00320         case 0:
00321                 return 0;
00322         case 1:
00323                 return 1;
00324         case 2:
00325                 if (tab [0] == tab [1])
00326                         return 1;
00327                 else if (tab [0] > tab [1])
00328                         swapelements (tab [0], tab [1]);
00329                 return 2;
00330         default:
00331                 for (int i = 0; i < n - 1; ++ i)
00332                 {
00333                         for (int j = i + 1; j < n; ++ j)
00334                                 if (tab [i] > tab [j])
00335                                         swapelements (tab [i],
00336                                                 tab [j]);
00337 
00338                         if (tab [i] == tab [i + 1])
00339                         {
00340                                 -- n;
00341                                 for (int j = i + 1; j < n; ++ j)
00342                                         tab [j] = tab [j + 1];
00343                         }
00344                 }
00345                 break;
00346         }
00347         return n;
00348 } /* sortelements */
00349 
00352 inline void ignoreline (std::istream &in)
00353 {
00354         in. ignore (0x7FFFFFFFl, '\n');
00355         return;
00356 } /* ignoreline */
00357 
00361 inline void ignorecomments (std::istream &in)
00362 {
00363         int ch = in. peek ();
00364         while (true)
00365         {
00366                 switch (ch)
00367                 {
00368                 case ';':
00369                         ignoreline (in);
00370                         ch = in. peek ();
00371                         break;
00372                 case ' ':
00373                 case '\t':
00374                 case '\r':
00375                 case '\n':
00376                         in. get ();
00377                         ch = in. peek ();
00378                         break;
00379                 default:
00380                         return;
00381                 }
00382         }       
00383 } /* ignorecomments */
00384 
00387 inline int closingparenthesis (int ch)
00388 {
00389         switch (ch)
00390         {
00391                 case '(':
00392                         return ')';
00393                 case '{':
00394                         return '}';
00395                 case '[':
00396                         return ']';
00397                 case '<':
00398                         return '>';
00399                 case '/':
00400                         return '/';
00401                 default:
00402                         return EOF;
00403         }
00404 } /* closingparenthesis */
00405 
00408 inline int readparenthesis (std::istream &in)
00409 {
00410         int closing = closingparenthesis (in. peek ());
00411         if (closing != EOF)
00412                 in. get ();
00413         return closing;
00414 } /* readparenthesis */
00415 
00417 inline std::string commandline (int argc, char *argv [])
00418 {
00419         std::string s;
00420         for (int i = 0; i < argc; ++ i)
00421         {
00422                 if (i)
00423                         s += ' ';
00424                 s += argv [i];
00425         }
00426         return s;
00427 } /* commandline */
00428 
00430 inline const char *currenttime (void)
00431 {
00432         std::time_t t;
00433         std::time (&t);
00434         return std::asctime (std::localtime (&t));
00435 } /* currenttime */
00436 
00443 template <class settype>
00444 static void savetheset (const settype &c, const char *prefix,
00445         const char *filename, const char *name)
00446 {
00447         // if there is no prefix given, do not save the file
00448         if (!prefix)
00449                 return;
00450 
00451         // prepare the full file name
00452         std::string str;
00453         if (prefix)
00454                 str = std::string (prefix) + std::string (filename);
00455         else
00456                 str = filename;
00457         const char *s = str. c_str ();
00458 
00459         // create the output file
00460         std::ofstream out (s);
00461         if (!out)
00462         {
00463                 sout << "WARNING: Cannot save the file '" << s << "'.\n";
00464                 return;
00465         }
00466 
00467         // write the cubes to the output file
00468         sout << "Saving " << name << " to '" << s << "'... ";
00469         out << "; This is " << name << ".\n";
00470         out << c;
00471         sout << "Done.\n";
00472 
00473         return;
00474 } /* savetheset */
00475 
00476 
00477 // --------------------------------------------------
00478 // ----------------- ERROR MESSAGE ------------------
00479 // --------------------------------------------------
00480 
00497 #define ERRORMSG {std::ostringstream error_msg_string; error_msg_string
00498 
00501 #define THROW ""; throw error_msg_string. str (). c_str (); }
00502 
00503 // --------------------------------------------------
00504 
00508 inline void fileerror (const char *filename, const char *what = "open")
00509 {
00510         ERRORMSG << "Cannot " << what << " the file '" <<
00511                 filename << "'." << THROW
00512         return;
00513 } /* fileerror */
00514 
00515 
00516 // --------------------------------------------------
00517 // -------------------- TEXTFILE --------------------
00518 // --------------------------------------------------
00519 
00522 #define MAXTEXTLENGTH 200
00523 
00528 class textfile
00529 {
00530 public:
00532         textfile ();
00533 
00535         textfile (std::istream &in);
00536 
00537         // a constructor which opens a file
00538 //      textfile (char *filename);
00539 
00544         int open (const char *filename);
00545 
00547         void close ();
00548 
00550         ~textfile ();
00551 
00555         long readnumber (long defaultnumber = 0, int ignorecolons = 0);
00556 
00559         int checkchar ();
00560 
00563         int readchar ();
00564 
00566         int readword (char *buf, int maxlength);
00567 
00572         int readphrase (const char *phrase);
00573 
00576         void ignoreline ();
00577 
00579         long linenumber ();
00580 
00583         operator int ();
00584 
00585 private:
00587         int ch;
00588 
00590         long line;
00591 
00593         std::ifstream *fs;
00594 
00596         std::istream *s;
00597 
00600         void ignorespaces ();
00601 
00602 }; /* class textfile */
00603 
00604 
00605 } // namespace homology
00606 } // namespace chomp
00607 
00608 #endif // _CHOMP_SYSTEM_TEXTFILE_H_
00609 
00611