The Original CHomP Software
textfile.h
Go to the documentation of this file.
1
3
16
17// Copyright (C) 1997-2020 by Pawel Pilarczyk.
18//
19// This file is part of my research software package. This is free software:
20// you can redistribute it and/or modify it under the terms of the GNU
21// General Public License as published by the Free Software Foundation,
22// either version 3 of the License, or (at your option) any later version.
23//
24// This software is distributed in the hope that it will be useful,
25// but WITHOUT ANY WARRANTY; without even the implied warranty of
26// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27// GNU General Public License for more details.
28//
29// You should have received a copy of the GNU General Public License
30// along with this software; see the file "license.txt". If not,
31// please, see <https://www.gnu.org/licenses/>.
32
33// Started in July 1997. Last revision: February 25, 2013.
34
35
36#ifndef _CHOMP_SYSTEM_TEXTFILE_H_
37#define _CHOMP_SYSTEM_TEXTFILE_H_
38
39#include "chomp/system/config.h"
40
41#include <ctime>
42#include <iostream>
43#include <fstream>
44#include <sstream>
45#include <iomanip>
46
47namespace chomp {
48namespace homology {
49
50
51// classes defined within this header file:
52class textfile;
53class outputstream;
54
55
56// --------------------------------------------------
57// ----------------- OUTPUT STREAM ------------------
58// --------------------------------------------------
59
64{
65public:
67 outputstream (std::ostream &_out = std::cout,
68 bool _show = true, bool _flush = false);
69
72
75 void logfile (const char *filename);
76
78 void logfile (const outputstream &other);
79
84 bool show;
85
88 bool log;
89
94 bool flush;
95
98 std::ofstream *getlogstream (void);
99
101 std::ostream &out;
102
106 void keepforever (void);
107
109 int precision () const;
110
115 struct mute
116 {
117 mute (outputstream &_stream): stream (_stream),
118 show (_stream. show), log (_stream. log)
119 {stream. show = false; stream. log = false; return;}
121 stream. log = log; return;}
123 bool show;
124 bool log;
125 };
126
127protected:
129 std::ofstream *logstream;
130
134 bool copied;
135
136}; /* class outputstream */
137
138// --------------------------------------------------
139
140inline outputstream::outputstream (std::ostream &_out, bool _show,
141 bool _flush): out (_out)
142{
143 show = _show;
144 flush = _flush;
145 log = false;
146 logstream = NULL;
147 copied = false;
148 return;
149} /* outputstream::outputstream */
150
151inline void outputstream::logfile (const char *filename)
152{
153 // delete the previous log stream
154 if (logstream && !copied)
155 delete logstream;
156
157 // make a note that this output stream is the master copy
158 copied = false;
159
160 // create a file stream to log the output to;
161 // note: if "keepforever" is applied to the output stream
162 // then this data structure is not released and produces
163 // a small memory leak; however, the file is automatically
164 // closed by the system; this may be necessary to avoid
165 // a crash of the program if any other output streams
166 // still want to write to a copy of this stream
167 // upon program's shutdown
168 logstream = new std::ofstream (filename);
169
170 // warn if the log file could not be created
171 if (!logstream || !*logstream)
172 {
173 out << "WARNING: Can't create '" << filename <<
174 "'. Logging to a file has been turned off." <<
175 std::endl;
176 if (logstream)
177 delete logstream;
178 logstream = NULL;
179 }
180
181 // otherwise set a flag indicating that logging to a file is on
182 else
183 log = true;
184
185 return;
186} /* outputstream::logfile */
187
188inline void outputstream::logfile (const outputstream &other)
189{
190 if (!copied && logstream)
191 delete logstream;
192 logstream = other. logstream;
193 if (logstream)
194 {
195 copied = true;
196 log = true;
197 }
198 return;
199} /* outputstream::logfile */
200
202{
203 if (!copied && logstream)
204 delete logstream;
205 return;
206} /* outputstream::~outputstream */
207
208inline std::ofstream *outputstream::getlogstream (void)
209{
210 return logstream;
211} /* outputstream::getlogstream */
212
214{
215 copied = true;
216 return;
217} /* outputstream::getlogstream */
218
219inline int outputstream::precision () const
220{
221 return out. precision ();
222} /* outputstream::precision */
223
226template<typename type>
227inline outputstream &operator << (outputstream &out, const type &object)
228{
229 if (out. flush)
230 {
231 if (out. show)
232 out. out << object << std::flush;
233 if (out. log && out. getlogstream ())
234 (*(out. getlogstream ())) << object << std::flush;
235 }
236 else
237 {
238 if (out. show)
239 out. out << object;
240 if (out. log && out. getlogstream ())
241 (*(out. getlogstream ())) << object;
242 }
243 return out;
244} /* operator << */
245
248inline outputstream &operator << (outputstream &out, const char *object)
249{
250 if (out. flush)
251 {
252 if (out. show)
253 out. out << object << std::flush;
254 if (out. log && out. getlogstream ())
255 (*(out. getlogstream ())) << object << std::flush;
256 }
257 else
258 {
259 if (out. show)
260 out. out << object;
261 if (out. log && out. getlogstream ())
262 (*(out. getlogstream ())) << object;
263 }
264 return out;
265} /* operator << */
266
270 std::ostream& (*object)(std::ostream&))
271{
272 if (out. flush)
273 {
274 if (out. show)
275 out. out << object << std::flush;
276 if (out. log && out. getlogstream ())
277 (*(out. getlogstream ())) << object << std::flush;
278 }
279 else
280 {
281 if (out. show)
282 out. out << object;
283 if (out. log && out. getlogstream ())
284 (*(out. getlogstream ())) << object;
285 }
286 return out;
287} /* operator << */
288
289// --------------------------------------------------
290
291#ifndef OUTPUTSTREAM
294#define OUTPUTSTREAM
295#endif
296
299extern outputstream sout;
300
303extern outputstream scon;
304
306extern outputstream serr;
307
311extern outputstream slog;
312
315extern outputstream sbug;
316
319extern outputstream sseq;
320
321
322// --------------------------------------------------
323// ----------------- various tools ------------------
324// --------------------------------------------------
325
328template <class type>
329inline void swapelements (type &x, type &y)
330{
331 type z (x);
332 x = y;
333 y = z;
334 return;
335} /* swapelements */
336
339template <class type>
340inline int sortelements (type *tab, int n)
341{
342 switch (n)
343 {
344 case 0:
345 return 0;
346 case 1:
347 return 1;
348 case 2:
349 if (tab [0] == tab [1])
350 return 1;
351 else if (tab [0] > tab [1])
352 swapelements (tab [0], tab [1]);
353 return 2;
354 default:
355 for (int i = 0; i < n - 1; ++ i)
356 {
357 for (int j = i + 1; j < n; ++ j)
358 if (tab [i] > tab [j])
359 swapelements (tab [i],
360 tab [j]);
361
362 if (tab [i] == tab [i + 1])
363 {
364 -- n;
365 for (int j = i + 1; j < n; ++ j)
366 tab [j] = tab [j + 1];
367 }
368 }
369 break;
370 }
371 return n;
372} /* sortelements */
373
376inline void ignoreline (std::istream &in)
377{
378 in. ignore (0x7FFFFFFFl, '\n');
379 return;
380} /* ignoreline */
381
385inline void ignorecomments (std::istream &in)
386{
387 int ch = in. peek ();
388 while (true)
389 {
390 switch (ch)
391 {
392 case ';':
393 ignoreline (in);
394 ch = in. peek ();
395 break;
396 case ' ':
397 case '\t':
398 case '\r':
399 case '\n':
400 in. get ();
401 ch = in. peek ();
402 break;
403 default:
404 return;
405 }
406 }
407} /* ignorecomments */
408
411inline int closingparenthesis (int ch)
412{
413 switch (ch)
414 {
415 case '(':
416 return ')';
417 case '{':
418 return '}';
419 case '[':
420 return ']';
421 case '<':
422 return '>';
423 case '/':
424 return '/';
425 default:
426 return EOF;
427 }
428} /* closingparenthesis */
429
432inline int readparenthesis (std::istream &in)
433{
434 int closing = closingparenthesis (in. peek ());
435 if (closing != EOF)
436 in. get ();
437 return closing;
438} /* readparenthesis */
439
441inline std::string commandline (int argc, char *argv [])
442{
443 std::string s;
444 for (int i = 0; i < argc; ++ i)
445 {
446 if (i)
447 s += ' ';
448 s += argv [i];
449 }
450 return s;
451} /* commandline */
452
454inline const char *currenttime (void)
455{
456 std::time_t t;
457 std::time (&t);
458 return std::asctime (std::localtime (&t));
459} /* currenttime */
460
467template <class settype>
468static void savetheset (const settype &c, const char *prefix,
469 const char *filename, const char *name)
470{
471 // if there is no prefix given, do not save the file
472 if (!prefix)
473 return;
474
475 // prepare the full file name
476 std::string str;
477 if (prefix)
478 str = std::string (prefix) + std::string (filename);
479 else
480 str = filename;
481 const char *s = str. c_str ();
482
483 // create the output file
484 std::ofstream out (s);
485 if (!out)
486 {
487 sout << "WARNING: Cannot save the file '" << s << "'.\n";
488 return;
489 }
490
491 // write the cubes to the output file
492 sout << "Saving " << name << " to '" << s << "'... ";
493 out << "; This is " << name << ".\n";
494 out << c;
495 sout << "Done.\n";
496
497 return;
498} /* savetheset */
499
500
501// --------------------------------------------------
502// ----------------- ERROR MESSAGE ------------------
503// --------------------------------------------------
504
521#define ERRORMSG {std::ostringstream error_msg_string; error_msg_string
522
525#define THROW ""; throw error_msg_string. str (). c_str (); }
526
527// --------------------------------------------------
528
532inline void fileerror (const char *filename, const char *what = "open")
533{
534 ERRORMSG << "Cannot " << what << " the file '" <<
535 filename << "'." << THROW
536 return;
537} /* fileerror */
538
539
540// --------------------------------------------------
541// -------------------- TEXTFILE --------------------
542// --------------------------------------------------
543
546#define MAXTEXTLENGTH 200
547
553{
554public:
557
559 textfile (std::istream &in);
560
561 // a constructor which opens a file
562// textfile (char *filename);
563
568 int open (const char *filename);
569
571 void close ();
572
575
579 long readnumber (long defaultnumber = 0, int ignorecolons = 0);
580
583 int checkchar ();
584
587 int readchar ();
588
590 int readword (char *buf, int maxlength);
591
596 int readphrase (const char *phrase);
597
600 void ignoreline ();
601
603 long linenumber ();
604
607 operator int ();
608
609private:
611 int ch;
612
614 long line;
615
617 std::ifstream *fs;
618
620 std::istream *s;
621
625
626}; /* class textfile */
627
628
629} // namespace homology
630} // namespace chomp
631
632#endif // _CHOMP_SYSTEM_TEXTFILE_H_
633
635
This class defines an output stream for replacing the standard 'cout'.
Definition: textfile.h:64
int precision() const
Returns the precision of the main output stream.
Definition: textfile.h:219
bool copied
This variable is set to true if this log file pointer was copied from another output stream,...
Definition: textfile.h:134
void keepforever(void)
Makes this stream keep the allocated file open for ever, and not close it even in the destructor.
Definition: textfile.h:213
bool flush
If this variable is set to true then both the output stream 'cout' and the log file are flushed after...
Definition: textfile.h:94
bool show
If this variable is set to true then everything that is written to this stream is also written to 'co...
Definition: textfile.h:84
std::ostream & out
A reference to the main output stream bound with this stream.
Definition: textfile.h:101
std::ofstream * getlogstream(void)
Returns a pointer to the stream which is working as a log file.
Definition: textfile.h:208
~outputstream()
The destructor.
Definition: textfile.h:201
std::ofstream * logstream
A pointer to the log file stream.
Definition: textfile.h:129
bool log
If this variable is set to true then everything that is written to this stream is also written to the...
Definition: textfile.h:88
outputstream(std::ostream &_out=std::cout, bool _show=true, bool _flush=false)
The default constructor.
Definition: textfile.h:140
void logfile(const char *filename)
Turns on logging to a file.
Definition: textfile.h:151
A class for reading text data from a text file.
Definition: textfile.h:553
void ignorespaces()
Ignores white characters and fills in the variable 'ch' with the first non-white character.
long linenumber()
Returns the current line number.
std::ifstream * fs
The true file if it was opened.
Definition: textfile.h:617
int readphrase(const char *phrase)
Reads a strongly expected phrase from the file.
std::istream * s
A pointer to an input stream (usually equal to 'fs').
Definition: textfile.h:620
long line
The current line number.
Definition: textfile.h:614
int open(const char *filename)
Opens a file with the given name.
void ignoreline()
Ignore the current line from the current position to the end of line, including the end of line chara...
int readword(char *buf, int maxlength)
Reads one word from the file and returns its actual length.
int ch
The character already read and waiting to be interpreted.
Definition: textfile.h:611
long readnumber(long defaultnumber=0, int ignorecolons=0)
Read an integer number from the input file.
void close()
Closes the file.
~textfile()
The destructor.
int checkchar()
Returns the first non-white character waiting to be read.
int readchar()
Read one non-white character from the file.
textfile(std::istream &in)
A constructor for an opened file.
textfile()
The default constructor.
This file contains some precompiler definitions which indicate the operating system and/or compiler u...
outputstream sseq
An auxiliary stream which captures sequences of processed data.
void ignoreline(std::istream &in)
Ignores the input characters until the end of a line, including this end of the line.
Definition: textfile.h:376
outputstream sout
A replacement for standard output stream, with optional logging and other features provided by the cl...
void swapelements(type &x, type &y)
A simple template for swapping two elements with the use of a temporary variable of the same type and...
Definition: textfile.h:329
int closingparenthesis(int ch)
Returns the matching closing parenthesis for the given opening one or EOF if none.
Definition: textfile.h:411
outputstream serr
A wrapper for the standard error stream.
std::string commandline(int argc, char *argv[])
Returns the entire command line as a single string.
Definition: textfile.h:441
void fileerror(const char *filename, const char *what="open")
Throws a message about the inability to do something with a file.
Definition: textfile.h:532
std::ostream & operator<<(std::ostream &out, const bincube< Dim, twoPower > &b)
Definition: bincube.h:907
outputstream sbug
An output stream for writing additional debug messages.
int readparenthesis(std::istream &in)
Reads an opening parenthesis from the input file.
Definition: textfile.h:432
void savetheset(const char *name, const settype &s, const char *pluralname, const char *what, const char *filecomment=0)
Saves a given set to a file and shows appropriate messages.
Definition: homtools.h:283
outputstream scon
The console output stream to which one should put all the junk that spoils the log file,...
const char * currenttime(void)
Retrieves the current time as a pointer to a C-style string.
Definition: textfile.h:454
void ignorecomments(std::istream &in)
Ignores white characters (spaces, tabulators, CRs and LFs), as well as comments from the input text f...
Definition: textfile.h:385
int sortelements(type *tab, int n)
A simple template that sorts an array using the bubble sort method, removes repeated elements and ret...
Definition: textfile.h:340
outputstream slog
The output stream to which one can send messages for logging only.
This namespace contains the entire CHomP library interface.
Definition: bitmaps.h:51
Local mute of the stream.
Definition: textfile.h:116
mute(outputstream &_stream)
Definition: textfile.h:117
#define ERRORMSG
The first macro in a pair of macrodefinitions for throwing an error message.
Definition: textfile.h:521
#define THROW
The second macro in a pair of macrodefinitions for throwing an error message.
Definition: textfile.h:525