diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extern/vera/src/structures/SourceLines.cpp	Wed Nov 22 20:10:03 2017 +0100
@@ -0,0 +1,120 @@
+//
+// 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 "SourceLines.h"
+#include "Tokens.h"
+#include "../plugins/Reports.h"
+#include <vector>
+#include <map>
+#include <fstream>
+#include <sstream>
+#include <cstring>
+#include <cerrno>
+
+
+namespace // unnamed
+{
+
+typedef std::map<Vera::Structures::SourceFiles::FileName,
+    Vera::Structures::SourceLines::LineCollection> SourceFileCollection;
+
+SourceFileCollection sources_;
+
+} // unnamed namespace
+
+
+namespace Vera
+{
+namespace Structures
+{
+
+const SourceLines::LineCollection & SourceLines::getAllLines(const SourceFiles::FileName & name)
+{
+    const SourceFileCollection::const_iterator it = sources_.find(name);
+    if (it != sources_.end())
+    {
+        return it->second;
+    }
+    else
+    {
+        // lazy load of the source file
+        loadFile(name);
+        return sources_[name];
+    }
+}
+
+void SourceLines::loadFile(const SourceFiles::FileName & name)
+{
+    if (name == "-")
+    {
+        SourceLines::loadFile(std::cin, name);
+    }
+    else
+    {
+        std::ifstream file(name.c_str());
+        if (file.is_open() == false)
+        {
+            std::ostringstream ss;
+            ss << "Cannot open source file " << name << ": "
+               << strerror(errno);
+            throw SourceFileError(ss.str());
+        }
+        SourceLines::loadFile(file, name);
+        if (file.bad())
+        {
+            throw std::runtime_error(
+                "Cannot read from " + name + ": " + strerror(errno));
+        }
+    }
+}
+
+void SourceLines::loadFile(std::istream & file, const SourceFiles::FileName & name)
+{
+    LineCollection & lines = sources_[name];
+
+    std::string line;
+    Tokens::FileContent fullSource;
+    while (getline(file, line))
+    {
+        lines.push_back(line);
+        fullSource += line;
+
+        // built-in rule
+        if (file.eof())
+        {
+            // Plugins::Reports::internal(name, static_cast<int>(lines.size()),
+            //     "no newline at end of file");
+        }
+        else
+        {
+            fullSource += '\n';
+        }
+    }
+
+    Tokens::parse(name, fullSource);
+}
+
+int SourceLines::getLineCount(const SourceFiles::FileName & name)
+{
+    return static_cast<int>(getAllLines(name).size());
+}
+
+const std::string & SourceLines::getLine(const SourceFiles::FileName & name, int lineNumber)
+{
+    const LineCollection & lines = getAllLines(name);
+    if (lineNumber < 1 || lineNumber > static_cast<int>(lines.size()))
+    {
+        std::cerr << "Requested wrong line number: " << lineNumber << '\n';
+        std::cerr << "lines.size in " << name << " is " << static_cast<int>(lines.size()) << '\n';
+        throw SourceFileError("requested line number is out of range");
+    }
+
+    return lines[lineNumber - 1];
+}
+
+}
+}