comparison extern/vera/src/structures/SourceLines.cpp @ 548:a7c0eb100760

CMake: import vera++ 1.3.0, closes #729
author David Demelier <markand@malikania.fr>
date Wed, 22 Nov 2017 20:10:03 +0100
parents
children
comparison
equal deleted inserted replaced
547:a95954e53589 548:a7c0eb100760
1 //
2 // Copyright (C) 2006-2007 Maciej Sobczak
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7
8 #include "SourceLines.h"
9 #include "Tokens.h"
10 #include "../plugins/Reports.h"
11 #include <vector>
12 #include <map>
13 #include <fstream>
14 #include <sstream>
15 #include <cstring>
16 #include <cerrno>
17
18
19 namespace // unnamed
20 {
21
22 typedef std::map<Vera::Structures::SourceFiles::FileName,
23 Vera::Structures::SourceLines::LineCollection> SourceFileCollection;
24
25 SourceFileCollection sources_;
26
27 } // unnamed namespace
28
29
30 namespace Vera
31 {
32 namespace Structures
33 {
34
35 const SourceLines::LineCollection & SourceLines::getAllLines(const SourceFiles::FileName & name)
36 {
37 const SourceFileCollection::const_iterator it = sources_.find(name);
38 if (it != sources_.end())
39 {
40 return it->second;
41 }
42 else
43 {
44 // lazy load of the source file
45 loadFile(name);
46 return sources_[name];
47 }
48 }
49
50 void SourceLines::loadFile(const SourceFiles::FileName & name)
51 {
52 if (name == "-")
53 {
54 SourceLines::loadFile(std::cin, name);
55 }
56 else
57 {
58 std::ifstream file(name.c_str());
59 if (file.is_open() == false)
60 {
61 std::ostringstream ss;
62 ss << "Cannot open source file " << name << ": "
63 << strerror(errno);
64 throw SourceFileError(ss.str());
65 }
66 SourceLines::loadFile(file, name);
67 if (file.bad())
68 {
69 throw std::runtime_error(
70 "Cannot read from " + name + ": " + strerror(errno));
71 }
72 }
73 }
74
75 void SourceLines::loadFile(std::istream & file, const SourceFiles::FileName & name)
76 {
77 LineCollection & lines = sources_[name];
78
79 std::string line;
80 Tokens::FileContent fullSource;
81 while (getline(file, line))
82 {
83 lines.push_back(line);
84 fullSource += line;
85
86 // built-in rule
87 if (file.eof())
88 {
89 // Plugins::Reports::internal(name, static_cast<int>(lines.size()),
90 // "no newline at end of file");
91 }
92 else
93 {
94 fullSource += '\n';
95 }
96 }
97
98 Tokens::parse(name, fullSource);
99 }
100
101 int SourceLines::getLineCount(const SourceFiles::FileName & name)
102 {
103 return static_cast<int>(getAllLines(name).size());
104 }
105
106 const std::string & SourceLines::getLine(const SourceFiles::FileName & name, int lineNumber)
107 {
108 const LineCollection & lines = getAllLines(name);
109 if (lineNumber < 1 || lineNumber > static_cast<int>(lines.size()))
110 {
111 std::cerr << "Requested wrong line number: " << lineNumber << '\n';
112 std::cerr << "lines.size in " << name << " is " << static_cast<int>(lines.size()) << '\n';
113 throw SourceFileError("requested line number is out of range");
114 }
115
116 return lines[lineNumber - 1];
117 }
118
119 }
120 }