diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extern/vera/src/plugins/tcl/TclInterpreter.cpp	Wed Nov 22 20:10:03 2017 +0100
@@ -0,0 +1,176 @@
+//
+// Copyright (C) 2006-2007 Maciej Sobczak
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include "TclInterpreter.h"
+#include "../Exclusions.h"
+#include "../Reports.h"
+#include "../Parameters.h"
+#include "../../structures/SourceFiles.h"
+#include "../../structures/SourceLines.h"
+#include "../../structures/Tokens.h"
+#include "cpptcl-1.1.4/cpptcl.h"
+#include <fstream>
+#include <iterator>
+#include <boost/lexical_cast.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+
+namespace // unnamed
+{
+
+// helper global pointer
+// - for those functions that might modify the interpreter's state
+
+Tcl::interpreter *pInter;
+
+void report(const std::string & fileName, int lineNumber, const std::string & message)
+{
+    Vera::Plugins::Reports::add(fileName, lineNumber, message);
+}
+
+std::string getParameter(const std::string & name, const std::string & defaultValue)
+{
+    return Vera::Plugins::Parameters::get(name, defaultValue);
+}
+
+Tcl::object getSourceFileNames()
+{
+    Tcl::object obj;
+
+    const Vera::Structures::SourceFiles::FileNameSet & files =
+            Vera::Structures::SourceFiles::getAllFileNames();
+
+    typedef Vera::Structures::SourceFiles::FileNameSet::const_iterator iterator;
+    const iterator end = files.end();
+    for (iterator it = files.begin(); it != end; ++it)
+    {
+        const Vera::Structures::SourceFiles::FileName & name = *it;
+
+        if (Vera::Plugins::Exclusions::isExcluded(name) == false)
+        {
+            obj.append(*pInter, Tcl::object(name));
+        }
+    }
+
+    return obj;
+}
+
+int getLineCount(const std::string & sourceName)
+{
+    return Vera::Structures::SourceLines::getLineCount(sourceName);
+}
+
+std::string getLine(const std::string & sourceName, int lineNumber)
+{
+    return Vera::Structures::SourceLines::getLine(sourceName, lineNumber);
+}
+
+Tcl::object getAllLines(const std::string & sourceName)
+{
+    Tcl::object obj;
+
+    const Vera::Structures::SourceLines::LineCollection & lines =
+            Vera::Structures::SourceLines::getAllLines(sourceName);
+
+    typedef Vera::Structures::SourceLines::LineCollection::const_iterator iterator;
+    const iterator end = lines.end();
+    for (iterator it = lines.begin(); it != end; ++it)
+    {
+        obj.append(*pInter, Tcl::object(*it));
+    }
+
+    return obj;
+}
+
+Tcl::object getTokens(const std::string & sourceName, int fromLine, int fromColumn,
+    int toLine, int toColumn, const Tcl::object & filter)
+{
+    Vera::Structures::Tokens::FilterSequence filterSeq;
+
+    size_t filterLength = filter.length(*pInter);
+    for (size_t i = 0; i != filterLength; ++i)
+    {
+        filterSeq.push_back(filter.at(*pInter, i).get());
+    }
+
+    Vera::Structures::Tokens::TokenSequence tokenSeq =
+        Vera::Structures::Tokens::getTokens(sourceName,
+        fromLine, fromColumn, toLine, toColumn, filterSeq);
+
+    Tcl::object ret;
+    Vera::Structures::Tokens::TokenSequence::iterator it = tokenSeq.begin();
+    Vera::Structures::Tokens::TokenSequence::iterator end = tokenSeq.end();
+    for ( ; it != end; ++it)
+    {
+        Tcl::object singleToken;
+        singleToken.append(*pInter, Tcl::object(it->value_));
+        singleToken.append(*pInter, Tcl::object(it->line_));
+        singleToken.append(*pInter, Tcl::object(it->column_));
+        singleToken.append(*pInter, Tcl::object(it->name_));
+
+        ret.append(*pInter, singleToken);
+    }
+
+    return ret;
+}
+
+void registerCommands(Tcl::interpreter & inter)
+{
+    pInter = &inter;
+
+    // commands related to source files and plain source code
+    inter.def("report", report);
+    inter.def("getParameter", getParameter);
+    inter.def("getSourceFileNames", getSourceFileNames);
+    inter.def("getLineCount", getLineCount);
+    inter.def("getLine", getLine);
+    inter.def("getAllLines", getAllLines);
+    inter.def("getTokens", getTokens);
+}
+
+} // unnamed namespace
+
+namespace Vera
+{
+namespace Plugins
+{
+
+void TclInterpreter::execute(const std::string & fileName)
+{
+    std::ifstream scriptFile(fileName.c_str());
+    if (scriptFile.is_open() == false)
+    {
+        std::ostringstream ss;
+        ss << "Cannot open script " << fileName;
+        throw ScriptError(ss.str());
+    }
+
+    std::string scriptBody;
+    scriptBody.assign(std::istreambuf_iterator<char>(scriptFile), std::istreambuf_iterator<char>());
+
+    Tcl::interpreter inter;
+    registerCommands(inter);
+    try
+    {
+        inter.eval(scriptBody);
+    }
+    catch (Tcl::tcl_error & e)
+    {
+        // rethrow the exception with the name of the rule
+#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
+        int errorLine = inter.get()->errorLine;
+#else
+        int errorLine = Tcl_GetErrorLine(inter.get());
+#endif
+        throw Tcl::tcl_error(std::string(e.what()) +
+            "\n    (file \"" + fileName + "\" line " +
+            boost::lexical_cast<std::string>(errorLine) + ")");
+    }
+}
+
+}
+}