]> granicus.if.org Git - icinga2/blob - lib/base/debuginfo.cpp
Merge pull request #7185 from Icinga/bugfix/gelfwriter-wrong-log-facility
[icinga2] / lib / base / debuginfo.cpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #include "base/debuginfo.hpp"
4 #include "base/convert.hpp"
5 #include <fstream>
6
7 using namespace icinga;
8
9 /**
10  * Outputs a DebugInfo struct to a stream.
11  *
12  * @param out The output stream.
13  * @param val The DebugInfo struct.
14  * @returns The output stream.
15  */
16 std::ostream& icinga::operator<<(std::ostream& out, const DebugInfo& val)
17 {
18         out << "in " << val.Path << ": "
19                 << val.FirstLine << ":" << val.FirstColumn
20                 << "-"
21                 << val.LastLine << ":" << val.LastColumn;
22
23         return out;
24 }
25
26 DebugInfo icinga::DebugInfoRange(const DebugInfo& start, const DebugInfo& end)
27 {
28         DebugInfo result;
29         result.Path = start.Path;
30         result.FirstLine = start.FirstLine;
31         result.FirstColumn = start.FirstColumn;
32         result.LastLine = end.LastLine;
33         result.LastColumn = end.LastColumn;
34         return result;
35 }
36
37 #define EXTRA_LINES 2
38
39 void icinga::ShowCodeLocation(std::ostream& out, const DebugInfo& di, bool verbose)
40 {
41         if (di.Path.IsEmpty())
42                 return;
43
44         out << "Location: " << di;
45
46         std::ifstream ifs;
47         ifs.open(di.Path.CStr(), std::ifstream::in);
48
49         int lineno = 0;
50         char line[1024];
51
52         while (ifs.good() && lineno <= di.LastLine + EXTRA_LINES) {
53                 if (lineno == 0)
54                         out << "\n";
55
56                 lineno++;
57
58                 ifs.getline(line, sizeof(line));
59
60                 for (int i = 0; line[i]; i++)
61                         if (line[i] == '\t')
62                                 line[i] = ' ';
63
64                 int extra_lines = verbose ? EXTRA_LINES : 0;
65
66                 if (lineno < di.FirstLine - extra_lines || lineno > di.LastLine + extra_lines)
67                         continue;
68
69                 String pathInfo = di.Path + "(" + Convert::ToString(lineno) + "): ";
70                 out << pathInfo;
71                 out << line << "\n";
72
73                 if (lineno >= di.FirstLine && lineno <= di.LastLine) {
74                         int start, end;
75
76                         start = 0;
77                         end = strlen(line);
78
79                         if (lineno == di.FirstLine)
80                                 start = di.FirstColumn - 1;
81
82                         if (lineno == di.LastLine)
83                                 end = di.LastColumn;
84
85                         if (start < 0) {
86                                 end -= start;
87                                 start = 0;
88                         }
89
90                         out << String(pathInfo.GetLength(), ' ');
91                         out << String(start, ' ');
92                         out << String(end - start, '^');
93
94                         out << "\n";
95                 }
96         }
97 }
98