comparison extern/vera/src/plugins/tcl/TclInterpreter.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 "TclInterpreter.h"
9 #include "../Exclusions.h"
10 #include "../Reports.h"
11 #include "../Parameters.h"
12 #include "../../structures/SourceFiles.h"
13 #include "../../structures/SourceLines.h"
14 #include "../../structures/Tokens.h"
15 #include "cpptcl-1.1.4/cpptcl.h"
16 #include <fstream>
17 #include <iterator>
18 #include <boost/lexical_cast.hpp>
19 #include <boost/filesystem.hpp>
20 #include <boost/algorithm/string/predicate.hpp>
21
22 namespace // unnamed
23 {
24
25 // helper global pointer
26 // - for those functions that might modify the interpreter's state
27
28 Tcl::interpreter *pInter;
29
30 void report(const std::string & fileName, int lineNumber, const std::string & message)
31 {
32 Vera::Plugins::Reports::add(fileName, lineNumber, message);
33 }
34
35 std::string getParameter(const std::string & name, const std::string & defaultValue)
36 {
37 return Vera::Plugins::Parameters::get(name, defaultValue);
38 }
39
40 Tcl::object getSourceFileNames()
41 {
42 Tcl::object obj;
43
44 const Vera::Structures::SourceFiles::FileNameSet & files =
45 Vera::Structures::SourceFiles::getAllFileNames();
46
47 typedef Vera::Structures::SourceFiles::FileNameSet::const_iterator iterator;
48 const iterator end = files.end();
49 for (iterator it = files.begin(); it != end; ++it)
50 {
51 const Vera::Structures::SourceFiles::FileName & name = *it;
52
53 if (Vera::Plugins::Exclusions::isExcluded(name) == false)
54 {
55 obj.append(*pInter, Tcl::object(name));
56 }
57 }
58
59 return obj;
60 }
61
62 int getLineCount(const std::string & sourceName)
63 {
64 return Vera::Structures::SourceLines::getLineCount(sourceName);
65 }
66
67 std::string getLine(const std::string & sourceName, int lineNumber)
68 {
69 return Vera::Structures::SourceLines::getLine(sourceName, lineNumber);
70 }
71
72 Tcl::object getAllLines(const std::string & sourceName)
73 {
74 Tcl::object obj;
75
76 const Vera::Structures::SourceLines::LineCollection & lines =
77 Vera::Structures::SourceLines::getAllLines(sourceName);
78
79 typedef Vera::Structures::SourceLines::LineCollection::const_iterator iterator;
80 const iterator end = lines.end();
81 for (iterator it = lines.begin(); it != end; ++it)
82 {
83 obj.append(*pInter, Tcl::object(*it));
84 }
85
86 return obj;
87 }
88
89 Tcl::object getTokens(const std::string & sourceName, int fromLine, int fromColumn,
90 int toLine, int toColumn, const Tcl::object & filter)
91 {
92 Vera::Structures::Tokens::FilterSequence filterSeq;
93
94 size_t filterLength = filter.length(*pInter);
95 for (size_t i = 0; i != filterLength; ++i)
96 {
97 filterSeq.push_back(filter.at(*pInter, i).get());
98 }
99
100 Vera::Structures::Tokens::TokenSequence tokenSeq =
101 Vera::Structures::Tokens::getTokens(sourceName,
102 fromLine, fromColumn, toLine, toColumn, filterSeq);
103
104 Tcl::object ret;
105 Vera::Structures::Tokens::TokenSequence::iterator it = tokenSeq.begin();
106 Vera::Structures::Tokens::TokenSequence::iterator end = tokenSeq.end();
107 for ( ; it != end; ++it)
108 {
109 Tcl::object singleToken;
110 singleToken.append(*pInter, Tcl::object(it->value_));
111 singleToken.append(*pInter, Tcl::object(it->line_));
112 singleToken.append(*pInter, Tcl::object(it->column_));
113 singleToken.append(*pInter, Tcl::object(it->name_));
114
115 ret.append(*pInter, singleToken);
116 }
117
118 return ret;
119 }
120
121 void registerCommands(Tcl::interpreter & inter)
122 {
123 pInter = &inter;
124
125 // commands related to source files and plain source code
126 inter.def("report", report);
127 inter.def("getParameter", getParameter);
128 inter.def("getSourceFileNames", getSourceFileNames);
129 inter.def("getLineCount", getLineCount);
130 inter.def("getLine", getLine);
131 inter.def("getAllLines", getAllLines);
132 inter.def("getTokens", getTokens);
133 }
134
135 } // unnamed namespace
136
137 namespace Vera
138 {
139 namespace Plugins
140 {
141
142 void TclInterpreter::execute(const std::string & fileName)
143 {
144 std::ifstream scriptFile(fileName.c_str());
145 if (scriptFile.is_open() == false)
146 {
147 std::ostringstream ss;
148 ss << "Cannot open script " << fileName;
149 throw ScriptError(ss.str());
150 }
151
152 std::string scriptBody;
153 scriptBody.assign(std::istreambuf_iterator<char>(scriptFile), std::istreambuf_iterator<char>());
154
155 Tcl::interpreter inter;
156 registerCommands(inter);
157 try
158 {
159 inter.eval(scriptBody);
160 }
161 catch (Tcl::tcl_error & e)
162 {
163 // rethrow the exception with the name of the rule
164 #if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
165 int errorLine = inter.get()->errorLine;
166 #else
167 int errorLine = Tcl_GetErrorLine(inter.get());
168 #endif
169 throw Tcl::tcl_error(std::string(e.what()) +
170 "\n (file \"" + fileName + "\" line " +
171 boost::lexical_cast<std::string>(errorLine) + ")");
172 }
173 }
174
175 }
176 }