]> granicus.if.org Git - icinga2/blob - lib/base/debuginfo.cpp
Update copyright headers for 2016
[icinga2] / lib / base / debuginfo.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2016 Icinga Development Team (https://www.icinga.org/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (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, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "base/debuginfo.hpp"
21 #include "base/convert.hpp"
22 #include <fstream>
23
24 using namespace icinga;
25
26 DebugInfo::DebugInfo(void)
27         : FirstLine(0), FirstColumn(0), LastLine(0), LastColumn(0)
28 { }
29
30 /**
31  * Outputs a DebugInfo struct to a stream.
32  *
33  * @param out The output stream.
34  * @param val The DebugInfo struct.
35  * @returns The output stream.
36  */
37 std::ostream& icinga::operator<<(std::ostream& out, const DebugInfo& val)
38 {
39         out << "in " << val.Path << ": "
40             << val.FirstLine << ":" << val.FirstColumn
41             << "-"
42             << val.LastLine << ":" << val.LastColumn;
43
44         return out;
45 }
46
47 DebugInfo icinga::DebugInfoRange(const DebugInfo& start, const DebugInfo& end)
48 {
49         DebugInfo result;
50         result.Path = start.Path;
51         result.FirstLine = start.FirstLine;
52         result.FirstColumn = start.FirstColumn;
53         result.LastLine = end.LastLine;
54         result.LastColumn = end.LastColumn;
55         return result;
56 }
57
58 #define EXTRA_LINES 2
59
60 void icinga::ShowCodeLocation(std::ostream& out, const DebugInfo& di, bool verbose)
61 {
62         if (di.Path.IsEmpty())
63                 return;
64
65         out << "Location: " << di << "\n";
66
67         std::ifstream ifs;
68         ifs.open(di.Path.CStr(), std::ifstream::in);
69
70         int lineno = 0;
71         char line[1024];
72
73         while (ifs.good() && lineno <= di.LastLine + EXTRA_LINES) {
74                 lineno++;
75
76                 ifs.getline(line, sizeof(line));
77
78                 for (int i = 0; line[i]; i++)
79                         if (line[i] == '\t')
80                                 line[i] = ' ';
81
82                 int extra_lines = verbose ? EXTRA_LINES : 0;
83
84                 if (lineno < di.FirstLine - extra_lines || lineno > di.LastLine + extra_lines)
85                         continue;
86
87                 String pathInfo = di.Path + "(" + Convert::ToString(lineno) + "): ";
88                 out << pathInfo;
89                 out << line << "\n";
90
91                 if (lineno >= di.FirstLine && lineno <= di.LastLine) {
92                         int start, end;
93
94                         start = 0;
95                         end = strlen(line);
96
97                         if (lineno == di.FirstLine)
98                                 start = di.FirstColumn - 1;
99
100                         if (lineno == di.LastLine)
101                                 end = di.LastColumn;
102
103                         if (start < 0) {
104                                 end -= start;
105                                 start = 0;
106                         }
107
108                         out << String(pathInfo.GetLength(), ' ');
109                         out << String(start, ' ');
110                         out << String(end - start, '^');
111
112                         out << "\n";
113                 }
114         }
115 }
116