Frobby  0.9.5
display.cpp
Go to the documentation of this file.
1 /* Frobby: Software for monomial ideal computations.
2  Copyright (C) 2010 University of Aarhus
3  Contact Bjarke Hammersholt Roune for license information (www.broune.com)
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see http://www.gnu.org/licenses/.
17 */
18 #include "stdinc.h"
19 #include "display.h"
20 
21 #include <cctype>
22 
23 namespace {
25  static const size_t ConsoleWidth = 79;
26 
28  class Printer {
29  public:
30  Printer(const string& msg, const string& prepend):
31  _pos(0), _lineSize(0), _msg(msg), _prefix(prepend) {
32 
33  string wordSpacePrefix;
34 
35  while (_pos < _msg.size()) {
36  // We are always at the start of a line at this point.
37  ASSERT(_lineSize == 0);
38  readIndentation();
39  printRaw(_prefix);
40  printRaw(_indentation);
41 
42  if (_pos == _msg.size())
43  break;
44  if (_msg[_pos] == '\n') {
45  newLine();
46  ++_pos;
47  continue;
48  }
49 
50  wordSpacePrefix.clear();
51  while (_pos < _msg.size()) {
52  if (_msg[_pos] == '\n') {
53  ++_pos;
54  break;
55  }
56  if (isspace(_msg[_pos])) {
57  wordSpacePrefix += _msg[_pos];
58  ++_pos;
59  continue;
60  }
61  ASSERT(!isspace(_msg[_pos]));
62  ASSERT(_msg[_pos] != '\n');
63  ASSERT(_pos < _msg.size());
64 
65  string word;
66  while (_pos < _msg.size() &&
67  _msg[_pos] != '\n' &&
68  !isspace(_msg[_pos])) {
69  word += _msg[_pos];
70  ++_pos;
71  }
72  ASSERT(!word.empty());
73  printWord(wordSpacePrefix, word);
74  wordSpacePrefix.clear();
75  }
76 
77  newLine();
78  }
79  }
80 
81  private:
82  void newLine() {
83  printRaw('\n');
84  _lineSize = 0;
85  }
86 
87  void readIndentation() {
88  // Read whitespace at beginning of line.
89  _indentation.clear();
90  while (_pos < _msg.size() && _msg[_pos] != '\n' && isspace(_msg[_pos])) {
91  _indentation += _msg[_pos];
92  ++_pos;
93  }
94  }
95 
96  void printWord(const string& wordSpacePrefix, const string& word) {
97  ASSERT(!word.empty());
98 
99  // Note that this will print beyond the console width if word is
100  // the first thing we are printing on this line. That is because
101  // there then is no way to fit the word on one line.
102  size_t wordAndPrefixSize = word.size() + wordSpacePrefix.size();
103  if (_lineSize != 0 && _lineSize + wordAndPrefixSize > ConsoleWidth) {
104  // we skip space before word if inserting newline
105  newLine();
106  printRaw(_prefix);
107  printRaw(_indentation);
108  } else
109  printRaw(wordSpacePrefix);
110  printRaw(word);
111  }
112 
113  void printRaw(const string& word) {
114  fputs(word.c_str(), stderr);
115  _lineSize += word.size();
116  }
117 
118  void printRaw(char c) {
119  fputc(c, stderr);
120  ++_lineSize;
121  }
122 
123  size_t _pos;
124  size_t _lineSize;
125  const string& _msg;
126  const string& _prefix;
127  string _indentation;
128  };
129 }
130 
131 void display(const string& msg, const string& prepend) {
132  Printer(msg, prepend);
133 }
134 
135 void displayNote(const string& msg) {
136  display("NOTE: " + msg + "\n");
137 }
138 
139 void displayError(const string& msg) {
140  display("ERROR: " + msg + "\n");
141 }
142 
143 void displayInternalError(const string& msg) {
144  display("INTERNAL ERROR: " + msg + "\n");
145 }
146 
147 void displayException(const std::exception& exception) {
148  try {
149  display(exception.what());
150  } catch (...) {
151  fputs("\n\n*** Error while printing error! ***\n", stderr);
152  fflush(stderr);
153  fputs("*** Retrying display of error using simpler display method. ***\n",
154  stderr);
155  fflush(stderr);
156  fputs(exception.what(), stderr);
157  fflush(stderr);
158  throw;
159  }
160 }
void display(const string &msg, const string &prepend)
Display msg to standard error with automatic line breaking.
Definition: display.cpp:131
void displayError(const string &msg)
Display msg to standard error in a way that indicates that it is an error.
Definition: display.cpp:139
void displayNote(const string &msg)
Display msg to standard error in a way that indicates that this is something that the user should tak...
Definition: display.cpp:135
void displayInternalError(const string &msg)
Display msg to standard in a way that indicates that it is an internal error.
Definition: display.cpp:143
void displayException(const std::exception &exception)
Display the message of exception.
Definition: display.cpp:147
This file contains functions for printing strings to standard error.
#define ASSERT(X)
Definition: stdinc.h:86