CBMC
gcc_message_handler.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "gcc_message_handler.h"
10 
11 #ifdef _MSC_VER
12 # include <util/unicode.h>
13 #endif
14 
15 #include <fstream>
16 #include <iostream>
17 
19  unsigned level,
20  const std::string &message,
21  const source_locationt &location)
22 {
23  message_handlert::print(level, message);
24 
25  if(verbosity >= level)
26  {
27  // gcc appears to send everything to cerr
28  auto &out = std::cerr;
29 
30  const irep_idt file = location.get_file();
31  const irep_idt line = location.get_line();
32  const irep_idt column = location.get_column();
33  const irep_idt function = location.get_function();
34 
35  if(!function.empty())
36  {
37  if(!file.empty())
38  out << string(messaget::bold) << file << ':' << string(messaget::reset)
39  << ' ';
40  out << "In function " << string(messaget::bold) << '\'' << function
41  << '\'' << string(messaget::reset) << ":\n";
42  }
43 
44  if(!line.empty())
45  {
46  out << string(messaget::bold);
47 
48  if(!file.empty())
49  out << file << ':';
50 
51  out << line << ':';
52 
53  if(column.empty())
54  out << "1: ";
55  else
56  out << column << ": ";
57 
58  if(level == messaget::M_ERROR)
59  out << string(messaget::red) << "error: ";
60  else if(level == messaget::M_WARNING)
61  out << string(messaget::bright_magenta) << "warning: ";
62 
63  out << string(messaget::reset);
64  }
65 
66  out << message << '\n';
67 
68  const auto file_name = location.full_path();
69  if(file_name.has_value() && !line.empty())
70  {
71 #ifdef _MSC_VER
72  std::ifstream in(widen(file_name.value()));
73 #else
74  std::ifstream in(file_name.value());
75 #endif
76  if(in)
77  {
78  const auto line_number = std::stoull(id2string(line));
79  std::string source_line;
80  for(std::size_t l = 0; l < line_number; l++)
81  std::getline(in, source_line);
82 
83  if(in)
84  out << ' ' << source_line << '\n'; // gcc adds a space, clang doesn't
85  }
86  }
87 
88  out << std::flush;
89  }
90 }
91 
92 void gcc_message_handlert::print(unsigned level, const std::string &message)
93 {
94  message_handlert::print(level, message);
95 
96  // gcc appears to send everything to cerr
97  if(verbosity >= level)
98  std::cerr << message << '\n' << std::flush;
99 }
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
source_locationt::get_function
const irep_idt & get_function() const
Definition: source_location.h:55
messaget::reset
static const commandt reset
return to default formatting, as defined by the terminal
Definition: message.h:343
source_locationt::get_column
const irep_idt & get_column() const
Definition: source_location.h:50
message_handlert::verbosity
unsigned verbosity
Definition: message.h:72
source_locationt::get_line
const irep_idt & get_line() const
Definition: source_location.h:45
message_handlert::print
virtual void print(unsigned level, const std::string &message)=0
Definition: message.cpp:60
messaget::bright_magenta
static const commandt bright_magenta
render text with bright magenta foreground color
Definition: message.h:376
messaget::bold
static const commandt bold
render text with bold font
Definition: message.h:382
gcc_message_handlert::string
std::string string(const messaget::commandt &c) const
feed a command into a string
Definition: gcc_message_handler.h:35
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
messaget::M_ERROR
@ M_ERROR
Definition: message.h:170
dstringt::empty
bool empty() const
Definition: dstring.h:88
source_locationt::full_path
optionalt< std::string > full_path() const
Get a path to the file, including working directory.
Definition: source_location.cpp:85
widen
std::wstring widen(const char *s)
Definition: unicode.cpp:48
source_locationt
Definition: source_location.h:18
gcc_message_handler.h
messaget::M_WARNING
@ M_WARNING
Definition: message.h:170
messaget::red
static const commandt red
render text with red foreground color
Definition: message.h:346
gcc_message_handlert::print
void print(unsigned, const xmlt &) override
Definition: gcc_message_handler.h:17
unicode.h
source_locationt::get_file
const irep_idt & get_file() const
Definition: source_location.h:35