coan  6.0.1
A C/C++ Configuration Analyzer
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
diagnostic.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2007-2013 Mike Kinghan, imk@burroingroingjoing.com *
3  * All rights reserved. *
4  * *
5  * Contributed originally by Mike Kinghan, imk@burroingroingjoing.com *
6  * *
7  * Redistribution and use in source and binary forms, with or without *
8  * modification, are permitted provided that the following conditions *
9  * are met: *
10  * *
11  * Redistributions of source code must retain the above copyright *
12  * notice, this list of conditions and the following disclaimer. *
13  * *
14  * Redistributions in binary form must reproduce the above copyright *
15  * notice, this list of conditions and the following disclaimer in the *
16  * documentation and/or other materials provided with the distribution. *
17  * *
18  * Neither the name of Mike Kinghan nor the names of its contributors *
19  * may be used to endorse or promote products derived from this software *
20  * without specific prior written permission. *
21  * *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *
29  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED *
30  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,*
31  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF *
32  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
33  * DAMAGE. *
34  * *
35  **************************************************************************/
36 
37 #include "diagnostic.h"
38 #include "dataset.h"
39 #include "if_control.h"
40 #include "line_despatch.h"
41 #include "options.h"
42 #include "io.h"
43 #include <iostream>
44 #include <iomanip>
45 
50 using namespace std;
51 
52 unsigned diagnostic_base::_infos_(0);
53 unsigned diagnostic_base::_warnings_(0);
54 unsigned diagnostic_base::_errors_(0);
55 unsigned diagnostic_base::_abends_(0);
58 
59 list<diagnostic_base::ptr> diagnostic_base::_queue_;
60 
61 diagnostic_base::diagnostic_base(std::string const & severity_name,
62  severity level, unsigned id,
63  bool in_code_only)
64  : _gagged(false)
65 {
66  unsigned reason = code(level,id);
67 
68  if (options::diagnostic_gagged(reason)) {
69  /* This message is filtered out. Don't output*/
70  _gagged = true;
71  return;
72  }
73  _text << options::prog_name() << ": ";
74  if (!options::got_opts()) {
75  _text << "while parsing options: ";
76  }
77  if (!io::in_file_name().empty()) {
78  _text << io::in_file_name() << ": ";
79  }
80  if (line_despatch::cur_line().num()) {
81  _text << "line " << line_despatch::cur_line().num() << ": ";
82  }
83  _text << severity_name << ' ' << "0x" << setfill('0')
84  << hex << setw(5) << reason << ": " << dec;
85 }
86 
87 void diagnostic_base::despatch() const throw(unsigned)
88 {
89  count();
90  if (!text().empty()) {
91  cerr << text() << '\n';
92  }
93  if (level() == severity::abend) {
94  exit(exitcode());
95  }
96  if (level() == severity::error) {
97  throw(unsigned(*this));
98  }
99 }
100 
102 {
103  size_t infiles = dataset::files();
104  char const * diagnostic_status = "";
105  int ret = exitcode();
106  if_control::top();
107  io::top();
108 
109  if (_abends_) {
110  diagnostic_status = " ABNORMALLY";
111  } else if (_errors_) {
112  diagnostic_status = " with errors";
113  } else if (_warnings_) {
114  diagnostic_status = " with warnings";
115  } else if (_infos_) {
116  diagnostic_status = " with remarks";
117  }
118 
119  progress_summary_all_done() << "Completed"
120  << diagnostic_status << ", exit code 0x" << setfill('0') << setw(2) <<
121  hex << ret << dec << emit();
122  if (infiles) {
124  dataset::done_files() << " out of " << infiles <<
125  " input files were reached; "
126  << (infiles - dataset::done_files()) << " files were not reached"
127  << emit();
130  << " out of " << dataset::done_files() <<
131  " files reached were valid; " << dataset::error_files() <<
132  " were abandoned due to parse errors" << emit();
133  if (infiles == dataset::done_files() && dataset::error_files() == 0) {
136  "Input lines were dropped" << emit();
137  }
140  "Input lines were changed" << emit();
141  }
144  "Input lines were changed to #error directives"
145  << emit();
146  }
149  "Unconditional #error directives are operative"
150  << emit();
151  }
152  }
153  }
154 }
155 
157 {
158  unsigned severities = 0;
159  unsigned summaries = 0;
161  summaries |= 16;
162  ++_infos_;
163  }
165  summaries |= 32;
166  ++_infos_;
167  }
169  summaries |= 64;
170  ++_warnings_;
171  }
173  summaries |= 128;
174  ++_warnings_;
175  }
176  if (_infos_) {
177  severities |= 1;
178  }
179  if (_warnings_) {
180  severities |= 2;
181  }
182  if (_errors_) {
183  severities |= 4;
184  }
185  if (_abends_) {
186  severities |= 8;
187  }
188  return severities < 4 ? severities | summaries : severities;
189 }
190 
192 {
193  for( ; !_queue_.empty(); _queue_.pop_front()) {
194  _queue_.begin()->get()->despatch();
195  }
196 }
197 
198 // EOF
static parsed_line & cur_line()
Get a reference to the current output line.
Definition: line_despatch.h:68
A fatal error disgnostic.
static unsigned _abends_
Global count of fatal error diagnostics.
Definition: diagnostic.h:332
static unsigned code(severity level, unsigned id)
Get the reason-code that encodes a causal identifier and severity.
Definition: diagnostic.h:314
diagnostic_base(std::string const &severity_name, severity level, unsigned id, bool in_code_only=false)
Constructor.
Definition: diagnostic.cpp:61
progress_summary_msg< 1 > progress_summary_all_done
Report processing complete.
Definition: diagnostic.h:822
info_summary_msg< 4 > info_summary_summary_changed_lines
Report that input lines were changed.
Definition: diagnostic.h:830
info_summary_msg< 2 > info_summary_files_dropped
Report total files abandoned due to errors.
Definition: diagnostic.h:826
static void flush_all()
Emit any queued diagnostics.
Definition: diagnostic.cpp:191
static unsigned error_files()
Get the number of files abandoned due to errors in traversal of the dataset.
Definition: dataset.h:147
static unsigned & lines_changed()
Get a reference to the count of changed lines.
static void top()
Reinitialize the module.
Definition: io.cpp:65
static int exitcode()
Convert the internal exit status to an exit code for exit().
Definition: diagnostic.cpp:156
static std::list< ptr > _queue_
Queue of deferred diagnostics.
Definition: diagnostic.h:323
static std::string in_file_name()
Get the name of the current source file.
Definition: io.h:105
unsigned num() const
Get the greatest source line number spanned by this line.
Definition: parsed_line.h:70
static bool got_opts()
Have we got all the options?
Definition: options.h:105
warning_summary_msg< 1 > warning_summary_summary_errored_lines
Report that input lines were converted to #errors
Definition: diagnostic.h:832
static unsigned _errors_
Global count of error diagnostics.
Definition: diagnostic.h:330
severity
Enumerated constants representing the severities of diagnostics.
Definition: diagnostic.h:51
static unsigned & lines_suppressed()
Get a reference to the count of suppressed lines.
virtual void count() const
Increment global counts appropriately for the runtime type.
Definition: diagnostic.h:290
bool _gagged
Is the diagnostic suppressed?
Definition: diagnostic.h:301
static void epilogue()
Write summary diagnostics on cerr at exit.
Definition: diagnostic.cpp:101
warning_summary_msg< 2 > warning_summary_summary_error_output
Report that unconditional #error lines were output.
Definition: diagnostic.h:834
info_summary_msg< 3 > info_summary_summary_dropped_lines
Report that input lines were dropped.
Definition: diagnostic.h:828
The tag class is inserted in a diagnostic_base to tell it to emit itself.
Definition: diagnostic.h:77
static unsigned files()
Get the number of files in the dataset.
Definition: dataset.h:135
static unsigned _error_directives_generated_
Global count of error directives output.
Definition: diagnostic.h:334
static unsigned done_files()
Get the number of files reached by traversal of the dataset
Definition: dataset.h:140
static void top()
Reset the depth of #if-nesting to 0.
Definition: if_control.h:128
info_summary_msg< 1 > info_summary_files_reached
Report total files reached.
Definition: diagnostic.h:824
An error diagnostic.
static unsigned _error_directives_operative_
Global count of operative error directives output.
Definition: diagnostic.h:336
std::string text() const
Get the text of the diagnostic.
Definition: diagnostic.h:153
static bool diagnostic_gagged(unsigned reason)
Say whether a diagnostic reason code is gagged.
Definition: options.cpp:796
virtual severity level() const
Get the severity level of the runtime type.
Definition: diagnostic.h:116
static unsigned _warnings_
Global count of warning diagnostics.
Definition: diagnostic.h:328
static std::string const & prog_name()
Get the program's name.
Definition: options.h:97
std::stringstream _text
The text of the diagnostic.
Definition: diagnostic.h:304
static unsigned _infos_
Global count of informational diagnostics.
Definition: diagnostic.h:326
void despatch() const
Emit the diagnostic.
Definition: diagnostic.cpp:87