Mercurial > irccd
changeset 548:a7c0eb100760
CMake: import vera++ 1.3.0, closes #729
line wrap: on
line diff
--- a/cmake/IrccdOptions.cmake Wed Nov 22 20:01:05 2017 +0100 +++ b/cmake/IrccdOptions.cmake Wed Nov 22 20:10:03 2017 +0100 @@ -166,25 +166,12 @@ set(WITH_HTML_MSG "No (disabled by user)") endif () -find_program(VERA_EXECUTABLE vera++) - -if (VERA_EXECUTABLE) - if (WITH_VERA) - execute_process( - COMMAND ${VERA_EXECUTABLE} --version - OUTPUT_VARIABLE VERA_VERSION - ) - - if (${VERA_VERSION} GREATER_EQUAL "1.3.0") - set(HAVE_VERA On) - else () - set(WITH_VERA_MSG "No (1.3.0 or greater required)") - endif () - else () - set(WITH_VERA_MSG "No (disabled by user)") - endif () +if (WITH_VERA) + add_subdirectory(extern/vera) + set(HAVE_VERA On) + set(WITH_VERA_MSG "Yes") else () - set(WITH_VERA_MSG "No (vera++ not found)") + set(WITH_VERA_MSG "No (disabled by user)") endif () #
--- a/cmake/function/IrccdVeraCheck.cmake Wed Nov 22 20:01:05 2017 +0100 +++ b/cmake/function/IrccdVeraCheck.cmake Wed Nov 22 20:10:03 2017 +0100 @@ -48,7 +48,7 @@ add_custom_command( TARGET ${target} COMMAND - ${VERA_EXECUTABLE} -w --root ${CMAKE_SOURCE_DIR}/vera ${newsources} + $<TARGET_FILE:vera> -w --root ${CMAKE_SOURCE_DIR}/vera ${newsources} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} VERBATIM )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/LICENSE.vera.txt Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/VERSION.vera.txt Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,1 @@ +1.3.0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/CMakeLists.txt Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,9 @@ +project(vera++) +cmake_minimum_required(VERSION 3.0) + +set(VERA_MAJOR 1) +set(VERA_MINOR 3) +set(VERA_BUILD 0) +set(VERA_VERSION "${VERA_MAJOR}.${VERA_MINOR}.${VERA_BUILD}") + +add_subdirectory(src)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/CMakeLists.txt Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,46 @@ +find_package(TCL) # REQUIRED) +# don't use find_package's REQUIRED parameter to avoid requiring tk +if(NOT TCL_FOUND) + message(FATAL_ERROR "TCL was not found.") +endif() +include_directories(SYSTEM ${TCL_INCLUDE_PATH}) +link_directories(${TCL_LIBRARY_DIRS}) + +set(boostLibs filesystem system program_options regex wave) + +if(WIN32) + # use boost static libs to avoid LNK2019 errors + # feel free to contribute a better fix! + set(Boost_USE_STATIC_LIBS ON) +else() + # expose the Boost_USE_STATIC_LIBS option to ease the manual creation of + # packages with cpack + option(Boost_USE_STATIC_LIBS "Use Boost static libraries" OFF) +endif() +find_package(Boost COMPONENTS ${boostLibs} REQUIRED) +include_directories(SYSTEM ${Boost_INCLUDE_DIRS}) +link_directories(${Boost_LIBRARY_DIRS}) +# hide Boost_DIR option that doesn't seem to be set by FindBoost +mark_as_advanced(Boost_DIR) +# no target +set(Boost_TARGET) + +if(MSVC) + # hide the warning generated by the usage of getenv() + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + add_definitions(-D_SCL_SECURE_NO_WARNINGS) +endif(MSVC) + +configure_file(config.h.in config.h @ONLY) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +file(GLOB_RECURSE srcs *.cpp) +add_executable(vera ${srcs}) +set_target_properties(vera PROPERTIES OUTPUT_NAME vera++) +target_link_libraries(vera + ${TCL_LIBRARY} + ${Boost_LIBRARIES}) +if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + # keep it at the end to be able to build on ubuntu + target_link_libraries(vera dl) +endif()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/boost_main.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,369 @@ +// +// 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 "config.h" +#include "structures/SourceFiles.h" +#include "plugins/Profiles.h" +#include "plugins/Rules.h" +#include "plugins/Exclusions.h" +#include "plugins/Transformations.h" +#include "plugins/Parameters.h" +#include "plugins/Reports.h" +#include "plugins/RootDirectory.h" +#include <iostream> +#include <fstream> +#include <string> +#include <vector> +#include <cstdlib> +#include <sys/stat.h> +#include <cstring> +#include <cerrno> +#include <boost/program_options.hpp> +#include <boost/foreach.hpp> +#include "get_vera_root_default.h" + +#define foreach BOOST_FOREACH + +#ifdef _MSC_VER +// vm.count() used as a bool +#pragma warning(disable:4800) +#endif + +template<typename Files, typename Options, typename Reporter> +void doReports(Files & reports, Options & vm, Reporter * reporter) +{ + foreach (const std::string & fn, reports) + { + if (fn == "-") + { + if (vm.count("warning") || vm.count("error")) + { + (*reporter)(std::cerr, vm.count("no-duplicate")); + } + else + { + (*reporter)(std::cout, vm.count("no-duplicate")); + } + } + else + { + std::ofstream file(fn.c_str()); + if (file.is_open() == false) + { + throw std::runtime_error( + "Cannot open " + fn + ": " + strerror(errno)); + } + (*reporter)(file, vm.count("no-duplicate")); + if (file.bad()) + { + throw std::runtime_error( + "Cannot write to " + fn + ": " + strerror(errno)); + } + file.close(); + } + } + +} + +int boost_main(int argc, char * argv[]) +{ + // The directory containing the profile and rule definitions + // by default it is (in this order, first has highest precedence): + // - VERA_ROOT (if VERA_ROOT is defined) + // - HOME/.vera++ (if HOME is defined) + // - current directory (if scripts and profile are present) + // - /usr/lib/vera++/ default debian directory + + Vera::Plugins::RootDirectory::DirectoryName veraRoot(get_vera_root_default(argv[0])); + + struct stat St; + bool isInCurrent = ( (stat( "./scripts", &St ) == 0 || stat( "./rules", &St ) == 0 + || stat( "./transforms", &St ) == 0) + && stat( "./profiles", &St ) == 0 ); + + // scripts and profiles folders are inside current directory + if (isInCurrent) + { + // we can override /usr/lib/vera++ + veraRoot = "."; + } + char * veraRootEnv = getenv("HOME"); + if (veraRootEnv != NULL) + { + Vera::Plugins::RootDirectory::DirectoryName veraRootTmp(veraRootEnv); + veraRootTmp += "/.vera++"; + bool isInHome = ( stat( veraRootTmp.c_str(), &St ) == 0 ); + if (isInHome) + { + // We assume that if the user has a .vera++ folder in + // their home then we can override the current + // directory + // We don't want to override the current directory + // only because $HOME is defined. + veraRoot = veraRootEnv; + veraRoot += "/.vera++"; + } + } + veraRootEnv = getenv("VERA_ROOT"); + if (veraRootEnv != NULL) + { + veraRoot = veraRootEnv; + } + + std::string profile = "default"; + std::string transform; + std::vector<std::string> rules; + std::vector<std::string> parameters; + std::vector<std::string> parameterFiles; + std::vector<std::string> inputs; + std::vector<std::string> inputFiles; + std::vector<std::string> exclusionFiles; + // outputs + std::vector<std::string> stdreports; + std::vector<std::string> vcreports; + std::vector<std::string> xmlreports; + std::vector<std::string> checkstylereports; + /** Define and parse the program options + */ + namespace po = boost::program_options; + po::options_description visibleOptions("Options"); + visibleOptions.add_options() + ("profile,p", po::value(&profile), "execute all rules from the given profile") + ("rule,R", po::value(&rules), "execute the given rule (note: the .tcl extension is added" + " automatically. can be used many times.)") + ("transform", po::value(&transform), "execute the given transformation") + ("std-report,o", po::value(&stdreports), "write the standard (gcc-like) report to this" + "file. Default is standard or error output depending on the options." + " (note: may be used many times.)") + ("vc-report,v", po::value(&vcreports), "write the Visual C report to this file." + " Not used by default. (note: may be used many times.)") + ("xml-report,x", po::value(&xmlreports), "write the XML report to this file." + " Not used by default. (note: may be used many times.)") + ("checkstyle-report,c", po::value(&checkstylereports), + "write the checkstyle report to this file." + " Not used by default. (note: may be used many times.)") + ("show-rule,s", "include rule name in each report") + ("no-duplicate,d", "do not duplicate messages if a single rule is violated many times in a" + " single line of code") + ("warning,w", "reports are marked as warning and generated on error output") + ("error,e", "reports are marked as error and generated on error output." + " A non zero exit code is used when one or more reports are generated.") + ("quiet,q", "don't display the reports") + ("summary,S", "display the number of reports and the number of processed files") + ("parameters", po::value(¶meterFiles), "read parameters from file" + " (note: can be used many times)") + ("parameter,P", po::value(¶meters), "provide parameters to the scripts as name=value" + " (note: can be used many times)") + ("exclusions", po::value(&exclusionFiles), "read exclusions from file" + " (note: can be used many times)") + ("inputs,i", po::value(&inputFiles), "the inputs are read from that file (note: one file" + " per line. can be used many times.)") + ("root,r", po::value(&veraRoot), "use the given directory as the vera root directory") + ("help,h", "show this help message and exit") + ("version", "show vera++'s version and exit"); + + // don't call it "input", as is may seems more logical, in order to get an error when + // --inputs is used without the "s" at the end + po::options_description allOptions; + allOptions.add(visibleOptions).add_options() + ("__input__", po::value(&inputs), "input files from command line"); + + po::positional_options_description positionalOptions; + positionalOptions.add("__input__", -1); + + po::variables_map vm; + try + { + po::store(po::command_line_parser(argc, argv).options(allOptions) + .positional(positionalOptions).run(), vm); + if ( vm.count("help") ) + { + std::cout << "vera++ [options] [list-of-files]" << std::endl + << visibleOptions << std::endl; + return EXIT_SUCCESS; + } + po::notify(vm); // throws on error, so do after help in case + // there are any problems + + // don't do the profile stuff when we only want the version + if (vm.count("version")) + { + std::cout << VERA_VERSION << '\n'; + return EXIT_SUCCESS; + } + + // we need the root to be able to find the profiles + Vera::Plugins::RootDirectory::setRootDirectory(veraRoot); + + if (vm.count("profile") != 0 || (vm.count("rule") == 0 && vm.count("transform") == 0)) + { + try + { + // backward compatibility stuff + Vera::Plugins::Profiles::RuleNameCollection res = + Vera::Plugins::Profiles::getListOfScriptNamesTcl(profile); + rules.insert(rules.end(), res.begin(), res.end()); + } + catch (...) + { + std::string profileFile = veraRoot + "/profiles/" + profile; + std::ifstream file(profileFile.c_str()); + if (file.is_open() == false) + { + throw std::runtime_error( + "Cannot open profile description for profile '" + profile + "': " + + strerror(errno)); + } + po::store(po::parse_config_file(file, visibleOptions), vm); + if (file.bad()) + { + throw std::runtime_error( + "Cannot read from profile description '" + profile + "': " + + strerror(errno)); + } + po::notify(vm); + } + } + } + catch (po::error& e) + { + std::cerr << "vera++: " << e.what() << std::endl << std::endl; + std::cerr << visibleOptions << std::endl; + return EXIT_FAILURE; + } + catch (std::exception& e) + { + std::cerr << "vera++: " << e.what() << std::endl; + return EXIT_FAILURE; + } + + try + { + Vera::Plugins::Reports::setShowRules(vm.count("show-rule")); + if (vm.count("warning")) + { + if (vm.count("error")) + { + std::cerr << "vera++: --warning and --error can't be used at the same time." + << std::endl; + std::cerr << visibleOptions << std::endl; + return EXIT_FAILURE; + } + Vera::Plugins::Reports::setPrefix("warning"); + } + if (vm.count("error")) + { + Vera::Plugins::Reports::setPrefix("error"); + } + foreach (const std::string & f, exclusionFiles) + { + Vera::Plugins::Exclusions::setExclusions(f); + } + foreach (const std::string & f, parameterFiles) + { + Vera::Plugins::Parameters::readFromFile(f); + } + foreach (const std::string & p, parameters) + { + Vera::Plugins::Parameters::ParamAssoc assoc(p); + Vera::Plugins::Parameters::set(assoc); + } + if (vm.count("__input__")) + { + foreach (const std::string & i, inputs) + { + Vera::Structures::SourceFiles::addFileName(i); + } + } + if (vm.count("__input__") == 0 && vm.count("inputs") == 0) + { + // list of source files is provided on stdin + inputFiles.push_back("-"); + } + + foreach (const std::string & f, inputFiles) + { + if (f == "-") + { + Vera::Structures::SourceFiles::FileName name; + while (std::getline(std::cin, name)) + { + Vera::Structures::SourceFiles::addFileName(name); + } + } + else + { + std::ifstream file(f.c_str()); + if (file.is_open() == false) + { + throw std::runtime_error( + "Cannot open " + f + ": " + strerror(errno)); + } + std::string name; + while (std::getline(file, name)) + { + Vera::Structures::SourceFiles::addFileName(name); + } + if (file.bad()) + { + throw std::runtime_error( + "Cannot read from " + f + ": " + strerror(errno)); + } + file.close(); + } + } + + if (vm.count("std-report") == 0 && vm.count("vc-report") == 0 + && vm.count("xml-report") == 0 && vm.count("checkstyle-report") == 0 + && vm.count("quiet") == 0) + { + // no report set - use std report on std out/err + stdreports.push_back("-"); + } + + if (rules.empty() == false) + { + if (vm.count("transform")) + { + std::cerr << "vera++: --transform and --rule can't be used at the same time." + << std::endl; + std::cerr << visibleOptions << std::endl; + return EXIT_FAILURE; + } + foreach (const std::string & r, rules) + { + Vera::Plugins::Rules::executeRule(r); + } + } + else if (vm.count("transform")) + { + Vera::Plugins::Transformations::executeTransformation(transform); + } + + doReports(stdreports, vm, Vera::Plugins::Reports::writeStd); + doReports(vcreports, vm, Vera::Plugins::Reports::writeVc); + doReports(xmlreports, vm, Vera::Plugins::Reports::writeXml); + doReports(checkstylereports, vm, Vera::Plugins::Reports::writeCheckStyle); + + if (vm.count("summary")) + { + std::cerr << Vera::Plugins::Reports::count() << " reports in " + << Vera::Structures::SourceFiles::count() << " files." << std::endl; + } + } + catch (const std::exception & e) + { + std::cerr << "vera++: " << e.what() << std::endl; + return EXIT_FAILURE; + } + + if (vm.count("error") && Vera::Plugins::Reports::count() !=0) + { + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/config.h.in Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,8 @@ +// +// 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) +// + +#define VERA_VERSION "@VERA_VERSION@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/executable_path.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,121 @@ +// +// Copyright (C) 2014 Ben Key +// 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 <stdio.h> +#include <stdlib.h> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> + +#include "executable_path.h" + +#if defined(_WIN32) + +# include <Windows.h> + +std::string executable_path(const char *argv0) +{ + char buf[1024] = {0}; + DWORD ret = GetModuleFileNameA(NULL, buf, sizeof(buf)); + if (ret == 0 || ret == sizeof(buf)) + { + return executable_path_fallback(argv0); + } + return buf; +} + +#elif defined(__APPLE__) + +# include <mach-o/dyld.h> + +std::string executable_path(const char *argv0) +{ + char buf[1024] = {0}; + uint32_t size = sizeof(buf); + int ret = _NSGetExecutablePath(buf, &size); + if (0 != ret) + { + return executable_path_fallback(argv0); + } + boost::filesystem::path full_path( + boost::filesystem::system_complete( + boost::filesystem::path(buf).normalize())); + return full_path.string(); +} + +#elif defined(sun) || defined(__sun) + +# include <stdlib.h> + +std::string executable_path(const char *argv0) +{ + return getexecname(); +} + +#elif defined(__FreeBSD__) + +# include <sys/sysctl.h> + +std::string executable_path(const char *argv0) +{ + int mib[4] = {0}; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + char buf[1024] = {0}; + size_t size = sizeof(buf); + sysctl(mib, 4, buf, &size, NULL, 0); + if (size == 0 || size == sizeof(buf)) + { + return executable_path_fallback(argv0); + } + std::string path(buf, size); + boost::filesystem::path full_path( + boost::filesystem::system_complete( + boost::filesystem::path(path).normalize())); + return full_path.string(); +} + +#elif defined(__linux__) + +# include <unistd.h> + +std::string executable_path(const char *argv0) +{ + char buf[1024] = {0}; + ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf)); + if (size == 0 || size == sizeof(buf)) + { + return executable_path_fallback(argv0); + } + std::string path(buf, size); + boost::filesystem::path full_path( + boost::filesystem::system_complete( + boost::filesystem::path(path).normalize())); + return full_path.string(); +} + +#else + +std::string executable_path(const char *argv0) +{ + return executable_path_fallback(argv0); +} + +#endif + +std::string executable_path_fallback(const char *argv0) +{ + if (0 == argv0 || 0 == argv0[0]) + { + return ""; + } + boost::filesystem::path full_path( + boost::filesystem::system_complete( + boost::filesystem::path(argv0))); + return full_path.string(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/executable_path.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,18 @@ +// +// Copyright (C) 2014 Ben Key +// 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) +// + +#ifndef EXECUTABLE_PATH_H_INCLUDED +#define EXECUTABLE_PATH_H_INCLUDED + +#pragma once + +#include <string> + +std::string executable_path(const char * argv0); +std::string executable_path_fallback(const char * argv0); + +#endif // EXECUTABLE_PATH_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/get_vera_root_default.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,33 @@ +// +// Copyright (C) 2014 Ben Key +// 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 <stdio.h> +#include <stdlib.h> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> +#include "get_vera_root_default.h" +#include "executable_path.h" + +std::string get_vera_install_dir(const char *argv0) +{ + boost::filesystem::path veraPath(executable_path(argv0)); + veraPath = veraPath.remove_filename(); + boost::filesystem::path fileName = veraPath.filename(); + if (fileName.string() == "bin") + { + veraPath = veraPath.remove_filename(); + } + return veraPath.string(); +} + +std::string get_vera_root_default(const char *argv0) +{ + boost::filesystem::path veraRoot(get_vera_install_dir(argv0)); + veraRoot /= "lib"; + veraRoot /= "vera++"; + return veraRoot.string(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/get_vera_root_default.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,18 @@ +// +// Copyright (C) 2014 Ben Key +// 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) +// + +#ifndef GET_VERA_INSTALL_DIR_H_INCLUDED +#define GET_VERA_INSTALL_DIR_H_INCLUDED + +#pragma once + +#include <string> + +std::string get_vera_install_dir(const char * argv0); +std::string get_vera_root_default(const char *argv0); + +#endif // GET_VERA_INSTALL_DIR_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/legacy_main.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,335 @@ +// +// 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 "config.h" +#include "structures/SourceFiles.h" +#include "plugins/Profiles.h" +#include "plugins/Rules.h" +#include "plugins/Exclusions.h" +#include "plugins/Transformations.h" +#include "plugins/Parameters.h" +#include "plugins/Reports.h" +#include "plugins/RootDirectory.h" +#include <iostream> +#include <fstream> +#include <string> +#include <vector> +#include <cstdlib> +#include <sys/stat.h> +#include "get_vera_root_default.h" + +namespace // unnamed +{ + +// helper function that checks whether the given file name names the C or C++ source file +bool isSourceFileName(const Vera::Structures::SourceFiles::FileName & name) +{ + const std::string suffixes[] = + { ".cpp", ".cxx", ".cc", ".c", ".C", ".h", ".hh", ".hpp", ".hxx", ".ipp" }; + + const int numOfSuffixes = sizeof(suffixes) / sizeof(std::string); + for (int i = 0; i != numOfSuffixes; ++i) + { + const std::string suf = suffixes[i]; + const Vera::Structures::SourceFiles::FileName::size_type pos = name.rfind(suf); + + if (pos != Vera::Structures::SourceFiles::FileName::npos && + pos == name.size() - suf.size()) + { + return true; + } + } + + return false; +} + +} // unnamed namespace + + +int legacy_main(int argc, char * argv[], bool silent = false) +{ + int exitCodeOnFailure = EXIT_FAILURE; + + try + { + Vera::Plugins::Profiles::ProfileName profile("default"); + + // the directory containing the profile and rule definitions + // by default it is (in this order, first has highest precedence): + // - VERA_ROOT (if VERA_ROOT is defined) + // - HOME/.vera++ (if HOME is defined) + // - current directory (if scripts and profile are present) + // - /usr/lib/vera++/ default debian directory + + Vera::Plugins::RootDirectory::DirectoryName veraRoot(get_vera_root_default(argv[0])); + + struct stat St; + bool isInCurrent = ( (stat( "./scripts", &St ) == 0 || stat( "./rules", &St ) == 0 + || stat( "./transforms", &St ) == 0) + && stat( "./profiles", &St ) == 0 ); + + // scripts and profiles folders are inside current directory + if (isInCurrent) + { + // we can override /usr/lib/vera++ + veraRoot = "."; + } + char * veraRootEnv = getenv("HOME"); + if (veraRootEnv != NULL) + { + Vera::Plugins::RootDirectory::DirectoryName veraRootTmp(veraRootEnv); + veraRootTmp += "/.vera++"; + bool isInHome = ( stat( veraRootTmp.c_str(), &St ) == 0 ); + if (isInHome) + { + // We assume that if the user has a .vera++ folder in + // their home then we can override the current + // directory + // We don't want to override the current directory + // only because $HOME is defined. + veraRoot = veraRootEnv; + veraRoot += "/.vera++"; + } + } + veraRootEnv = getenv("VERA_ROOT"); + if (veraRootEnv != NULL) + { + veraRoot = veraRootEnv; + } + + Vera::Plugins::RootDirectory::setRootDirectory(veraRoot); + + // collect all source file names and interpret options + + Vera::Plugins::Rules::RuleName singleRule; + Vera::Plugins::Transformations::TransformationName singleTransformation; + + bool omitDuplicates = false; + + int i = 1; + while (i != argc) + { + const std::string arg(argv[i]); + + if (arg == "-help") + { + std::cout << "vera++ [options] [list-of-files]\n\n" + "This command line interface is deprecated and is planned to be removed.\n\n" + "Recognized options:\n\n" + "- (a single minus sign) indicates that the list of\n" + " source file names will be provided on the stdin.\n\n" + "-exclusions file read exclusions from file\n\n" + "-help print this message\n\n" + "-nofail do not fail even when finding rule violations\n\n" + "-nodup do not duplicate messages if a single rule is violated\n" + " many times in a single line of code\n\n" + "-profile name execute all rules from the given profile\n\n" + "-param name=value provide parameters to scripts (can be used many times)\n\n" + "-paramfile file read parameters from file\n\n" + "-rule name execute the given rule\n" + " (note: the .tcl extension is added automatically)\n\n" + "-showrules include rule name in each report\n\n" + "-vcformat report in Visual C++ format\n\n" + "-xmlreport produce report in the XML format\n\n" + "-transform name execute the given transformation\n\n" + "-version print version number\n\n"; + exit(EXIT_SUCCESS); + } + else if (arg == "-version") + { + std::cout << VERA_VERSION << '\n'; + exit(EXIT_SUCCESS); + } + else if (arg == "-nofail") + { + exitCodeOnFailure = EXIT_SUCCESS; + } + else if (arg == "-nodup") + { + omitDuplicates = true; + } + else if (arg == "-") + { + // list of source files is provided on stdin + Vera::Structures::SourceFiles::FileName name; + while (std::cin >> name) + { + Vera::Structures::SourceFiles::addFileName(name); + } + } + else if (arg == "-showrules") + { + Vera::Plugins::Reports::setShowRules(true); + } + else if (arg == "-xmlreport") + { + Vera::Plugins::Reports::setXMLReport(true); + } + else if (arg == "-vcformat") + { + Vera::Plugins::Reports::setVCFormat(true); + } + else if (arg == "-rule") + { + ++i; + if (argv[i] != NULL) + { + singleRule = argv[i]; + } + else + { + if (silent == false) + { + std::cerr << "error: option -rule provided with no rule name\n"; + } + return exitCodeOnFailure; + } + } + else if (arg == "-profile") + { + ++i; + if (argv[i] != NULL) + { + profile = argv[i]; + } + else + { + if (silent == false) + { + std::cerr << "error: option -profile provided with no profile name\n"; + } + return exitCodeOnFailure; + } + } + else if (arg == "-exclusions") + { + ++i; + if (argv[i] != NULL) + { + Vera::Plugins::Exclusions::ExclusionFileName file(argv[i]); + Vera::Plugins::Exclusions::setExclusions(file); + } + else + { + if (silent == false) + { + std::cerr << "error: option -exclusions provided without name of file\n"; + } + return exitCodeOnFailure; + } + } + else if (arg == "-param") + { + ++i; + if (argv[i] != NULL) + { + Vera::Plugins::Parameters::ParamAssoc assoc(argv[i]); + Vera::Plugins::Parameters::set(assoc); + } + else + { + if (silent == false) + { + std::cerr << "error: option -param provided without name and value\n"; + } + return exitCodeOnFailure; + } + } + else if (arg == "-paramfile") + { + ++i; + if (argv[i] != NULL) + { + Vera::Plugins::Parameters::FileName file(argv[i]); + Vera::Plugins::Parameters::readFromFile(file); + } + else + { + if (silent == false) + { + std::cerr << "error: option -paramfile provided without name of file\n"; + } + return exitCodeOnFailure; + } + } + else if (arg == "-transform") + { + ++i; + if (argv[i] != NULL) + { + singleTransformation = argv[i]; + } + else + { + if (silent == false) + { + std::cerr + << "error: option -transform provided without name of transformation\n"; + } + return exitCodeOnFailure; + } + } + else if (isSourceFileName(arg)) + { + Vera::Structures::SourceFiles::addFileName(arg); + } + else + { + // the option was not recognized as a name of the source file + // or a vera-specific option + if (silent == false) + { + std::cerr << "error: option " << arg << " not recognized\n"; + } + return EXIT_FAILURE; + } + + ++i; + } + + if (Vera::Structures::SourceFiles::empty()) + { + if (silent == false) + { + std::cerr << "vera++: no input files\n"; + } + return exitCodeOnFailure; + } + + if (singleTransformation.empty() == false) + { + if (singleRule.empty() == false || profile != "default") + { + if (silent == false) + { + std::cerr << "error: " + "transformation cannot be specified together with rules or profiles\n"; + } + return exitCodeOnFailure; + } + + Vera::Plugins::Transformations::executeTransformation(singleTransformation); + } + else if (singleRule.empty() == false) + { + // single rule requested + Vera::Plugins::Rules::executeRule(singleRule); + } + else + { + Vera::Plugins::Profiles::executeProfile(profile); + } + + Vera::Plugins::Reports::dumpAll(std::cerr, omitDuplicates); + } + catch (const std::exception & e) + { + std::cerr << "error: " << e.what() << '\n'; + exit(exitCodeOnFailure); + } + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/main.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,65 @@ +// +// 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 <cstdlib> +#include <string> +#include <boost/algorithm/string.hpp> + +int legacy_main(int argc, char * argv[], bool silent = false); + +int boost_main(int argc, char * argv[]); + +int main(int argc, char * argv[]) +{ + char * veraLegacyEnv = getenv("VERA_LEGACY"); + if (veraLegacyEnv != NULL) + { + std::string legacy = veraLegacyEnv; + boost::to_lower(legacy); + if (legacy == "yes" || legacy == "on" || legacy == "1") + { + // use the legacy main, and nothing else + return legacy_main(argc, argv); + } + // use the boost main and nothing else + return boost_main(argc, argv); + } + // look at the arg if we can find some options that looks like legacy + // options + int i = 1; + bool useLegacy = false; + while (i != argc) + { + const std::string arg(argv[i]); + if (arg == "-version" + || arg == "-help" + || arg == "-nofail" + || arg == "-nodup" + || arg == "-showrules" + || arg == "-xmlreport" + || arg == "-vcformat" + || arg == "-rule" + || arg == "-profile" + || arg == "-exclusions" + || arg == "-param" + || arg == "-paramfile" + || arg == "-transform") + { + useLegacy = true; + break; + } + ++i; + } + // if legacy main fail, we silently pass to boost main in order to display + // the new usage message + if (useLegacy && legacy_main(argc, argv, true) == EXIT_SUCCESS) + { + return EXIT_SUCCESS; + } + return boost_main(argc, argv); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/CurrentRule.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,32 @@ +// +// 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) +// + +#ifndef CURRENTRULE_H_INCLUDED +#define CURRENTRULE_H_INCLUDED + +#include <string> + + +namespace Vera +{ +namespace Plugins +{ + +class CurrentRule +{ +public: + typedef std::string RuleName; + + static void setCurrentRule(const RuleName & name); + static RuleName getCurrentRule(); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // CURRENTRULE_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Exclusions.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,153 @@ +// +// 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 "Exclusions.h" +#include "Rules.h" +#include "../structures/SourceFiles.h" +#include "tcl/cpptcl-1.1.4/cpptcl.h" +#include <fstream> +#include <sstream> +#include <cstring> +#include <cerrno> +#include <boost/regex.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/foreach.hpp> + +#define foreach BOOST_FOREACH + + +namespace // unnamed +{ + +typedef std::set<Vera::Structures::SourceFiles::FileName> FileNameSet; +typedef std::map<Vera::Plugins::Rules::RuleName, FileNameSet> ExclusionMap; +ExclusionMap exclusions; + +typedef std::vector<boost::regex> RegexList; +RegexList exclusionRegexs; + +} // unnamed namespace + +namespace Vera +{ +namespace Plugins +{ + +void Exclusions::setExclusions(const ExclusionFileName & fileName) +{ + try + { + setExclusionsTcl(fileName); + } + catch (...) + { + setExclusionsRegex(fileName); + } +} + +void Exclusions::setExclusionsRegex(const ExclusionFileName & fileName) +{ + std::ifstream exclusionsFile(fileName.c_str()); + if (exclusionsFile.is_open() == false) + { + std::ostringstream ss; + ss << "Cannot open exclusions file " << fileName << ": " + << strerror(errno); + throw ExclusionError(ss.str()); + } + std::string re; + while (std::getline(exclusionsFile, re)) + { + // don't process empty lines and lines begining with a # + if (re.empty() == false && re.substr(0, 1) != "#") + { + exclusionRegexs.push_back(boost::regex(re)); + } + } + if (exclusionsFile.bad()) + { + throw std::runtime_error( + "Cannot read from " + fileName + ": " + strerror(errno)); + } +} + +void Exclusions::setExclusionsTcl(const ExclusionFileName & fileName) +{ + std::ifstream exclusionsFile(fileName.c_str()); + if (exclusionsFile.is_open() == false) + { + std::ostringstream ss; + ss << "Cannot open exclusions file " << fileName << ": " + << strerror(errno); + throw ExclusionError(ss.str()); + } + + Tcl::interpreter interp; + interp.eval(exclusionsFile); + if (exclusionsFile.bad()) + { + throw std::runtime_error( + "Cannot read from " + fileName + ": " + strerror(errno)); + } + + const Tcl::object ruleNames = interp.eval("array names ruleExclusions"); + const size_t ruleNamesLength = ruleNames.length(interp); + for (size_t i = 0; i != ruleNamesLength; ++i) + { + const std::string ruleName = ruleNames.at(interp, i).get(); + + const Tcl::object exceptionList = interp.eval("set ruleExclusions(" + ruleName + ")"); + const size_t exceptionListLength = exceptionList.length(interp); + + FileNameSet files; + for (size_t j = 0; j != exceptionListLength; ++j) + { + const Structures::SourceFiles::FileName file = exceptionList.at(interp, j).get(); + files.insert(file); + } + + exclusions[ruleName] = files; + } +} + +bool Exclusions::isExcluded(const Structures::SourceFiles::FileName & name, + int lineNumber, const Rules::RuleName & currentRule, const std::string & msg) +{ + std::string fmsg = name + ":" + boost::lexical_cast<std::string>(lineNumber) + + ": " + currentRule + ": " + msg; + foreach(boost::regex const& re, exclusionRegexs) + { + if (boost::regex_search(fmsg, re)) + { + return true; + } + } + return false; +} + +bool Exclusions::isExcluded(const Structures::SourceFiles::FileName & name) +{ + const Rules::RuleName currentRule = Rules::getCurrentRule(); + + const ExclusionMap::const_iterator eit = exclusions.find(currentRule); + if (eit != exclusions.end()) + { + const FileNameSet & files = eit->second; + + const FileNameSet::const_iterator fit = + files.find(name.substr(name.find_last_of("\\/") + 1)); + return fit != files.end(); + } + else + { + return false; + } +} + +} + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Exclusions.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,46 @@ +// +// 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) +// + +#ifndef EXCLUSIONS_H_INCLUDED +#define EXCLUSIONS_H_INCLUDED + +#include <string> +#include "../structures/SourceFiles.h" +#include "Rules.h" +#include <stdexcept> + + +namespace Vera +{ +namespace Plugins +{ + +class ExclusionError : public std::runtime_error +{ +public: + ExclusionError(const std::string & msg) : std::runtime_error(msg) {} +}; + +class Exclusions +{ +public: + typedef std::string ExclusionFileName; + + static void setExclusions(const ExclusionFileName & name); + static void setExclusionsTcl(const ExclusionFileName & name); + static void setExclusionsRegex(const ExclusionFileName & name); + + static bool isExcluded(const Structures::SourceFiles::FileName & name); + static bool isExcluded(const Structures::SourceFiles::FileName & name, + int lineNumber, const Rules::RuleName & currentRule, const std::string & msg); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // EXCLUSIONS_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Interpreter.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,109 @@ +// +// 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 "Interpreter.h" +#include "Exclusions.h" +#include "Reports.h" +#include "Parameters.h" +#include "../structures/SourceFiles.h" +#include "../structures/SourceLines.h" +#include "../structures/Tokens.h" +#include <fstream> +#include <iterator> +#include <boost/lexical_cast.hpp> +#include <boost/filesystem.hpp> +#include <boost/algorithm/string/predicate.hpp> + +#include "tcl/TclInterpreter.h" +#ifdef VERA_PYTHON +#include "python/PythonInterpreter.h" +#endif +#ifdef VERA_LUA +#include "lua/LuaInterpreter.h" +#endif + +namespace Vera +{ +namespace Plugins +{ + +void Interpreter::execute(const DirectoryName & root, + ScriptType type, const ScriptName & name) +{ + std::string scriptDir = root + "/scripts/"; + std::string scriptDir2 = root + "/"; + switch (type) + { + case rule: + scriptDir += "rules/"; + scriptDir2 += "rules/"; + break; + case transformation: + scriptDir += "transformations/"; + scriptDir2 += "transformations/"; + break; + } + + // first look at tcl rules + std::string tclName = name; + if (boost::algorithm::ends_with(tclName, ".tcl") == false) + { + tclName += ".tcl"; + } + if (boost::filesystem::exists(scriptDir + tclName)) + { + TclInterpreter::execute(scriptDir + tclName); + return; + } + else if (boost::filesystem::exists(scriptDir2 + tclName)) + { + TclInterpreter::execute(scriptDir2 + tclName); + return; + } +#ifdef VERA_PYTHON + // then python + std::string pyName = name; + if (boost::algorithm::ends_with(pyName, ".py") == false) + { + pyName += ".py"; + } + if (boost::filesystem::exists(scriptDir + pyName)) + { + PythonInterpreter::execute(scriptDir + pyName); + return; + } + else if (boost::filesystem::exists(scriptDir2 + pyName)) + { + PythonInterpreter::execute(scriptDir2 + pyName); + return; + } +#endif +#ifdef VERA_LUA + // then lua + std::string luaName = name; + if (boost::algorithm::ends_with(luaName, ".lua") == false) + { + luaName += ".lua"; + } + if (boost::filesystem::exists(scriptDir + luaName)) + { + LuaInterpreter::execute(scriptDir + luaName); + return; + } + else if (boost::filesystem::exists(scriptDir2 + luaName)) + { + LuaInterpreter::execute(scriptDir2 + luaName); + return; + } +#endif + std::ostringstream ss; + ss << "cannot open script " << name; + throw ScriptError(ss.str()); +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Interpreter.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,43 @@ +// +// 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) +// + +#ifndef INTERPRETER_H_INCLUDED +#define INTERPRETER_H_INCLUDED + +#include <stdexcept> + + +namespace Vera +{ +namespace Plugins +{ + + +class ScriptError : public std::runtime_error +{ +public: + ScriptError(const std::string & msg) : std::runtime_error(msg) {} +}; + + +class Interpreter +{ +public: + enum ScriptType { rule, transformation }; + + typedef std::string DirectoryName; + typedef std::string ScriptName; + + static void execute(const DirectoryName & root, + ScriptType type, const ScriptName & name); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // INTERPRETER_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Parameters.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,100 @@ +// +// 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 "Parameters.h" +#include <fstream> +#include <sstream> +#include <map> +#include <cstring> +#include <cerrno> + + +namespace // unnamed +{ + +typedef std::map<Vera::Plugins::Parameters::ParamName, Vera::Plugins::Parameters::ParamValue> + ParametersCollection; + +ParametersCollection parameters_; + +} // unnamed namespace + +namespace Vera +{ +namespace Plugins +{ + +void Parameters::set(const ParamAssoc & assoc) +{ + std::string::size_type pos = assoc.find("="); + if (pos != std::string::npos) + { + ParamName name = assoc.substr(0, pos); + ParamValue value = assoc.substr(pos + 1); + + parameters_[name] = value; + } + else + { + std::ostringstream ss; + ss << "Invalid parameter association: " << assoc; + throw ParametersError(ss.str()); + } +} + + +Parameters::ParamValue Parameters::get(const ParamName & name, const ParamValue & defaultValue) +{ + ParametersCollection::iterator it = parameters_.find(name); + if (it != parameters_.end()) + { + return it->second; + } + else + { + return defaultValue; + } +} + + +void Parameters::readFromFile(const FileName & name) +{ + std::ifstream file(name.c_str()); + if (file.is_open() == false) + { + std::ostringstream ss; + ss << "Cannot open parameters file " << name << ": " + << strerror(errno); + throw ParametersError(ss.str()); + } + + std::string line; + int lineNumber = 0; + while (getline(file, line)) + { + ++lineNumber; + + if (line.empty()) + { + continue; + } + + if (line[0] != '#') + { + set(line); + } + } + if (file.bad()) + { + throw std::runtime_error( + "Cannot read from " + name + ": " + strerror(errno)); + } + file.close(); +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Parameters.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,46 @@ +// +// 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) +// + +#ifndef PARAMETERS_H_INCLUDED +#define PARAMETERS_H_INCLUDED + +#include <string> +#include <stdexcept> + + +namespace Vera +{ +namespace Plugins +{ + + +class ParametersError : public std::runtime_error +{ +public: + ParametersError(const std::string & msg) : std::runtime_error(msg) {} +}; + + +class Parameters +{ +public: + typedef std::string ParamName; + typedef std::string ParamValue; + typedef std::string ParamAssoc; + typedef std::string FileName; + + static void set(const ParamAssoc & assoc); + static void readFromFile(const FileName & name); + + static ParamValue get(const ParamName & name, const ParamValue & defaultValue); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // PARAMETERS_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Profiles.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,145 @@ +// +// 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 "Profiles.h" +#include "RootDirectory.h" +#include "tcl/cpptcl-1.1.4/cpptcl.h" +#include <set> +#include <map> +#include <fstream> +#include <sstream> +#include <algorithm> +#include <cstring> +#include <cerrno> + + +namespace Vera +{ +namespace Plugins +{ + + +Profiles::RuleNameCollection Profiles::getListOfScriptNamesTcl( + const Vera::Plugins::Profiles::ProfileName & profile) +{ + RuleNameCollection allRules; + + // name of the profile is also the name of the profile file + + const Vera::Plugins::RootDirectory::DirectoryName veraRoot = + Vera::Plugins::RootDirectory::getRootDirectory(); + + std::string fileName(veraRoot + "/profiles/"); + fileName += profile; + + std::ifstream profileFile(fileName.c_str()); + if (profileFile.is_open() == false) + { + std::ostringstream ss; + ss << "Cannot open profile description for profile '" << profile + << "': "<< strerror(errno); + throw Vera::Plugins::ProfileError(ss.str()); + } + + Tcl::interpreter interp; + interp.eval(profileFile); + if (profileFile.bad()) + { + throw std::runtime_error( + "Cannot read from " + fileName + ": " + strerror(errno)); + } + + const Tcl::object ruleList = interp.eval("set rules"); + + const size_t ruleListLength = ruleList.length(interp); + for (size_t i = 0; i != ruleListLength; ++i) + { + const Vera::Plugins::Rules::RuleName rName = ruleList.at(interp, i).get(); + allRules.push_back(rName); + } + + return allRules; +} + +Profiles::RuleNameCollection Profiles::getListOfScriptNamesKeys( + const Vera::Plugins::Profiles::ProfileName & profile) +{ + RuleNameCollection allRules; + + // name of the profile is also the name of the profile file + + const Vera::Plugins::RootDirectory::DirectoryName veraRoot = + Vera::Plugins::RootDirectory::getRootDirectory(); + + std::string fileName(veraRoot + "/profiles/"); + fileName += profile; + + std::ifstream profileFile(fileName.c_str()); + if (profileFile.is_open() == false) + { + std::ostringstream ss; + ss << "Cannot open profile description for profile '" << profile + << "': "<< strerror(errno); + throw Vera::Plugins::ProfileError(ss.str()); + } + + std::string line; + while (getline(profileFile, line)) + { + if (line.empty() == false && line[0] != '#') + { + std::string::size_type pos = line.find("="); + if (pos != std::string::npos) + { + std::string name = line.substr(0, pos); + std::string value = line.substr(pos + 1); + + if (name == "rule") + { + allRules.push_back(value); + } + } + } + } + + if (profileFile.bad()) + { + throw std::runtime_error( + "Cannot read from " + fileName + ": " + strerror(errno)); + } + profileFile.close(); + + return allRules; +} + +Profiles::RuleNameCollection Profiles::getListOfScriptNames( + const Vera::Plugins::Profiles::ProfileName & profile) +{ + try + { + return getListOfScriptNamesTcl(profile); + } + catch (...) + { + return getListOfScriptNamesKeys(profile); + } +} + +void Profiles::executeProfile(const ProfileName & profile) +{ + const RuleNameCollection scripts = getListOfScriptNames(profile); + + typedef RuleNameCollection::const_iterator iterator; + const iterator end = scripts.end(); + for (iterator it = scripts.begin(); it != end; ++it) + { + Rules::executeRule(*it); + } +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Profiles.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,48 @@ +// +// 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) +// + +#ifndef PROFILES_H_INCLUDED +#define PROFILES_H_INCLUDED + +#include <string> +#include <stdexcept> +#include <vector> +#include "Rules.h" + + +namespace Vera +{ +namespace Plugins +{ + + +class ProfileError : public std::runtime_error +{ +public: + ProfileError(const std::string & msg) : std::runtime_error(msg) {} +}; + +class Profiles +{ +public: + typedef std::string ProfileName; + typedef std::vector<Vera::Plugins::Rules::RuleName> RuleNameCollection; + + static void executeProfile(const ProfileName & name); + static RuleNameCollection getListOfScriptNamesTcl( + const Vera::Plugins::Profiles::ProfileName & profile); + static RuleNameCollection getListOfScriptNamesKeys( + const Vera::Plugins::Profiles::ProfileName & profile); + static RuleNameCollection getListOfScriptNames( + const Vera::Plugins::Profiles::ProfileName & profile); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // PROFILES_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Reports.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,378 @@ +// +// 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 "Reports.h" +#include "Rules.h" +#include "Exclusions.h" +#include <sstream> +#include <map> +#include <utility> +#include <stdexcept> +#include <boost/algorithm/string/replace.hpp> + + +namespace // unnamed +{ + +// for a single report +typedef std::pair<Vera::Plugins::Rules::RuleName, Vera::Plugins::Reports::Message> SingleReport; + +// for a single file (line number -> single report) +typedef std::multimap<int, SingleReport> FileMessagesCollection; + +// for all reports +typedef std::map<Vera::Plugins::Reports::FileName, FileMessagesCollection> MessagesCollection; + +MessagesCollection messages_; + +bool showRules_; +bool vcFormat_; +bool xmlReport_; +std::string prefix_; + +} // unnamed namespace + +namespace Vera +{ +namespace Plugins +{ + +void Reports::setShowRules(bool show) +{ + showRules_ = show; +} + +void Reports::setXMLReport(bool xmlReport) +{ + xmlReport_ = xmlReport; +} + +void Reports::setVCFormat(bool vc) +{ + vcFormat_ = vc; +} + +void Reports::setPrefix(std::string prefix) +{ + prefix_ = prefix; +} + +int Reports::count() +{ + return messages_.size(); +} + +void Reports::add(const FileName & name, int lineNumber, const Message & msg) +{ + if (lineNumber <= 0) + { + std::ostringstream ss; + ss << "Line number out of range: " << lineNumber; + throw std::out_of_range(ss.str()); + } + const Rules::RuleName currentRule = Rules::getCurrentRule(); + if (Exclusions::isExcluded(name, lineNumber, currentRule, msg) == false) + { + messages_[name].insert(make_pair(lineNumber, make_pair(currentRule, msg))); + } +} + +void Reports::internal(const FileName & name, int lineNumber, const Message & msg) +{ + const Rules::RuleName currentRule = "vera++ internal"; + + messages_[name].insert(make_pair(lineNumber, make_pair(currentRule, msg))); +} + +void Reports::dumpAll(std::ostream & os, bool omitDuplicates) +{ + if (xmlReport_) + { + dumpAllXML(os, omitDuplicates); + } + else + { + dumpAllNormal(os, omitDuplicates); + } +} + +void Reports::dumpAllNormal(std::ostream & os, bool omitDuplicates) +{ + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + if (showRules_) + { + if (vcFormat_) + { + os << name << '(' << lineNumber << ") : " + << '(' << rule << ") " << msg << '\n'; + } + else + { + os << name << ':' << lineNumber << ": " + << '(' << rule << ") " << msg << '\n'; + } + } + else + { + if (vcFormat_) + { + os << name << '(' << lineNumber << ") : " + << msg << '\n'; + } + else + { + os << name << ':' << lineNumber << ": " + << msg << '\n'; + } + } + + lastLineNumber = lineNumber; + lastReport = report; + } + } + } +} + +void Reports::dumpAllXML(std::ostream & os, bool omitDuplicates) +{ + writeXml(os, omitDuplicates); +} + +void Reports::writeStd(std::ostream & os, bool omitDuplicates) +{ + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + os << name; + os << ':' << lineNumber << ":"; + if (prefix_ != "") + { + os << " " << prefix_; + } + if (showRules_) + { + os << " " << rule; + } + if (showRules_ || prefix_ != "") + { + os << ":"; + } + os << " " << msg << std::endl; + + lastLineNumber = lineNumber; + lastReport = report; + } + } + } +} + +void Reports::writeVc(std::ostream & os, bool omitDuplicates) +{ + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + os << name; + os << '(' << lineNumber << "):"; + if (prefix_ != "") + { + os << " " << prefix_; + } + if (showRules_) + { + os << " " << rule; + } + if (showRules_ || prefix_ != "") + { + os << ":"; + } + os << " " << msg << std::endl; + + lastLineNumber = lineNumber; + lastReport = report; + } + } + } +} + +void Reports::writeXml(std::ostream & os, bool omitDuplicates) +{ + os<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; + os << "<vera>\n"; + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + os << " <file name=\"" << name << "\">\n"; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + if (showRules_) + { + os << " <report rule=\"" << xmlEscape(rule) + << "\" line=\"" << lineNumber + << "\">![CDATA[" << msg << "]]</report>\n"; + } + else + { + os << " <report line=\"" << lineNumber + << "\">![CDATA[" << msg << "]]</report>\n"; + } + + lastLineNumber = lineNumber; + lastReport = report; + } + } + + os << " </file>\n"; + } + + os << "</vera>\n"; +} + +void Reports::writeCheckStyle(std::ostream & os, bool omitDuplicates) +{ + std::string severity = prefix_; + if (severity == "") + { + severity = "info"; + } + os<< "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; + os << "<checkstyle version=\"5.0\">\n"; + + for (MessagesCollection::iterator it = messages_.begin(), end = messages_.end(); + it != end; ++it) + { + const FileName & name = it->first; + + os << " <file name=\"" << name << "\">\n"; + + FileMessagesCollection & fileMessages = it->second; + + FileMessagesCollection::iterator fit = fileMessages.begin(); + FileMessagesCollection::iterator fend = fileMessages.end(); + + int lastLineNumber = 0; + SingleReport lastReport; + for ( ; fit != fend; ++fit) + { + int lineNumber = fit->first; + const SingleReport & report = fit->second; + const Rules::RuleName & rule = report.first; + const Message & msg = report.second; + + if (omitDuplicates == false || + lineNumber != lastLineNumber || report != lastReport) + { + os << " <error source=\"" << xmlEscape(rule) + << "\" severity=\"" << xmlEscape(severity) + << "\" line=\"" << lineNumber + << "\" message=\"" << xmlEscape(msg) + << "\" />\n"; + + lastLineNumber = lineNumber; + lastReport = report; + } + } + + os << " </file>\n"; + } + + os << "</checkstyle>\n"; +} + +std::string Reports::xmlEscape(const std::string & msg) +{ + std::string res = msg; + boost::algorithm::replace_all(res, "&", "&"); + boost::algorithm::replace_all(res, "\"", """); + boost::algorithm::replace_all(res, "\'", "'"); + boost::algorithm::replace_all(res, "<", "<"); + boost::algorithm::replace_all(res, ">", ">"); + return res; +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Reports.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,56 @@ +// +// 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) +// + +#ifndef REPORTS_H_INCLUDED +#define REPORTS_H_INCLUDED + +#include "Reports.h" +#include <string> +#include <ostream> + + +namespace Vera +{ +namespace Plugins +{ + + +class Reports +{ +public: + typedef std::string FileName; + typedef std::string Message; + + static void setShowRules(bool show); + static void setVCFormat(bool vc); + static void setXMLReport(bool xmlReport); + static void setPrefix(std::string prefix); + + static int count(); + + static void add(const FileName & name, int lineNumber, const Message & msg); + static void internal(const FileName & name, int lineNumber, + const Message & msg); + + static void dumpAll(std::ostream & os, bool omitDuplicates); + + static void writeStd(std::ostream & os, bool omitDuplicates); + static void writeVc(std::ostream & os, bool omitDuplicates); + static void writeXml(std::ostream & os, bool omitDuplicates); + static void writeCheckStyle(std::ostream & os, bool omitDuplicates); + +private: + static void dumpAllNormal(std::ostream & os, bool omitDuplicates); + static void dumpAllXML(std::ostream & os, bool omitDuplicates); + static std::string xmlEscape(const std::string & msg); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // REPORTS_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/RootDirectory.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,34 @@ +// +// 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 "RootDirectory.h" + + +namespace // unnamed +{ + +Vera::Plugins::RootDirectory::DirectoryName root_; + +} // unnamed namespace + +namespace Vera +{ +namespace Plugins +{ + +void RootDirectory::setRootDirectory(const DirectoryName & name) +{ + root_ = name; +} + +RootDirectory::DirectoryName RootDirectory::getRootDirectory() +{ + return root_; +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/RootDirectory.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,34 @@ +// +// 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) +// + +#ifndef ROOTDIRECTORY_H_INCLUDED +#define ROOTDIRECTORY_H_INCLUDED + +#include <string> + + +namespace Vera +{ +namespace Plugins +{ + + +class RootDirectory +{ +public: + typedef std::string DirectoryName; + + static void setRootDirectory(const DirectoryName & name); + + static DirectoryName getRootDirectory(); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // ROOTDIRECTORY_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Rules.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,40 @@ +// +// 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 "Rules.h" +#include "RootDirectory.h" +#include "Interpreter.h" + + +namespace // unnamed +{ + +Vera::Plugins::Rules::RuleName currentRule_; + +} // unnamed namespace + +namespace Vera +{ +namespace Plugins +{ + +void Rules::executeRule(const RuleName & name) +{ + currentRule_ = name; + + const Vera::Plugins::RootDirectory::DirectoryName veraRoot = + Vera::Plugins::RootDirectory::getRootDirectory(); + Interpreter::execute(veraRoot, Interpreter::rule, name); +} + +Rules::RuleName Rules::getCurrentRule() +{ + return currentRule_; +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Rules.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,33 @@ +// +// 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) +// + +#ifndef RULES_H_INCLUDED +#define RULES_H_INCLUDED + +#include <string> + + +namespace Vera +{ +namespace Plugins +{ + +class Rules +{ +public: + typedef std::string RuleName; + + static void executeRule(const RuleName & name); + + static RuleName getCurrentRule(); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // RULES_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Transformations.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,24 @@ +// +// 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 "Transformations.h" +#include "RootDirectory.h" +#include "Interpreter.h" + +namespace Vera +{ +namespace Plugins +{ + +void Transformations::executeTransformation(const TransformationName & name) +{ + const RootDirectory::DirectoryName veraRoot = RootDirectory::getRootDirectory(); + Interpreter::execute(veraRoot, Interpreter::transformation, name); +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/Transformations.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,32 @@ +// +// 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) +// + +#ifndef TRANSFORMATIONS_H_INCLUDED +#define TRANSFORMATIONS_H_INCLUDED + +#include <string> + + +namespace Vera +{ +namespace Plugins +{ + + +class Transformations +{ +public: + typedef std::string TransformationName; + + static void executeTransformation(const TransformationName & name); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // TRANSFORMATIONS_H_INCLUDED
--- /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) + ")"); + } +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/TclInterpreter.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,34 @@ +// +// 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) +// + +#ifndef TCL_INTERPRETER_H_INCLUDED +#define TCL_INTERPRETER_H_INCLUDED + +#include <stdexcept> +#include "../Interpreter.h" + + +namespace Vera +{ +namespace Plugins +{ + +class TclInterpreter +{ +public: + typedef Interpreter::ScriptType ScriptType; + typedef std::string DirectoryName; + typedef std::string ScriptName; + + static void execute(const ScriptName & name); +}; + +} // namespace Plugins + +} // namespace Vera + +#endif // TCL_INTERPRETER_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/cpptcl.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,1112 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#include "cpptcl.h" +#include <map> +#include <sstream> +#include <iterator> + +namespace Tcl +{ +namespace details +{ + +result::result(Tcl_Interp *interp) : interp_(interp) {} + +result::operator bool() const +{ + Tcl_Obj *obj = Tcl_GetObjResult(interp_); + + int val, cc; + cc = Tcl_GetBooleanFromObj(interp_, obj, &val); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } + + return val != 0; +} + +result::operator double() const +{ + Tcl_Obj *obj = Tcl_GetObjResult(interp_); + + double val; + int cc = Tcl_GetDoubleFromObj(interp_, obj, &val); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } + + return val; +} + +result::operator int() const +{ + Tcl_Obj *obj = Tcl_GetObjResult(interp_); + + int val, cc; + cc = Tcl_GetIntFromObj(interp_, obj, &val); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } + + return val; +} + +result::operator long() const +{ + Tcl_Obj *obj = Tcl_GetObjResult(interp_); + + long val; + int cc; + cc = Tcl_GetLongFromObj(interp_, obj, &val); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } + + return val; +} + +result::operator std::string() const +{ + Tcl_Obj *obj = Tcl_GetObjResult(interp_); + return Tcl_GetString(obj); +} + +result::operator Tcl::object() const +{ + return object(Tcl_GetObjResult(interp_)); +} + +void set_result(Tcl_Interp *interp, bool b) +{ + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(b)); +} + +void set_result(Tcl_Interp *interp, int i) +{ + Tcl_SetObjResult(interp, Tcl_NewIntObj(i)); +} + +void set_result(Tcl_Interp *interp, long i) +{ + Tcl_SetObjResult(interp, Tcl_NewLongObj(i)); +} + +void set_result(Tcl_Interp *interp, double d) +{ + Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d)); +} + +void set_result(Tcl_Interp *interp, std::string const &s) +{ + Tcl_SetObjResult(interp, + Tcl_NewStringObj(s.data(), static_cast<int>(s.size()))); +} + +void set_result(Tcl_Interp *interp, void *p) +{ + std::ostringstream ss; + ss << 'p' << p; + std::string s(ss.str()); + + Tcl_SetObjResult(interp, + Tcl_NewStringObj(s.data(), static_cast<int>(s.size()))); +} + +void set_result(Tcl_Interp *interp, object const &o) +{ + Tcl_SetObjResult(interp, o.get_object()); +} + + +void check_params_no(int objc, int required) +{ + if (objc < required) + { + throw tcl_error("Too few arguments."); + } +} + +object get_var_params(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + int from, policies const &pol) +{ + object o; + if (pol.variadic_) + { + check_params_no(objc, from); + o.assign(objv + from, objv + objc); + } + else + { + check_params_no(objc, from + 1); + o.assign(objv[from]); + } + + o.set_interp(interp); + + return o; +} + +} + +namespace // unnamed +{ + +// map of polymorphic callbacks +typedef std::map<std::string, boost::shared_ptr<Tcl::details::callback_base> > callback_interp_map; +typedef std::map<Tcl_Interp *, callback_interp_map> callback_map; + +callback_map callbacks; +callback_map constructors; + +// map of call policies +typedef std::map<std::string, policies> policies_interp_map; +typedef std::map<Tcl_Interp *, policies_interp_map> policies_map; + +policies_map call_policies; + +// map of object handlers +typedef std::map<std::string, boost::shared_ptr<Tcl::details::class_handler_base> > + class_interp_map; +typedef std::map<Tcl_Interp *, class_interp_map> class_handlers_map; + +class_handlers_map class_handlers; + + +// helper for finding call policies - returns true when found +bool find_policies(Tcl_Interp *interp, std::string const &cmdName, + policies_interp_map::iterator &piti) +{ + policies_map::iterator pit = call_policies.find(interp); + if (pit == call_policies.end()) + { + return false; + } + + piti = pit->second.find(cmdName); + return piti != pit->second.end(); +} + +extern "C" +int object_handler(ClientData cd, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[]); + +// helper function for post-processing call policies +// for both free functions (isMethod == false) +// and class methods (isMethod == true) +void post_process_policies(Tcl_Interp *interp, policies &pol, + Tcl_Obj * CONST objv[], bool isMethod) +{ + // check if it is a factory + if (pol.factory_.empty() == false) + { + class_handlers_map::iterator it = class_handlers.find(interp); + if (it == class_handlers.end()) + { + throw tcl_error( + "Factory was registered for unknown class."); + } + + class_interp_map::iterator oit = it->second.find(pol.factory_); + if (oit == it->second.end()) + { + throw tcl_error( + "Factory was registered for unknown class."); + } + + Tcl::details::class_handler_base *chb = oit->second.get(); + + // register a new command for the object returned + // by this factory function + // if everything went OK, the result is the address of the + // new object in the 'pXXX' form + // - the new command will be created with this name + + Tcl_CreateObjCommand(interp, + Tcl_GetString(Tcl_GetObjResult(interp)), + object_handler, static_cast<ClientData>(chb), 0); + } + + // process all declared sinks + // - unregister all object commands that envelopes the pointers + for (std::vector<int>::iterator s = pol.sinks_.begin(); + s != pol.sinks_.end(); ++s) + { + if (isMethod == false) + { + // example: if there is a declared sink at parameter 3, + // and the Tcl command was: + // % fun par1 par2 PAR3 par4 + // then the index 3 correctly points into the objv array + + int index = *s; + Tcl_DeleteCommand(interp, Tcl_GetString(objv[index])); + } + else + { + // example: if there is a declared sink at parameter 3, + // and the Tcl command was: + // % $p method par1 par2 PAR3 par4 + // then the index 3 needs to be incremented + // in order correctly point into the 4th index of objv array + + int index = *s + 1; + Tcl_DeleteCommand(interp, Tcl_GetString(objv[index])); + } + } +} + +// actual functions handling various callbacks + +// generic callback handler +extern "C" +int callback_handler(ClientData, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[]) +{ + callback_map::iterator it = callbacks.find(interp); + if (it == callbacks.end()) + { + char msg[] = "Trying to invoke non-existent callback (wrong interpreter?)"; + Tcl_SetResult(interp, + msg, + TCL_STATIC); + return TCL_ERROR; + } + + std::string cmdName(Tcl_GetString(objv[0])); + callback_interp_map::iterator iti = it->second.find(cmdName); + if (iti == it->second.end()) + { + char msg[] = "Trying to invoke non-existent callback (wrong cmd name?)"; + Tcl_SetResult(interp, + msg, + TCL_STATIC); + return TCL_ERROR; + } + + policies_map::iterator pit = call_policies.find(interp); + if (pit == call_policies.end()) + { + char msg[] = "Trying to invoke callback with no known policies"; + Tcl_SetResult(interp, + msg, + TCL_STATIC); + return TCL_ERROR; + } + + policies_interp_map::iterator piti; + if (find_policies(interp, cmdName, piti) == false) + { + char msg[] = "Trying to invoke callback with no known policies"; + Tcl_SetResult(interp, + msg, + TCL_STATIC); + return TCL_ERROR; + } + + policies &pol = piti->second; + + try + { + iti->second->invoke(interp, objc, objv, pol); + + post_process_policies(interp, pol, objv, false); + } + catch (std::exception const &e) + { + Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE); + return TCL_ERROR; + } + catch (...) + { + char msg[] = "Unknown error."; + Tcl_SetResult(interp, msg, TCL_STATIC); + return TCL_ERROR; + } + + return TCL_OK; +} + +// generic "object" command handler +extern "C" +int object_handler(ClientData cd, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[]) +{ + // here, client data points to the singleton object + // which is responsible for managing commands for + // objects of a given type + + Tcl::details::class_handler_base *chb = + reinterpret_cast<Tcl::details::class_handler_base*>(cd); + + // the command name has the form 'pXXX' where XXX is the address + // of the "this" object + + std::string const str(Tcl_GetString(objv[0])); + std::istringstream ss(str); + char dummy; + void *p; + ss >> dummy >> p; + + try + { + std::string methodName(Tcl_GetString(objv[1])); + policies &pol = chb->get_policies(methodName); + + chb->invoke(p, interp, objc, objv, pol); + + post_process_policies(interp, pol, objv, true); + } + catch (std::exception const &e) + { + Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE); + return TCL_ERROR; + } + catch (...) + { + char msg[] = "Unknown error."; + Tcl_SetResult(interp, msg, TCL_STATIC); + return TCL_ERROR; + } + + return TCL_OK; +} + +// generic "constructor" command +extern "C" +int constructor_handler(ClientData cd, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[]) +{ + // here, client data points to the singleton object + // which is responsible for managing commands for + // objects of a given type + + Tcl::details::class_handler_base *chb = + reinterpret_cast<Tcl::details::class_handler_base*>(cd); + + callback_map::iterator it = constructors.find(interp); + if (it == constructors.end()) + { + char msg[] = "Trying to invoke non-existent callback (wrong interpreter?)"; + Tcl_SetResult(interp, + msg, + TCL_STATIC); + return TCL_ERROR; + } + + std::string className(Tcl_GetString(objv[0])); + callback_interp_map::iterator iti = it->second.find(className); + if (iti == it->second.end()) + { + char msg[] = "Trying to invoke non-existent callback (wrong class name?)"; + Tcl_SetResult(interp, + msg, + TCL_STATIC); + return TCL_ERROR; + } + + policies_interp_map::iterator piti; + if (find_policies(interp, className, piti) == false) + { + char msg[] = "Trying to invoke callback with no known policies"; + Tcl_SetResult(interp, + msg, + TCL_STATIC); + return TCL_ERROR; + } + + policies &pol = piti->second; + + try + { + iti->second->invoke(interp, objc, objv, pol); + + // if everything went OK, the result is the address of the + // new object in the 'pXXX' form + // - we can create a new command with this name + + Tcl_CreateObjCommand(interp, + Tcl_GetString(Tcl_GetObjResult(interp)), + object_handler, static_cast<ClientData>(chb), 0); + } + catch (std::exception const &e) + { + Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE); + return TCL_ERROR; + } + catch (...) + { + char msg[] = "Unknown error."; + Tcl_SetResult(interp, msg, TCL_STATIC); + return TCL_ERROR; + } + + return TCL_OK; +} + +} // unnamed namespace + +Tcl::details::no_init_type no_init; + + +policies & policies::factory(std::string const &name) +{ + factory_ = name; + return *this; +} + +policies & policies::sink(int index) +{ + sinks_.push_back(index); + return *this; +} + +policies & policies::variadic() +{ + variadic_ = true; + return *this; +} + +policies factory(std::string const &name) +{ + return policies().factory(name); +} + +policies sink(int index) +{ + return policies().sink(index); +} + +policies variadic() +{ + return policies().variadic(); +} + + +namespace details +{ + +class_handler_base::class_handler_base() +{ + // default policies for the -delete command + policies_["-delete"] = policies(); +} + +void class_handler_base::register_method(std::string const &name, + boost::shared_ptr<object_cmd_base> ocb, policies const &p) +{ + methods_[name] = ocb; + policies_[name] = p; +} + +policies & class_handler_base::get_policies(std::string const &name) +{ + policies_map_type::iterator it = policies_.find(name); + if (it == policies_.end()) + { + throw tcl_error("Trying to use non-existent policy: " + name); + } + + return it->second; +} +} + +object::object() + : interp_(0) +{ + obj_ = Tcl_NewObj(); + Tcl_IncrRefCount(obj_); +} + +object::object(bool b) + : interp_(0) +{ + obj_ = Tcl_NewBooleanObj(b); + Tcl_IncrRefCount(obj_); +} + +object::object(char const *buf, size_t size) + : interp_(0) +{ + obj_ = Tcl_NewByteArrayObj( + reinterpret_cast<unsigned char const *>(buf), + static_cast<int>(size)); + Tcl_IncrRefCount(obj_); +} + +object::object(double d) + : interp_(0) +{ + obj_ = Tcl_NewDoubleObj(d); + Tcl_IncrRefCount(obj_); +} + +object::object(int i) + : interp_(0) +{ + obj_ = Tcl_NewIntObj(i); + Tcl_IncrRefCount(obj_); +} + +object::object(long ln) + : interp_(0) +{ + obj_ = Tcl_NewLongObj(ln); + Tcl_IncrRefCount(obj_); +} + +object::object(char const *s) + : interp_(0) +{ + obj_ = Tcl_NewStringObj(s, -1); + Tcl_IncrRefCount(obj_); +} + +object::object(std::string const &s) + : interp_(0) +{ + obj_ = Tcl_NewStringObj(s.data(), static_cast<int>(s.size())); + Tcl_IncrRefCount(obj_); +} + +object::object(Tcl_Obj *o, bool shared) + : interp_(0) +{ + init(o, shared); +} + +object::object(object const &other, bool shared) + : interp_(other.get_interp()) +{ + init(other.obj_, shared); +} + +void object::init(Tcl_Obj *o, bool shared) +{ + if (shared) + { + obj_ = o; + } + else + { + obj_ = Tcl_DuplicateObj(o); + } + Tcl_IncrRefCount(obj_); +} + +object::~object() +{ + Tcl_DecrRefCount(obj_); +} + +object & object::assign(bool b) +{ + Tcl_SetBooleanObj(obj_, b); + return *this; +} + +object & object::resize(size_t size) +{ + Tcl_SetByteArrayLength(obj_, static_cast<int>(size)); + return *this; +} + +object & object::assign(char const *buf, size_t size) +{ + Tcl_SetByteArrayObj(obj_, + reinterpret_cast<unsigned char const *>(buf), + static_cast<int>(size)); + return *this; +} + +object & object::assign(double d) +{ + Tcl_SetDoubleObj(obj_, d); + return *this; +} + +object & object::assign(int i) +{ + Tcl_SetIntObj(obj_, i); + return *this; +} + +object & object::assign(long ln) +{ + Tcl_SetLongObj(obj_, ln); + return *this; +} + +object & object::assign(char const *s) +{ + Tcl_SetStringObj(obj_, s, -1); + return *this; +} + +object & object::assign(std::string const &s) +{ + Tcl_SetStringObj(obj_, s.data(), static_cast<int>(s.size())); + return *this; +} + +object & object::assign(object const &other) +{ + object(other).swap(*this); + return *this; +} + +object & object::assign(Tcl_Obj *o) +{ + object(o).swap(*this); + return *this; +} + +object & object::swap(object &other) +{ + std::swap(obj_, other.obj_); + std::swap(interp_, other.interp_); + return *this; +} + +template <> +bool object::get<bool>(interpreter &i) const +{ + int retVal; + int res = Tcl_GetBooleanFromObj(i.get(), obj_, &retVal); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return retVal != 0; +} + +template <> +std::vector<char> object::get<std::vector<char> >(interpreter &) const +{ + size_t size; + char const *buf = get(size); + return std::vector<char>(buf, buf + size); +} + +template <> +double object::get<double>(interpreter &i) const +{ + double retVal; + int res = Tcl_GetDoubleFromObj(i.get(), obj_, &retVal); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return retVal; +} + +template <> +int object::get<int>(interpreter &i) const +{ + int retVal; + + int res = Tcl_GetIntFromObj(i.get(), obj_, &retVal); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return retVal; +} + +template <> +long object::get<long>(interpreter &i) const +{ + long retVal; + int res = Tcl_GetLongFromObj(i.get(), obj_, &retVal); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return retVal; +} + +template <> +char const * object::get<char const *>(interpreter &) const +{ + return get(); +} + +template <> +std::string object::get<std::string>(interpreter &) const +{ + int len; + char const *buf = Tcl_GetStringFromObj(obj_, &len); + return std::string(buf, buf + len); +} + +char const * object::get() const +{ + return Tcl_GetString(obj_); +} + +char const * object::get(size_t &size) const +{ + int len; + unsigned char *buf = Tcl_GetByteArrayFromObj(obj_, &len); + size = len; + return const_cast<char const *>(reinterpret_cast<char *>(buf)); +} + +size_t object::length(interpreter &i) const +{ + int len; + int res = Tcl_ListObjLength(i.get(), obj_, &len); + + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return static_cast<size_t>(len); +} + +object object::at(interpreter &i, size_t index) const +{ + Tcl_Obj *o; + int res = Tcl_ListObjIndex(i.get(), obj_, static_cast<int>(index), &o); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + if (o == NULL) + { + throw tcl_error("Index out of range."); + } + + return object(o); +} + +object & object::append(interpreter &i, object const &o) +{ + int res = Tcl_ListObjAppendElement(i.get(), obj_, o.obj_); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return *this; +} + +object & object::append_list(interpreter &i, object const &o) +{ + int res = Tcl_ListObjAppendList(i.get(), obj_, o.obj_); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return *this; +} + +object & object::replace(interpreter &i, size_t index, size_t count, + object const &o) +{ + int res = Tcl_ListObjReplace(i.get(), obj_, + static_cast<int>(index), static_cast<int>(count), + 1, &(o.obj_)); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return *this; +} + +object & object::replace_list(interpreter &i, size_t index, size_t count, + object const &o) +{ + int objc; + Tcl_Obj **objv; + + int res = Tcl_ListObjGetElements(i.get(), o.obj_, &objc, &objv); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + res = Tcl_ListObjReplace(i.get(), obj_, + static_cast<int>(index), static_cast<int>(count), + objc, objv); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return *this; +} + +void object::set_interp(Tcl_Interp *interp) +{ + interp_ = interp; +} + +Tcl_Interp * object::get_interp() const +{ + return interp_; +} + + +interpreter::interpreter() +{ + interp_ = Tcl_CreateInterp(); + owner_ = true; +} + +interpreter::interpreter(Tcl_Interp *interp, bool owner) +{ + interp_ = interp; + owner_ = owner; +} + +interpreter::~interpreter() +{ + if (owner_) + { + // clear all callback info belonging to this interpreter + clear_definitions(interp_); + + Tcl_DeleteInterp(interp_); + } +} + +void interpreter::make_safe() +{ + int cc = Tcl_MakeSafe(interp_); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } +} + +details::result interpreter::eval(std::string const &script) +{ + int cc = Tcl_Eval(interp_, script.c_str()); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } + + return details::result(interp_); +} + +details::result interpreter::eval(std::istream &s) +{ + std::string str( + std::istreambuf_iterator<char>(s.rdbuf()), + std::istreambuf_iterator<char>() + ); + return eval(str); +} + +details::result interpreter::eval(object const &o) +{ + int cc = Tcl_EvalObjEx(interp_, o.get_object(), 0); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } + + return details::result(interp_); +} + +void interpreter::pkg_provide(std::string const &name, std::string const &version) +{ + int cc = Tcl_PkgProvide(interp_, name.c_str(), version.c_str()); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } +} + +void interpreter::create_alias(std::string const &cmd, + interpreter &targetInterp, std::string const &targetCmd) +{ + int cc = Tcl_CreateAlias(interp_, cmd.c_str(), + targetInterp.interp_, targetCmd.c_str(), 0, 0); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } +} + +void interpreter::clear_definitions(Tcl_Interp *interp) +{ + // delete all callbacks that were registered for given interpreter + + { + callback_map::iterator it = callbacks.find(interp); + if (it == callbacks.end()) + { + // no callbacks defined for this interpreter + return; + } + + callback_interp_map &imap = it->second; + for (callback_interp_map::iterator it2 = imap.begin(); + it2 != imap.end(); ++it2) + { + Tcl_DeleteCommand(interp, it2->first.c_str()); + } + + callbacks.erase(interp); + } + + // delete all constructors + + { + callback_map::iterator it = constructors.find(interp); + if (it == constructors.end()) + { + // no callbacks defined for this interpreter + return; + } + + callback_interp_map &imap = it->second; + for (callback_interp_map::iterator it2 = imap.begin(); + it2 != imap.end(); ++it2) + { + Tcl_DeleteCommand(interp, it2->first.c_str()); + } + + callbacks.erase(interp); + } + + // delete all call policies + + call_policies.erase(interp); + + // delete all object handlers + // (we have to assume that all living objects were destroyed, + // otherwise Bad Things will happen) + + class_handlers.erase(interp); +} + +void interpreter::add_function(std::string const &name, + boost::shared_ptr<details::callback_base> cb, policies const &p) +{ + Tcl_CreateObjCommand(interp_, name.c_str(), + callback_handler, 0, 0); + + callbacks[interp_][name] = cb; + call_policies[interp_][name] = p; +} + +void interpreter::add_class(std::string const &name, + boost::shared_ptr<details::class_handler_base> chb) +{ + class_handlers[interp_][name] = chb; +} + +void interpreter::add_constructor(std::string const &name, + boost::shared_ptr<details::class_handler_base> chb, + boost::shared_ptr<details::callback_base> cb, + policies const &p) +{ + Tcl_CreateObjCommand(interp_, name.c_str(), + constructor_handler, static_cast<ClientData>(chb.get()), 0); + + constructors[interp_][name] = cb; + call_policies[interp_][name] = p; +} + +namespace details +{ + +int tcl_cast<int>::from(Tcl_Interp *interp, Tcl_Obj *obj) +{ + int res; + int cc = Tcl_GetIntFromObj(interp, obj, &res); + if (cc != TCL_OK) + { + std::ostringstream ss; + ss << "Can't cast '" << Tcl_GetString(obj) << "' to int"; + throw tcl_error(ss.str()); + } + + return res; +} + +long tcl_cast<long>::from(Tcl_Interp *interp, Tcl_Obj *obj) +{ + long res; + int cc = Tcl_GetLongFromObj(interp, obj, &res); + if (cc != TCL_OK) + { + std::ostringstream ss; + ss << "Can't cast '" << Tcl_GetString(obj) << "' to long"; + throw tcl_error(ss.str()); + } + + return res; +} + +bool tcl_cast<bool>::from(Tcl_Interp *interp, Tcl_Obj *obj) +{ + int res; + int cc = Tcl_GetBooleanFromObj(interp, obj, &res); + if (cc != TCL_OK) + { + std::ostringstream ss; + ss << "Can't cast '" << Tcl_GetString(obj) << "' to bool"; + throw tcl_error(ss.str()); + } + + return res != 0; +} + +double tcl_cast<double>::from(Tcl_Interp *interp, Tcl_Obj *obj) +{ + double res; + int cc = Tcl_GetDoubleFromObj(interp, obj, &res); + if (cc != TCL_OK) + { + std::ostringstream ss; + ss << "Can't cast '" << Tcl_GetString(obj) << "' to double"; + throw tcl_error(ss.str()); + } + + return res; +} + +std::string tcl_cast<std::string>::from(Tcl_Interp *, Tcl_Obj *obj) +{ + return Tcl_GetString(obj); +} + +char const * tcl_cast<char const *>::from(Tcl_Interp *, Tcl_Obj *obj) +{ + return Tcl_GetString(obj); +} + +object tcl_cast<object>::from(Tcl_Interp *interp, Tcl_Obj *obj) +{ + object o(obj); + o.set_interp(interp); + + return o; +} + +} + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/cpptcl.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,871 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#ifndef CPPTCL_INCLUDED +#define CPPTCL_INCLUDED + +#include <tcl.h> +#include <string> +#include <stdexcept> +#include <sstream> +#include <map> +#include <vector> +#include <boost/shared_ptr.hpp> +#include <boost/bind.hpp> + + +namespace Tcl +{ + +// exception class used for reporting all Tcl errors + +class tcl_error : public std::runtime_error +{ +public: + explicit tcl_error(std::string const &msg) + : std::runtime_error(msg) {} + explicit tcl_error(Tcl_Interp *interp) + : std::runtime_error( + Tcl_GetString(Tcl_GetVar2Ex(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY))){} +}; + +// call policies + +struct policies +{ + policies() : variadic_(false) {} + + policies & factory(std::string const &name); + + // note: this is additive + policies & sink(int index); + + policies & variadic(); + + std::string factory_; + std::vector<int> sinks_; + bool variadic_; +}; + +// syntax short-cuts +policies factory(std::string const &name); +policies sink(int index); +policies variadic(); + + +class interpreter; +class object; + +namespace details +{ + +// wrapper for the evaluation result +class result +{ +public: + result(Tcl_Interp *interp); + + operator bool() const; + operator double() const; + operator int() const; + operator long() const; + operator std::string() const; + operator object() const; + +private: + Tcl_Interp *interp_; +}; + +// helper functions used to set the result value + +void set_result(Tcl_Interp *interp, bool b); +void set_result(Tcl_Interp *interp, int i); +void set_result(Tcl_Interp *interp, long i); +void set_result(Tcl_Interp *interp, double d); +void set_result(Tcl_Interp *interp, std::string const &s); +void set_result(Tcl_Interp *interp, void *p); +void set_result(Tcl_Interp *interp, object const &o); + +// helper functor for converting Tcl objects to the given type +#include "details/conversions.h" + +// dispatchers able to capture (or ignore) the result +#include "details/dispatchers.h" + +// helper for checking for required number of parameters +// (throws tcl_error when not met) +void check_params_no(int objc, int required); + +// helper for gathering optional params in variadic functions +object get_var_params(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + int from, policies const &pol); + +// the callback_base is used to store callback handlers in a polynorphic map +class callback_base +{ +public: + virtual ~callback_base() {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) = 0; +}; + + +// base class for object command handlers +// and for class handlers +class object_cmd_base +{ +public: + // destructor not needed, but exists to shut up the compiler warnings + virtual ~object_cmd_base() {} + + virtual void invoke(void *p, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) = 0; +}; + +// base class for all class handlers, still abstract +class class_handler_base : public object_cmd_base +{ +public: + typedef std::map<std::string, policies> policies_map_type; + + class_handler_base(); + + void register_method(std::string const &name, + boost::shared_ptr<object_cmd_base> ocb, policies const &p); + + policies & get_policies(std::string const &name); + +protected: + typedef std::map< + std::string, + boost::shared_ptr<object_cmd_base> + > method_map_type; + + // a map of methods for the given class + method_map_type methods_; + + policies_map_type policies_; +}; + +// class handler - responsible for executing class methods +template <class C> +class class_handler : public class_handler_base +{ +public: + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C * p = static_cast<C*>(pv); + + if (objc < 2) + { + throw tcl_error("Too few arguments."); + } + + std::string methodName(Tcl_GetString(objv[1])); + + if (methodName == "-delete") + { + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); + delete p; + return; + } + + // dispatch on the method name + + method_map_type::iterator it = methods_.find(methodName); + if (it == methods_.end()) + { + throw tcl_error("Method " + methodName + " not found."); + } + + it->second->invoke(pv, interp, objc, objv, pol); + } +}; + + +// factory functions for creating class objects +#include "details/constructors.h" + +// actual callback envelopes +#include "details/callbacks.h" + +// actual method envelopes +#include "details/methods.h" + +// helper meta function for figuring appropriate constructor callback +#include "details/metahelpers.h" + + +// this class is used to provide the "def" interface for defining +// class member functions + +template <class C> +class class_definer +{ +public: + class_definer(boost::shared_ptr<class_handler<C> > ch) : ch_(ch) {} + + template <typename R> + class_definer & def(std::string const &name, R (C::*f)(), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method0<C, R>(f)), p); + return *this; + } + + template <typename R> + class_definer & def(std::string const &name, R (C::*f)() const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method0<C, R>(f)), p); + return *this; + } + + template <typename R, typename T1> + class_definer & def(std::string const &name, R (C::*f)(T1), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method1<C, R, T1>(f)), p); + return *this; + } + + template <typename R, typename T1> + class_definer & def(std::string const &name, R (C::*f)(T1) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method1<C, R, T1>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2> + class_definer & def(std::string const &name, R (C::*f)(T1, T2), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method2<C, R, T1, T2>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2> + class_definer & def(std::string const &name, R (C::*f)(T1, T2) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method2<C, R, T1, T2>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3> + class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method3<C, R, T1, T2, T3>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3> + class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method3<C, R, T1, T2, T3>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4> + class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method4<C, R, T1, T2, T3, T4>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method4<C, R, T1, T2, T3, T4>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5), policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5) const, policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6), policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)), + p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)), + p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6, T7), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method7<C, R, + T1, T2, T3, T4, T5, T6, T7>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6, T7) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method7<C, R, + T1, T2, T3, T4, T5, T6, T7>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method8<C, R, + T1, T2, T3, T4, T5, T6, T7, T8>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method8<C, R, + T1, T2, T3, T4, T5, T6, T7, T8>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, typename T9> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9), + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method9<C, R, + T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p); + return *this; + } + + template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, typename T9> + class_definer & def(std::string const &name, + R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const, + policies const &p = policies()) + { + ch_->register_method(name, + boost::shared_ptr<details::object_cmd_base>( + new details::method9<C, R, + T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p); + return *this; + } + +private: + boost::shared_ptr<class_handler<C> > ch_; +}; + +} // namespace details + + +// init type for defining class constructors +template <typename T1 = void, typename T2 = void, typename T3 = void, + typename T4 = void, typename T5 = void, typename T6 = void, + typename T7 = void, typename T8 = void, typename T9 = void> +class init {}; + +// no_init type and object - to define classes without constructors +namespace details +{ + struct no_init_type {}; +} // namespace details +extern details::no_init_type no_init; + + +// interpreter wrapper +class interpreter +{ +public: + interpreter(); + interpreter(Tcl_Interp *, bool owner = true); + ~interpreter(); + + void make_safe(); + + Tcl_Interp * get() const { return interp_; } + + // free function definitions + + template <typename R> + void def(std::string const &name, R (*f)(), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback0<R>(f)), p); + } + + template <typename R, typename T1> + void def(std::string const &name, R (*f)(T1), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback1<R, T1>(f)), p); + } + + template <typename R, typename T1, typename T2> + void def(std::string const &name, R (*f)(T1, T2), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback2<R, T1, T2>(f)), p); + } + + template <typename R, typename T1, typename T2, typename T3> + void def(std::string const &name, R (*f)(T1, T2, T3), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback3<R, T1, T2, T3>(f)), p); + } + + template <typename R, typename T1, typename T2, typename T3, typename T4> + void def(std::string const &name, R (*f)(T1, T2, T3, T4), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback4<R, T1, T2, T3, T4>(f)), p); + } + + template <typename R, typename T1, typename T2, typename T3, + typename T4, typename T5> + void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback5<R, T1, T2, T3, T4, T5>(f)), p); + } + + template <typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6> + void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback6<R, T1, T2, T3, T4, T5, T6>(f)), p); + } + + template <typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7> + void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback7<R, + T1, T2, T3, T4, T5, T6, T7>(f)), p); + } + + template <typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7, typename T8> + void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7, T8), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback8<R, + T1, T2, T3, T4, T5, T6, T7, T8>(f)), p); + } + + template <typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7, typename T8, + typename T9> + void def(std::string const &name, + R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9), + policies const &p = policies()) + { + add_function(name, + boost::shared_ptr<details::callback_base>( + new details::callback9<R, + T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p); + } + + + // class definitions + + template <class C> + details::class_definer<C> class_(std::string const &name) + { + boost::shared_ptr<details::class_handler<C> > ch( + new details::class_handler<C>()); + + add_class(name, ch); + + add_constructor(name, ch, + boost::shared_ptr<details::callback_base>( + new details::callback0<C*>(&details::construct< + C, void, void, void, void, void, void, void, + void, void>::doit))); + + return details::class_definer<C>(ch); + } + + template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, + typename T9> + details::class_definer<C> class_(std::string const &name, + init<T1, T2, T3, T4, T5, T6, T7, T8, T9> const &, + policies const &p = policies()) + { + typedef typename details::get_callback_type_for_construct< + C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type + callback_type; + + boost::shared_ptr<details::class_handler<C> > ch( + new details::class_handler<C>()); + + add_class(name, ch); + + add_constructor(name, ch, + boost::shared_ptr<details::callback_base>( + new callback_type(&details::construct< + C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::doit)), p); + + return details::class_definer<C>(ch); + } + + template <class C> + details::class_definer<C> class_( + std::string const &name, details::no_init_type const &) + { + boost::shared_ptr<details::class_handler<C> > ch( + new details::class_handler<C>()); + + add_class(name, ch); + + return details::class_definer<C>(ch); + } + + // free script evaluation + details::result eval(std::string const &script); + details::result eval(std::istream &s); + + details::result eval(object const &o); + + // the InputIterator should give object& or Tcl_Obj* when dereferenced + template <class InputIterator> + details::result eval(InputIterator first, InputIterator last); + + // create alias from the *this interpreter to the target interpreter + void create_alias(std::string const &cmd, + interpreter &targetInterp, std::string const &targetCmd); + + // register a package info (useful when defining packages) + void pkg_provide(std::string const &name, std::string const &version); + + // helper for cleaning up callbacks in non-managed interpreters + static void clear_definitions(Tcl_Interp *); + +private: + + // copy not supported + interpreter(const interpreter &); + void operator=(const interpreter &); + + void add_function(std::string const &name, + boost::shared_ptr<details::callback_base> cb, + policies const &p = policies()); + + void add_class(std::string const &name, + boost::shared_ptr<details::class_handler_base> chb); + + void add_constructor(std::string const &name, + boost::shared_ptr<details::class_handler_base> chb, + boost::shared_ptr<details::callback_base> cb, + policies const &p = policies()); + + Tcl_Interp *interp_; + bool owner_; +}; + + +// object wrapper +class object +{ +public: + + // constructors + + object(); + + explicit object(bool b); + object(char const *buf, size_t size); // byte array + explicit object(double b); + explicit object(int i); + + // list creation + // the InputIterator should give object& or Tcl_Obj* when dereferenced + template <class InputIterator> + object(InputIterator first, InputIterator last) + : interp_(0) + { + std::vector<Tcl_Obj*> v; + fill_vector(v, first, last); + obj_ = Tcl_NewListObj(static_cast<int>(v.size()), + v.empty() ? NULL : &v[0]); + Tcl_IncrRefCount(obj_); + } + + explicit object(long i); + explicit object(char const *s); // string construction + explicit object(std::string const &s); // string construction + + explicit object(Tcl_Obj *o, bool shared = false); + + object(object const &other, bool shared = false); + ~object(); + + // assignment + + object & assign(bool b); + object & resize(size_t size); // byte array resize + object & assign(char const *buf, size_t size); // byte array assignment + object & assign(double d); + object & assign(int i); + + // list assignment + // the InputIterator should give Tcl_Obj* or object& when dereferenced + template <class InputIterator> + object & assign(InputIterator first, InputIterator last) + { + std::vector<Tcl_Obj*> v; + fill_vector(v, first, last); + Tcl_SetListObj(obj_, static_cast<int>(v.size()), + v.empty() ? NULL : &v[0]); + return *this; + } + + object & assign(long ln); + object & assign(char const *s); // string assignment + object & assign(std::string const &s); // string assignment + object & assign(object const &o); + object & assign(Tcl_Obj *o); + + object & operator=(bool b) { return assign(b); } + object & operator=(double d) { return assign(d); } + object & operator=(int i) { return assign(i); } + object & operator=(long ln) { return assign(ln); } + object & operator=(char const *s) { return assign(s); } + object & operator=(std::string const &s) { return assign(s); } + + object & operator=(object const &o) { return assign(o); } + object & swap(object &other); + + // (logically) non-modifying members + + template <typename T> + T get(interpreter &i) const; + + char const * get() const; // string get + char const * get(size_t &size) const; // byte array get + + size_t length(interpreter &i) const; // returns list length + object at(interpreter &i, size_t index) const; + + Tcl_Obj * get_object() const { return obj_; } + + // modifying members + + object & append(interpreter &i, object const &o); + object & append_list(interpreter &i, object const &o); + + // list replace + // the InputIterator should give Tcl_Obj* or object& when dereferenced + template <class InputIterator> + object & replace(interpreter &i, size_t index, size_t count, + InputIterator first, InputIterator last) + { + std::vector<Tcl_Obj*> v; + fill_vector(v, first, last); + int res = Tcl_ListObjReplace(i.get(), obj_, + static_cast<int>(index), static_cast<int>(count), + static_cast<int>(v.size()), v.empty() ? NULL : &v[0]); + if (res != TCL_OK) + { + throw tcl_error(i.get()); + } + + return *this; + } + + object & replace(interpreter &i, size_t index, size_t count, + object const &o); + object & replace_list(interpreter &i, size_t index, size_t count, + object const &o); + + // helper functions for piggy-backing interpreter info + void set_interp(Tcl_Interp *interp); + Tcl_Interp * get_interp() const; + + // helper function, also used from interpreter::eval + template <class InputIterator> + static void fill_vector(std::vector<Tcl_Obj*> &v, + InputIterator first, InputIterator last) + { + for (; first != last; ++first) + { + object o(*first, true); + v.push_back(o.obj_); + } + } + +private: + + // helper function used from copy constructors + void init(Tcl_Obj *o, bool shared); + + Tcl_Obj *obj_; + Tcl_Interp *interp_; +}; + +// available specializations for object::get +template <> bool object::get<bool>(interpreter &i) const; +template <> double object::get<double>(interpreter &i) const; +template <> int object::get<int>(interpreter &i) const; +template <> long object::get<long>(interpreter &i) const; +template <> char const * object::get<char const *>(interpreter &i) const; +template <> std::string object::get<std::string>(interpreter &i) const; +template <> +std::vector<char> object::get<std::vector<char> >(interpreter &i) const; + +// the InputIterator should give object& or Tcl_Obj* when dereferenced +template <class InputIterator> +details::result interpreter::eval(InputIterator first, InputIterator last) +{ + std::vector<Tcl_Obj*> v; + object::fill_vector(v, first, last); + int cc = Tcl_EvalObjv(interp_, + static_cast<int>(v.size()), v.empty() ? NULL : &v[0], 0); + if (cc != TCL_OK) + { + throw tcl_error(interp_); + } + + return details::result(interp_); +} + +namespace details +{ + +// additional callback envelopes for variadic functions +#include "details/callbacks_v.h" + +// additional method envelopes for variadic methods +#include "details/methods_v.h" + +} // namespace details + +} // namespace Tcl + + +// macro for defining loadable module entry point +// - used for extending Tcl interpreter + +#define CPPTCL_MODULE(name, i) void name##_cpptcl_Init(Tcl::interpreter &i); \ + extern "C" int name##_Init(Tcl_Interp *interp) \ + { \ + Tcl::interpreter i(interp, false); \ + name##_cpptcl_Init(i); \ + return TCL_OK; \ + } \ + void name##_cpptcl_Init(Tcl::interpreter &i) + + +#endif // CPPTCL_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/callbacks.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,273 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +template <typename R> +class callback0 : public callback_base +{ + typedef R (*functor_type)(); + +public: + callback0(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int, Tcl_Obj * CONST [], + policies const &) + { + dispatch<R>::do_dispatch(interp, f_); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1> +class callback1 : public callback_base +{ + typedef R (*functor_type)(T1); + +public: + callback1(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 2); + + dispatch<R>::template do_dispatch<T1>(interp, f_, + tcl_cast<T1>::from(interp, objv[1])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2> +class callback2 : public callback_base +{ + typedef R (*functor_type)(T1, T2); + +public: + callback2(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 3); + + dispatch<R>::template do_dispatch<T1, T2>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3> +class callback3 : public callback_base +{ + typedef R (*functor_type)(T1, T2, T3); + +public: + callback3(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 4); + + dispatch<R>::template do_dispatch<T1, T2, T3>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4> +class callback4 : public callback_base +{ + typedef R (*functor_type)(T1, T2, T3, T4); + +public: + callback4(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 5); + + dispatch<R>::template do_dispatch<T1, T2, T3, T4>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5> +class callback5 : public callback_base +{ + typedef R (*functor_type)(T1, T2, T3, T4, T5); + +public: + callback5(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 6); + + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> +class callback6 : public callback_base +{ + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6); + +public: + callback6(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 7); + + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + tcl_cast<T6>::from(interp, objv[6])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> +class callback7 : public callback_base +{ + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7); + +public: + callback7(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 8); + + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + tcl_cast<T6>::from(interp, objv[6]), + tcl_cast<T7>::from(interp, objv[7])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> +class callback8 : public callback_base +{ + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8); + +public: + callback8(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 9); + + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7, T8>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + tcl_cast<T6>::from(interp, objv[6]), + tcl_cast<T7>::from(interp, objv[7]), + tcl_cast<T8>::from(interp, objv[8])); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, typename T9> +class callback9 : public callback_base +{ + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9); + +public: + callback9(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &) + { + check_params_no(objc, 10); + + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8, T9>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + tcl_cast<T6>::from(interp, objv[6]), + tcl_cast<T7>::from(interp, objv[7]), + tcl_cast<T8>::from(interp, objv[8]), + tcl_cast<T9>::from(interp, objv[9])); + } + +private: + functor_type f_; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/callbacks_v.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,267 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +template <typename R> +class callback1<R, object const &> : public callback_base +{ + typedef object const & T1; + typedef R (*functor_type)(T1); + enum { var_start = 1 }; + +public: + callback1(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t1 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1>(interp, f_, + t1); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1> +class callback2<R, T1, object const &> : public callback_base +{ + typedef object const & T2; + typedef R (*functor_type)(T1, T2); + enum { var_start = 2 }; + +public: + callback2(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t2 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1, T2>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + t2); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2> +class callback3<R, T1, T2, object const &> : public callback_base +{ + typedef object const & T3; + typedef R (*functor_type)(T1, T2, T3); + enum { var_start = 3 }; + +public: + callback3(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t3 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1, T2, T3>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + t3); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3> +class callback4<R, T1, T2, T3, object const &> : public callback_base +{ + typedef object const & T4; + typedef R (*functor_type)(T1, T2, T3, T4); + enum { var_start = 4 }; + +public: + callback4(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t4 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1, T2, T3, T4>(interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + t4); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4> +class callback5<R, T1, T2, T3, T4, object const &> : public callback_base +{ + typedef object const & T5; + typedef R (*functor_type)(T1, T2, T3, T4, T5); + enum { var_start = 5 }; + +public: + callback5(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t5 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + t5); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5> +class callback6<R, T1, T2, T3, T4, T5, object const &> : public callback_base +{ + typedef object const & T6; + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6); + enum { var_start = 6 }; + +public: + callback6(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t6 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + t6); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> +class callback7<R, T1, T2, T3, T4, T5, T6, object const &> + : public callback_base +{ + typedef object const & T7; + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7); + enum { var_start = 7 }; + +public: + callback7(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t7 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + tcl_cast<T6>::from(interp, objv[6]), + t7); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> +class callback8<R, T1, T2, T3, T4, T5, T6, T7, object const &> + : public callback_base +{ + typedef object const & T8; + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8); + enum { var_start = 8 }; + +public: + callback8(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t8 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7, T8>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + tcl_cast<T6>::from(interp, objv[6]), + tcl_cast<T7>::from(interp, objv[7]), + t8); + } + +private: + functor_type f_; +}; + +template <typename R, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> +class callback9<R, T1, T2, T3, T4, T5, T6, T7, T8, object const &> + : public callback_base +{ + typedef object const & T9; + typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9); + enum { var_start = 9 }; + +public: + callback9(functor_type f) : f_(f) {} + + virtual void invoke(Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], + policies const &pol) + { + object t9 = get_var_params(interp, objc, objv, var_start, pol); + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8, T9>( + interp, f_, + tcl_cast<T1>::from(interp, objv[1]), + tcl_cast<T2>::from(interp, objv[2]), + tcl_cast<T3>::from(interp, objv[3]), + tcl_cast<T4>::from(interp, objv[4]), + tcl_cast<T5>::from(interp, objv[5]), + tcl_cast<T6>::from(interp, objv[6]), + tcl_cast<T7>::from(interp, objv[7]), + tcl_cast<T8>::from(interp, objv[8]), + t9); + } + +private: + functor_type f_; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/constructors.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,88 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, typename T9> +struct construct +{ + static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, + T8 t8, T9 t9) + { return new C(t1, t2, t3, t4, t5, t6, t7, t8, t9); } +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> +struct construct<C, T1, T2, T3, T4, T5, T6, T7, T8, void> +{ + static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) + { return new C(t1, t2, t3, t4, t5, t6, t7, t8); } +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> +struct construct<C, T1, T2, T3, T4, T5, T6, T7, void, void> +{ + static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) + { return new C(t1, t2, t3, t4, t5, t6, t7); } +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> +struct construct<C, T1, T2, T3, T4, T5, T6, void, void, void> +{ + static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) + { return new C(t1, t2, t3, t4, t5, t6); } +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5> +struct construct<C, T1, T2, T3, T4, T5, void, void, void, void> +{ + static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) + { return new C(t1, t2, t3, t4, t5); } +}; + +template <class C, typename T1, typename T2, typename T3, typename T4> +struct construct<C, T1, T2, T3, T4, void, void, void, void, void> +{ + static C * doit(T1 t1, T2 t2, T3 t3, T4 t4) + { return new C(t1, t2, t3, t4); } +}; + +template <class C, typename T1, typename T2, typename T3> +struct construct<C, T1, T2, T3, void, void, void, void, void, void> +{ + static C * doit(T1 t1, T2 t2, T3 t3) + { return new C(t1, t2, t3); } +}; + +template <class C, typename T1, typename T2> +struct construct<C, T1, T2, void, void, void, void, void, void, void> +{ + static C * doit(T1 t1, T2 t2) + { return new C(t1, t2); } +}; + +template <class C, typename T1> +struct construct<C, T1, void, void, void, void, void, void, void, void> +{ + static C * doit(T1 t1) + { return new C(t1); } +}; + +template <class C> +struct construct<C, void, void, void, void, void, + void, void, void, void> +{ + static C * doit() + { return new C(); } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/conversions.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,101 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +// helper functor for converting Tcl objects to the given type +// (it is a struct instead of function, +// because I need to partially specialize it) + +template <typename T> +struct tcl_cast; + +template <typename T> +struct tcl_cast<T*> +{ + static T * from(Tcl_Interp *, Tcl_Obj *obj) + { + std::string s(Tcl_GetString(obj)); + if (s.size() == 0) + { + throw tcl_error("Expected pointer value, got empty string."); + } + + if (s[0] != 'p') + { + throw tcl_error("Expected pointer value."); + } + + std::istringstream ss(s); + char dummy; + void *p; + ss >> dummy >> p; + + return static_cast<T*>(p); + } +}; + +// the following partial specialization is to strip reference +// (it returns a temporary object of the underlying type, which +// can be bound to the const-ref parameter of the actual function) + +template <typename T> +struct tcl_cast<T const &> +{ + static T from(Tcl_Interp *interp, Tcl_Obj *obj) + { + return tcl_cast<T>::from(interp, obj); + } +}; + + +// the following specializations are implemented + +template <> +struct tcl_cast<int> +{ + static int from(Tcl_Interp *, Tcl_Obj *); +}; + +template <> +struct tcl_cast<long> +{ + static long from(Tcl_Interp *, Tcl_Obj *); +}; + +template <> +struct tcl_cast<bool> +{ + static bool from(Tcl_Interp *, Tcl_Obj *); +}; + +template <> +struct tcl_cast<double> +{ + static double from(Tcl_Interp *, Tcl_Obj *); +}; + +template <> +struct tcl_cast<std::string> +{ + static std::string from(Tcl_Interp *, Tcl_Obj *); +}; + +template <> +struct tcl_cast<char const *> +{ + static char const * from(Tcl_Interp *, Tcl_Obj *); +}; + +template <> +struct tcl_cast<object> +{ + static object from(Tcl_Interp *, Tcl_Obj *); +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/dispatchers.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,181 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +// the dispatch class is used to execute the callback functor and to +// capture its return value +// further dispatch<void> specialization ignores the res + +template <typename R> +struct dispatch +{ + template <class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f) + { + R res = f(); + set_result(interp, res); + } + + template <typename T1, class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, T1 t1) + { + R res = f(t1); + set_result(interp, res); + } + + template <typename T1, typename T2, class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, T1 t1, T2 t2) + { + R res = f(t1, t2); + set_result(interp, res); + } + + template <typename T1, typename T2, typename T3, class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, + T1 t1, T2 t2, T3 t3) + { + R res = f(t1, t2, t3); + set_result(interp, res); + } + + template <typename T1, typename T2, typename T3, typename T4, + class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4) + { + R res = f(t1, t2, t3, t4); + set_result(interp, res); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) + { + R res = f(t1, t2, t3, t4, t5); + set_result(interp, res); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) + { + R res = f(t1, t2, t3, t4, t5, t6); + set_result(interp, res); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) + { + R res = f(t1, t2, t3, t4, t5, t6, t7); + set_result(interp, res); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) + { + R res = f(t1, t2, t3, t4, t5, t6, t7, t8); + set_result(interp, res); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, typename T9, + class Functor> + static void do_dispatch(Tcl_Interp *interp, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) + { + R res = f(t1, t2, t3, t4, t5, t6, t7, t8, t9); + set_result(interp, res); + } +}; + +template <> +struct dispatch<void> +{ + template <class Functor> + static void do_dispatch(Tcl_Interp *, Functor f) + { + f(); + } + + template <typename T1, class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, T1 t1) + { + f(t1); + } + + template <typename T1, typename T2, class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, T1 t1, T2 t2) + { + f(t1, t2); + } + + template <typename T1, typename T2, typename T3, class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, + T1 t1, T2 t2, T3 t3) + { + f(t1, t2, t3); + } + + template <typename T1, typename T2, typename T3, typename T4, + class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4) + { + f(t1, t2, t3, t4); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) + { + f(t1, t2, t3, t4, t5); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) + { + f(t1, t2, t3, t4, t5, t6); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) + { + f(t1, t2, t3, t4, t5, t6, t7); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) + { + f(t1, t2, t3, t4, t5, t6, t7, t8); + } + + template <typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, typename T9, + class Functor> + static void do_dispatch(Tcl_Interp *, Functor f, + T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) + { + f(t1, t2, t3, t4, t5, t6, t7, t8, t9); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/metahelpers.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,86 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8, + typename T9> +struct get_callback_type_for_construct +{ + typedef callback9<C*, T1, T2, T3, T4, T5, T6, T7, T8, T9> type; +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7, typename T8> +struct get_callback_type_for_construct< + C, T1, T2, T3, T4, T5, T6, T7, T8, void> +{ + typedef callback8<C*, T1, T2, T3, T4, T5, T6, T7, T8> type; +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6, typename T7> +struct get_callback_type_for_construct< + C, T1, T2, T3, T4, T5, T6, T7, void, void> +{ + typedef callback7<C*, T1, T2, T3, T4, T5, T6, T7> type; +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5, typename T6> +struct get_callback_type_for_construct< + C, T1, T2, T3, T4, T5, T6, void, void, void> +{ + typedef callback6<C*, T1, T2, T3, T4, T5, T6> type; +}; + +template <class C, typename T1, typename T2, typename T3, typename T4, + typename T5> +struct get_callback_type_for_construct< + C, T1, T2, T3, T4, T5, void, void, void, void> +{ + typedef callback5<C*, T1, T2, T3, T4, T5> type; +}; + +template <class C, typename T1, typename T2, typename T3, typename T4> +struct get_callback_type_for_construct< + C, T1, T2, T3, T4, void, void, void, void, void> +{ + typedef callback4<C*, T1, T2, T3, T4> type; +}; + +template <class C, typename T1, typename T2, typename T3> +struct get_callback_type_for_construct< + C, T1, T2, T3, void, void, void, void, void, void> +{ + typedef callback3<C*, T1, T2, T3> type; +}; + +template <class C, typename T1, typename T2> +struct get_callback_type_for_construct< + C, T1, T2, void, void, void, void, void, void, void> +{ + typedef callback2<C*, T1, T2> type; +}; + +template <class C, typename T1> +struct get_callback_type_for_construct< + C, T1, void, void, void, void, void, void, void, void> +{ + typedef callback1<C*, T1> type; +}; + +template <class C> +struct get_callback_type_for_construct< + C, void, void, void, void, void, void, void, void, void> +{ + typedef callback0<C*> type; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/methods.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,452 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +template <class C, typename R> +class method0 : public object_cmd_base +{ + typedef R (C::*mem_type)(); + typedef R (C::*cmem_type)() const; + +public: + method0(mem_type f) : f_(f), cmem_(false) {} + method0(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int, Tcl_Obj * CONST [], policies const &) + { + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::do_dispatch(interp, boost::bind(cf_, p)); + } + else + { + dispatch<R>::do_dispatch(interp, boost::bind(f_, p)); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1> +class method1 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1); + typedef R (C::*cmem_type)(T1) const; + +public: + method1(mem_type f) : f_(f), cmem_(false) {} + method1(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 3); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch<T1>( + interp, boost::bind(cf_, p, _1), + tcl_cast<T1>::from(interp, objv[2])); + } + else + { + dispatch<R>::template do_dispatch<T1>( + interp, boost::bind(f_, p, _1), + tcl_cast<T1>::from(interp, objv[2])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2> +class method2 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2); + typedef R (C::*cmem_type)(T1, T2) const; + +public: + method2(mem_type f) : f_(f), cmem_(false) {} + method2(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 4); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2>( + interp, boost::bind(cf_, p, _1, _2), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3])); + } + else + { + dispatch<R>::template do_dispatch<T1, T2>( + interp, boost::bind(f_, p, _1, _2), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3> +class method3 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2, T3); + typedef R (C::*cmem_type)(T1, T2, T3) const; + +public: + method3(mem_type f) : f_(f), cmem_(false) {} + method3(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 5); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3>( + interp, boost::bind(cf_, p, _1, _2, _3), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4])); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3>( + interp, boost::bind(f_, p, _1, _2, _3), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4> +class method4 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2, T3, T4); + typedef R (C::*cmem_type)(T1, T2, T3, T4) const; + +public: + method4(mem_type f) : f_(f), cmem_(false) {} + method4(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 6); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4>( + interp, boost::bind(cf_, p, _1, _2, _3, _4), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5])); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4>( + interp, boost::bind(f_, p, _1, _2, _3, _4), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5> +class method5 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2, T3, T4, T5); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5) const; + +public: + method5(mem_type f) : f_(f), cmem_(false) {} + method5(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 7); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>( + interp, boost::bind(cf_, p, _1, _2, _3, _4, _5), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6])); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>( + interp, boost::bind(f_, p, _1, _2, _3, _4, _5), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6> +class method6 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6) const; + +public: + method6(mem_type f) : f_(f), cmem_(false) {} + method6(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 8); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>( + interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7])); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>( + interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7> +class method7 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7) const; + +public: + method7(mem_type f) : f_(f), cmem_(false) {} + method7(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 9); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>( + interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6, _7), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8])); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>( + interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6, _7), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7, typename T8> +class method8 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8) const; + +public: + method8(mem_type f) : f_(f), cmem_(false) {} + method8(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 10); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8>( + interp, boost::bind(cf_, p, + _1, _2, _3, _4, _5, _6, _7, _8), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + tcl_cast<T8>::from(interp, objv[9])); + } + else + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8>( + interp, boost::bind(f_, p, + _1, _2, _3, _4, _5, _6, _7, _8), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + tcl_cast<T8>::from(interp, objv[9])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7, typename T8, + typename T9> +class method9 : public object_cmd_base +{ + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const; + +public: + method9(mem_type f) : f_(f), cmem_(false) {} + method9(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &) + { + check_params_no(objc, 11); + + C *p = static_cast<C*>(pv); + if (cmem_) + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8, T9>( + interp, boost::bind(cf_, p, + _1, _2, _3, _4, _5, _6, _7, _8, _9), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + tcl_cast<T8>::from(interp, objv[9]), + tcl_cast<T9>::from(interp, objv[10])); + } + else + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8, T9>( + interp, boost::bind(f_, p, + _1, _2, _3, _4, _5, _6, _7, _8, _9), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + tcl_cast<T8>::from(interp, objv[9]), + tcl_cast<T9>::from(interp, objv[10])); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/plugins/tcl/cpptcl-1.1.4/details/methods_v.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,451 @@ +// +// Copyright (C) 2004-2006, Maciej Sobczak +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +// Note: this file is not supposed to be a stand-alone header + + +template <class C, typename R> +class method1<C, R, object const &> : public object_cmd_base +{ + typedef object const & T1; + typedef R (C::*mem_type)(T1); + typedef R (C::*cmem_type)(T1) const; + enum { var_start = 2 }; + +public: + method1(mem_type f) : f_(f), cmem_(false) {} + method1(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t1 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch<T1>( + interp, boost::bind(cf_, p, _1), + t1); + } + else + { + dispatch<R>::template do_dispatch<T1>( + interp, boost::bind(f_, p, _1), + t1); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1> +class method2<C, R, T1, object const &> : public object_cmd_base +{ + typedef object const & T2; + typedef R (C::*mem_type)(T1, T2); + typedef R (C::*cmem_type)(T1, T2) const; + enum { var_start = 3 }; + +public: + method2(mem_type f) : f_(f), cmem_(false) {} + method2(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t2 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2>( + interp, boost::bind(cf_, p, _1, _2), + tcl_cast<T1>::from(interp, objv[2]), + t2); + } + else + { + dispatch<R>::template do_dispatch<T1, T2>( + interp, boost::bind(f_, p, _1, _2), + tcl_cast<T1>::from(interp, objv[2]), + t2); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2> +class method3<C, R, T1, T2, object const &> : public object_cmd_base +{ + typedef object const & T3; + typedef R (C::*mem_type)(T1, T2, T3); + typedef R (C::*cmem_type)(T1, T2, T3) const; + enum { var_start = 4 }; + +public: + method3(mem_type f) : f_(f), cmem_(false) {} + method3(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t3 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3>( + interp, boost::bind(cf_, p, _1, _2, _3), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + t3); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3>( + interp, boost::bind(f_, p, _1, _2, _3), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + t3); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3> +class method4<C, R, T1, T2, T3, object const &> : public object_cmd_base +{ + typedef object const & T4; + typedef R (C::*mem_type)(T1, T2, T3, T4); + typedef R (C::*cmem_type)(T1, T2, T3, T4) const; + enum { var_start = 5 }; + +public: + method4(mem_type f) : f_(f), cmem_(false) {} + method4(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t4 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4>( + interp, boost::bind(cf_, p, _1, _2, _3, _4), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + t4); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4>( + interp, boost::bind(f_, p, _1, _2, _3, _4), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + t4); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4> +class method5<C, R, T1, T2, T3, T4, object const &> : public object_cmd_base +{ + typedef object const & T5; + typedef R (C::*mem_type)(T1, T2, T3, T4, T5); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5) const; + enum { var_start = 6 }; + +public: + method5(mem_type f) : f_(f), cmem_(false) {} + method5(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t5 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>( + interp, boost::bind(cf_, p, _1, _2, _3, _4, _5), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + t5); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>( + interp, boost::bind(f_, p, _1, _2, _3, _4, _5), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + t5); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5> +class method6<C, R, T1, T2, T3, T4, T5, object const &> + : public object_cmd_base +{ + typedef object const & T6; + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6) const; + enum { var_start = 7 }; + +public: + method6(mem_type f) : f_(f), cmem_(false) {} + method6(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t6 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>( + interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + t6); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>( + interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + t6); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6> +class method7<C, R, T1, T2, T3, T4, T5, T6, object const &> + : public object_cmd_base +{ + typedef object const & T7; + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7) const; + enum { var_start = 8 }; + +public: + method7(mem_type f) : f_(f), cmem_(false) {} + method7(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t7 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>( + interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6, _7), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + t7); + } + else + { + dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>( + interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6, _7), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + t7); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7> +class method8<C, R, T1, T2, T3, T4, T5, T6, T7, object const &> + : public object_cmd_base +{ + typedef object const & T8; + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8) const; + enum { var_start = 9 }; + +public: + method8(mem_type f) : f_(f), cmem_(false) {} + method8(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t8 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8>( + interp, boost::bind(cf_, p, + _1, _2, _3, _4, _5, _6, _7, _8), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + t8); + } + else + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8>( + interp, boost::bind(f_, p, + _1, _2, _3, _4, _5, _6, _7, _8), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + t8); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +}; + +template <class C, typename R, typename T1, typename T2, typename T3, + typename T4, typename T5, typename T6, typename T7, typename T8> +class method9<C, R, T1, T2, T3, T4, T5, T6, T7, T8, object const &> + : public object_cmd_base +{ + typedef object const & T9; + typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9); + typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const; + enum { var_start = 10 }; + +public: + method9(mem_type f) : f_(f), cmem_(false) {} + method9(cmem_type f) : cf_(f), cmem_(true) {} + + virtual void invoke(void *pv, Tcl_Interp *interp, + int objc, Tcl_Obj * CONST objv[], policies const &pol) + { + C *p = static_cast<C*>(pv); + + object t9 = get_var_params(interp, objc, objv, var_start, pol); + + if (cmem_) + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8, T9>( + interp, boost::bind(cf_, p, + _1, _2, _3, _4, _5, _6, _7, _8, _9), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + tcl_cast<T8>::from(interp, objv[9]), + t9); + } + else + { + dispatch<R>::template do_dispatch< + T1, T2, T3, T4, T5, T6, T7, T8, T9>( + interp, boost::bind(f_, p, + _1, _2, _3, _4, _5, _6, _7, _8, _9), + tcl_cast<T1>::from(interp, objv[2]), + tcl_cast<T2>::from(interp, objv[3]), + tcl_cast<T3>::from(interp, objv[4]), + tcl_cast<T4>::from(interp, objv[5]), + tcl_cast<T5>::from(interp, objv[6]), + tcl_cast<T6>::from(interp, objv[7]), + tcl_cast<T7>::from(interp, objv[8]), + tcl_cast<T8>::from(interp, objv[9]), + t9); + } + } + +private: + mem_type f_; + cmem_type cf_; + bool cmem_; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/structures/SourceFiles.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,44 @@ +// +// 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 "SourceFiles.h" + + +namespace // unnamed +{ + +Vera::Structures::SourceFiles::FileNameSet files_; + +} // unnamed namespace + +namespace Vera +{ +namespace Structures +{ + +int SourceFiles::count() +{ + return files_.size(); +} + +void SourceFiles::addFileName(const FileName & name) +{ + files_.insert(name); +} + +bool SourceFiles::empty() +{ + return files_.empty(); +} + +const SourceFiles::FileNameSet & SourceFiles::getAllFileNames() +{ + return files_; +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/structures/SourceFiles.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,47 @@ +// +// 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) +// + +#ifndef SOURCEFILES_H_INCLUDED +#define SOURCEFILES_H_INCLUDED + +#include <string> +#include <set> +#include <stdexcept> + + +namespace Vera +{ +namespace Structures +{ + + +class SourceFileError : public std::runtime_error +{ +public: + SourceFileError(const std::string & msg) : std::runtime_error(msg) {} +}; + +class SourceFiles +{ +public: + typedef std::string FileName; + typedef std::set<FileName> FileNameSet; + typedef FileNameSet::const_iterator iterator; + + static void addFileName(const FileName & name); + + static bool empty(); + static int count(); + + static const FileNameSet & getAllFileNames(); +}; + +} // namespace Structures + +} // namespace Vera + +#endif // SOURCEFILES_H_INCLUDED
--- /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]; +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/structures/SourceLines.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,38 @@ +// +// 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) +// + +#ifndef SOURCELINES_H_INCLUDED +#define SOURCELINES_H_INCLUDED + +#include "SourceFiles.h" +#include <vector> +#include <iostream> + +namespace Vera +{ +namespace Structures +{ + + +class SourceLines +{ +public: + typedef std::vector<std::string> LineCollection; + + static const LineCollection & getAllLines(const SourceFiles::FileName & name); + static int getLineCount(const SourceFiles::FileName & name); + static const std::string & getLine(const SourceFiles::FileName & name, int lineNumber); + + static void loadFile(const SourceFiles::FileName & name); + static void loadFile(std::istream & file, const SourceFiles::FileName & name); +}; + +} // namespace Structures + +} // namespace Vera + +#endif // SOURCELINES_H_INCLUDED
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/structures/Tokens.cpp Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,497 @@ +// +// 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 "Tokens.h" +#include "SourceLines.h" +#include "../plugins/Reports.h" +#include <boost/wave.hpp> +#include <boost/wave/cpplexer/cpp_lex_token.hpp> +#include <boost/wave/cpplexer/cpp_lex_iterator.hpp> +#include <boost/wave/cpplexer/cpplexer_exceptions.hpp> +#include <boost/algorithm/string/case_conv.hpp> +#include <boost/function.hpp> +#include <boost/bind.hpp> +#include <vector> +#include <map> +#include <algorithm> +#include <sstream> +#include <cctype> + + +namespace // unnamed +{ + +typedef std::vector<std::string> PhysicalTokenCollection; +PhysicalTokenCollection physicalTokens; + +struct TokenRef +{ + TokenRef(boost::wave::token_id id, int line, int column, int length) + : id_(id), line_(line), column_(column), length_(length), index_(-1) {} + + TokenRef(boost::wave::token_id id, int line, int column, int length, const std::string & value) + : id_(id), line_(line), column_(column), length_(length) + { + // newline is optimized as the most common case + + if (id_ != boost::wave::T_NEWLINE) + { + // value of the token is stored in physicalTokens collection + // (because it has no physical representation in the source code) + + index_ = static_cast<int>(physicalTokens.size()); + physicalTokens.push_back(value); + } + } + + std::string getTokenValue(const Vera::Structures::SourceFiles::FileName & fileName) const + { + if (id_ == boost::wave::T_NEWLINE) + { + return "\n"; + } + else if (index_ >= 0) + { + // token value stored in the physicalTokens structure + // (this is used with line continuation and other cases + // where the token has no representation in physical lines) + + return physicalTokens[static_cast<size_t>(index_)]; + } + else + { + // token value has to be retrieved from the physical line collection + + return Vera::Structures::SourceLines::getLine(fileName, line_).substr(column_, length_); + } + } + + boost::wave::token_id id_; + int line_; + int column_; + int length_; + + // if >= 0, it is the index into the physicalTokens collection, + // used only for line continuation + // and when line_ and column_ do not reflect the physical layout: + int index_; +}; + +typedef std::vector<TokenRef> TokenCollection; + +typedef std::map<Vera::Structures::SourceFiles::FileName, TokenCollection> FileTokenCollection; + +FileTokenCollection fileTokens_; + +typedef std::vector<boost::function<bool (boost::wave::token_id)> > CompiledFilterSequence; + +boost::wave::token_id tokenIdFromTokenFilter(const Vera::Structures::Tokens::TokenFilter & filter) +{ + typedef std::map<Vera::Structures::Tokens::TokenFilter, boost::wave::token_id> + TokenFilterToIdMap; + + static TokenFilterToIdMap tokenMap; + if (tokenMap.empty()) + { + tokenMap["and"] = static_cast<boost::wave::token_id>(256); + tokenMap["andand"] = static_cast<boost::wave::token_id>(257); + tokenMap["assign"] = static_cast<boost::wave::token_id>(258); + tokenMap["andassign"] = static_cast<boost::wave::token_id>(259); + tokenMap["or"] = static_cast<boost::wave::token_id>(260); + tokenMap["orassign"] = static_cast<boost::wave::token_id>(261); + tokenMap["xor"] = static_cast<boost::wave::token_id>(262); + tokenMap["xorassign"] = static_cast<boost::wave::token_id>(263); + tokenMap["comma"] = static_cast<boost::wave::token_id>(264); + tokenMap["colon"] = static_cast<boost::wave::token_id>(265); + tokenMap["divide"] = static_cast<boost::wave::token_id>(266); + tokenMap["divideassign"] = static_cast<boost::wave::token_id>(267); + tokenMap["dot"] = static_cast<boost::wave::token_id>(268); + tokenMap["dotstar"] = static_cast<boost::wave::token_id>(269); + tokenMap["ellipsis"] = static_cast<boost::wave::token_id>(270); + tokenMap["equal"] = static_cast<boost::wave::token_id>(271); + tokenMap["greater"] = static_cast<boost::wave::token_id>(272); + tokenMap["greaterequal"] = static_cast<boost::wave::token_id>(273); + tokenMap["leftbrace"] = static_cast<boost::wave::token_id>(274); + tokenMap["less"] = static_cast<boost::wave::token_id>(275); + tokenMap["lessequal"] = static_cast<boost::wave::token_id>(276); + tokenMap["leftparen"] = static_cast<boost::wave::token_id>(277); + tokenMap["leftbracket"] = static_cast<boost::wave::token_id>(278); + tokenMap["minus"] = static_cast<boost::wave::token_id>(279); + tokenMap["minusassign"] = static_cast<boost::wave::token_id>(280); + tokenMap["minusminus"] = static_cast<boost::wave::token_id>(281); + tokenMap["percent"] = static_cast<boost::wave::token_id>(282); + tokenMap["percentassign"] = static_cast<boost::wave::token_id>(283); + tokenMap["not"] = static_cast<boost::wave::token_id>(284); + tokenMap["notequal"] = static_cast<boost::wave::token_id>(285); + tokenMap["oror"] = static_cast<boost::wave::token_id>(286); + tokenMap["plus"] = static_cast<boost::wave::token_id>(287); + tokenMap["plusassign"] = static_cast<boost::wave::token_id>(288); + tokenMap["plusplus"] = static_cast<boost::wave::token_id>(289); + tokenMap["arrow"] = static_cast<boost::wave::token_id>(290); + tokenMap["arrowstar"] = static_cast<boost::wave::token_id>(291); + tokenMap["question_mark"] = static_cast<boost::wave::token_id>(292); + tokenMap["rightbrace"] = static_cast<boost::wave::token_id>(293); + tokenMap["rightparen"] = static_cast<boost::wave::token_id>(294); + tokenMap["rightbracket"] = static_cast<boost::wave::token_id>(295); + tokenMap["colon_colon"] = static_cast<boost::wave::token_id>(296); + tokenMap["semicolon"] = static_cast<boost::wave::token_id>(297); + tokenMap["shiftleft"] = static_cast<boost::wave::token_id>(298); + tokenMap["shiftleftassign"] = static_cast<boost::wave::token_id>(299); + tokenMap["shiftright"] = static_cast<boost::wave::token_id>(300); + tokenMap["shiftrightassign"] = static_cast<boost::wave::token_id>(301); + tokenMap["star"] = static_cast<boost::wave::token_id>(302); + tokenMap["compl"] = static_cast<boost::wave::token_id>(303); + tokenMap["starassign"] = static_cast<boost::wave::token_id>(304); + tokenMap["asm"] = static_cast<boost::wave::token_id>(305); + tokenMap["auto"] = static_cast<boost::wave::token_id>(306); + tokenMap["bool"] = static_cast<boost::wave::token_id>(307); + tokenMap["false"] = static_cast<boost::wave::token_id>(308); + tokenMap["true"] = static_cast<boost::wave::token_id>(309); + tokenMap["break"] = static_cast<boost::wave::token_id>(310); + tokenMap["case"] = static_cast<boost::wave::token_id>(311); + tokenMap["catch"] = static_cast<boost::wave::token_id>(312); + tokenMap["char"] = static_cast<boost::wave::token_id>(313); + tokenMap["class"] = static_cast<boost::wave::token_id>(314); + tokenMap["const"] = static_cast<boost::wave::token_id>(315); + tokenMap["constcast"] = static_cast<boost::wave::token_id>(316); + tokenMap["continue"] = static_cast<boost::wave::token_id>(317); + tokenMap["default"] = static_cast<boost::wave::token_id>(318); + tokenMap["delete"] = static_cast<boost::wave::token_id>(319); + tokenMap["do"] = static_cast<boost::wave::token_id>(320); + tokenMap["double"] = static_cast<boost::wave::token_id>(321); + tokenMap["dynamiccast"] = static_cast<boost::wave::token_id>(322); + tokenMap["else"] = static_cast<boost::wave::token_id>(323); + tokenMap["enum"] = static_cast<boost::wave::token_id>(324); + tokenMap["explicit"] = static_cast<boost::wave::token_id>(325); + tokenMap["export"] = static_cast<boost::wave::token_id>(326); + tokenMap["extern"] = static_cast<boost::wave::token_id>(327); + tokenMap["float"] = static_cast<boost::wave::token_id>(328); + tokenMap["for"] = static_cast<boost::wave::token_id>(329); + tokenMap["friend"] = static_cast<boost::wave::token_id>(330); + tokenMap["goto"] = static_cast<boost::wave::token_id>(331); + tokenMap["if"] = static_cast<boost::wave::token_id>(332); + tokenMap["inline"] = static_cast<boost::wave::token_id>(333); + tokenMap["int"] = static_cast<boost::wave::token_id>(334); + tokenMap["long"] = static_cast<boost::wave::token_id>(335); + tokenMap["mutable"] = static_cast<boost::wave::token_id>(336); + tokenMap["namespace"] = static_cast<boost::wave::token_id>(337); + tokenMap["new"] = static_cast<boost::wave::token_id>(338); + tokenMap["operator"] = static_cast<boost::wave::token_id>(339); + tokenMap["private"] = static_cast<boost::wave::token_id>(340); + tokenMap["protected"] = static_cast<boost::wave::token_id>(341); + tokenMap["public"] = static_cast<boost::wave::token_id>(342); + tokenMap["register"] = static_cast<boost::wave::token_id>(343); + tokenMap["reinterpretcast"] = static_cast<boost::wave::token_id>(344); + tokenMap["return"] = static_cast<boost::wave::token_id>(345); + tokenMap["short"] = static_cast<boost::wave::token_id>(346); + tokenMap["signed"] = static_cast<boost::wave::token_id>(347); + tokenMap["sizeof"] = static_cast<boost::wave::token_id>(348); + tokenMap["static"] = static_cast<boost::wave::token_id>(349); + tokenMap["staticcast"] = static_cast<boost::wave::token_id>(350); + tokenMap["struct"] = static_cast<boost::wave::token_id>(351); + tokenMap["switch"] = static_cast<boost::wave::token_id>(352); + tokenMap["template"] = static_cast<boost::wave::token_id>(353); + tokenMap["this"] = static_cast<boost::wave::token_id>(354); + tokenMap["throw"] = static_cast<boost::wave::token_id>(355); + tokenMap["try"] = static_cast<boost::wave::token_id>(356); + tokenMap["typedef"] = static_cast<boost::wave::token_id>(357); + tokenMap["typeid"] = static_cast<boost::wave::token_id>(358); + tokenMap["typename"] = static_cast<boost::wave::token_id>(359); + tokenMap["union"] = static_cast<boost::wave::token_id>(360); + tokenMap["unsigned"] = static_cast<boost::wave::token_id>(361); + tokenMap["using"] = static_cast<boost::wave::token_id>(362); + tokenMap["virtual"] = static_cast<boost::wave::token_id>(363); + tokenMap["void"] = static_cast<boost::wave::token_id>(364); + tokenMap["volatile"] = static_cast<boost::wave::token_id>(365); + tokenMap["wchart"] = static_cast<boost::wave::token_id>(366); + tokenMap["while"] = static_cast<boost::wave::token_id>(367); + tokenMap["pp_define"] = static_cast<boost::wave::token_id>(368); + tokenMap["pp_if"] = static_cast<boost::wave::token_id>(369); + tokenMap["pp_ifdef"] = static_cast<boost::wave::token_id>(370); + tokenMap["pp_ifndef"] = static_cast<boost::wave::token_id>(371); + tokenMap["pp_else"] = static_cast<boost::wave::token_id>(372); + tokenMap["pp_elif"] = static_cast<boost::wave::token_id>(373); + tokenMap["pp_endif"] = static_cast<boost::wave::token_id>(374); + tokenMap["pp_error"] = static_cast<boost::wave::token_id>(375); + tokenMap["pp_line"] = static_cast<boost::wave::token_id>(376); + tokenMap["pp_pragma"] = static_cast<boost::wave::token_id>(377); + tokenMap["pp_undef"] = static_cast<boost::wave::token_id>(378); + tokenMap["pp_warning"] = static_cast<boost::wave::token_id>(379); + tokenMap["identifier"] = static_cast<boost::wave::token_id>(380); + tokenMap["octalint"] = static_cast<boost::wave::token_id>(381); + tokenMap["decimalint"] = static_cast<boost::wave::token_id>(382); + tokenMap["hexaint"] = static_cast<boost::wave::token_id>(383); + tokenMap["intlit"] = static_cast<boost::wave::token_id>(384); + tokenMap["longintlit"] = static_cast<boost::wave::token_id>(385); + tokenMap["floatlit"] = static_cast<boost::wave::token_id>(386); + tokenMap["ccomment"] = static_cast<boost::wave::token_id>(387); + tokenMap["cppcomment"] = static_cast<boost::wave::token_id>(388); + tokenMap["charlit"] = static_cast<boost::wave::token_id>(389); + tokenMap["stringlit"] = static_cast<boost::wave::token_id>(390); + tokenMap["contline"] = static_cast<boost::wave::token_id>(391); + tokenMap["space"] = static_cast<boost::wave::token_id>(392); + tokenMap["space2"] = static_cast<boost::wave::token_id>(393); + tokenMap["newline"] = static_cast<boost::wave::token_id>(394); + tokenMap["pound_pound"] = static_cast<boost::wave::token_id>(395); + tokenMap["pound"] = static_cast<boost::wave::token_id>(396); + tokenMap["any"] = static_cast<boost::wave::token_id>(397); + tokenMap["pp_include"] = static_cast<boost::wave::token_id>(398); + tokenMap["pp_qheader"] = static_cast<boost::wave::token_id>(399); + tokenMap["pp_hheader"] = static_cast<boost::wave::token_id>(400); + tokenMap["eof"] = static_cast<boost::wave::token_id>(401); + tokenMap["eoi"] = static_cast<boost::wave::token_id>(402); + tokenMap["pp_number"] = static_cast<boost::wave::token_id>(403); + tokenMap["msext_int8"] = static_cast<boost::wave::token_id>(404); + tokenMap["msext_int16"] = static_cast<boost::wave::token_id>(405); + tokenMap["msext_int32"] = static_cast<boost::wave::token_id>(406); + tokenMap["msext_int64"] = static_cast<boost::wave::token_id>(407); + tokenMap["msext_based"] = static_cast<boost::wave::token_id>(408); + tokenMap["msext_declspec"] = static_cast<boost::wave::token_id>(409); + tokenMap["msext_cdecl"] = static_cast<boost::wave::token_id>(410); + tokenMap["msext_fastcall"] = static_cast<boost::wave::token_id>(411); + tokenMap["msext_stdcall"] = static_cast<boost::wave::token_id>(412); + tokenMap["msext_try"] = static_cast<boost::wave::token_id>(413); + tokenMap["msext_except"] = static_cast<boost::wave::token_id>(414); + tokenMap["msext_finally"] = static_cast<boost::wave::token_id>(415); + tokenMap["msext_leave"] = static_cast<boost::wave::token_id>(416); + tokenMap["msext_inline"] = static_cast<boost::wave::token_id>(417); + tokenMap["msext_asm"] = static_cast<boost::wave::token_id>(418); + tokenMap["msext_region"] = static_cast<boost::wave::token_id>(419); + tokenMap["msext_endregion"] = static_cast<boost::wave::token_id>(420); + tokenMap["import"] = static_cast<boost::wave::token_id>(421); + } + + const TokenFilterToIdMap::const_iterator it = tokenMap.find(filter); + if (it != tokenMap.end()) + { + return it->second; + } + else + { + throw Vera::Structures::TokensError("unknown token filter requested"); + } +} + +bool matchAll(boost::wave::token_id) +{ + return true; +} + +bool matchTokenBaseId(boost::wave::token_id id, boost::wave::token_id ref) +{ + return BASEID_FROM_TOKEN(id) == ref; +} + +CompiledFilterSequence prepareCompiledFilter( + const Vera::Structures::Tokens::FilterSequence & filterSeq) +{ + CompiledFilterSequence ret; + + if (filterSeq.empty()) + { + // with empty filter all tokens should be accepted + ret.push_back(matchAll); + } + else + { + Vera::Structures::Tokens::FilterSequence::const_iterator it = filterSeq.begin(); + const Vera::Structures::Tokens::FilterSequence::const_iterator end = filterSeq.end(); + + for ( ; it != end; ++it) + { + ret.push_back(bind(matchTokenBaseId, _1, tokenIdFromTokenFilter(*it))); + } + } + + return ret; +} + +bool match(const CompiledFilterSequence & compiledFilter, boost::wave::token_id id) +{ + CompiledFilterSequence::const_iterator it = compiledFilter.begin(); + const CompiledFilterSequence::const_iterator end = compiledFilter.end(); + + for ( ; it != end; ++it) + { + if ((*it)(id)) + { + return true; + } + } + + return false; +} + +struct LineNumberComparator +{ + bool operator()(const TokenRef & left, const TokenRef & right) const + { + return left.line_ < right.line_; + } +}; + +void findRange(const TokenCollection & tokens, int fromLine, int toLine, + TokenCollection::const_iterator & beg, TokenCollection::const_iterator & end) +{ + const TokenRef tokenToCompareFrom(boost::wave::token_id(), fromLine, 0, 0); + beg = lower_bound(tokens.begin(), tokens.end(), tokenToCompareFrom, LineNumberComparator()); + + if (toLine < 0) + { + end = tokens.end(); + } + else + { + const TokenRef tokenToCompareTo(boost::wave::token_id(), toLine, 0, 0); + end = upper_bound(tokens.begin(), tokens.end(), tokenToCompareTo, LineNumberComparator()); + } +} + +} // unnamed namespace + +namespace Vera +{ +namespace Structures +{ + +void Tokens::parse(const SourceFiles::FileName & name, const FileContent & src) +{ + TokenCollection & tokensInFile = fileTokens_[name]; + + // wave throws exceptions when given an empty file + if (src.empty() == false) + { + try + { + typedef boost::wave::cpplexer::lex_token<> token_type; + typedef boost::wave::cpplexer::lex_iterator<token_type> lexer_type; + typedef token_type::position_type position_type; + + const position_type pos(name.c_str()); + lexer_type it = lexer_type(src.begin(), src.end(), pos, + boost::wave::language_support( + boost::wave::support_cpp | boost::wave::support_option_long_long)); + const lexer_type end = lexer_type(); + + const int lineCount = SourceLines::getLineCount(name); + + for ( ; it != end; ++it) + { + const boost::wave::token_id id(*it); + + const token_type::position_type pos = it->get_position(); + const std::string value = it->get_value().c_str(); + const int line = pos.get_line(); + const int column = pos.get_column() - 1; + const int length = static_cast<int>(value.size()); + + bool useReference = true; + if (id == boost::wave::T_NEWLINE || id == boost::wave::T_EOF || line > lineCount) + { + useReference = false; + } + else + { + const std::string & sourceLine = SourceLines::getLine(name, line); + if (column > static_cast<int>(sourceLine.size()) || + value != sourceLine.substr(column, length)) + { + useReference = false; + } + } + + if (useReference) + { + // the reference representation of the token is stored + + tokensInFile.push_back(TokenRef(id, line, column, length)); + } + else + { + // value of the token has no representation in the physical line + // so the real token value is stored in physicalTokens + + tokensInFile.push_back(TokenRef(id, line, column, length, value)); + } + } + } + catch (const boost::wave::cpplexer::cpplexer_exception & e) + { + std::ostringstream ss; + ss << "illegal token in column " << e.column_no() + << ", giving up (hint: fix the file or remove it from the working set)"; + Plugins::Reports::internal(name, e.line_no(), ss.str()); + } + } +} + +Tokens::TokenSequence Tokens::getTokens(const SourceFiles::FileName & fileName, + int fromLine, int fromColumn, int toLine, int toColumn, + const FilterSequence & filter) +{ + if ((fromLine < 1) || + (fromColumn < 0) || + (toLine > 0 && fromLine > toLine) || + (fromLine == toLine && toColumn >= 0 && fromColumn > toColumn)) + { + throw TokensError("illegal range of tokens requested by the script"); + } + + { + // lazy load and parse + const FileTokenCollection::const_iterator fit = fileTokens_.find(fileName); + if (fit == fileTokens_.end()) + { + SourceLines::loadFile(fileName); + } + } + + // here we know that the file is already loaded and parsed + // (or the exception was thrown in the above) + + const CompiledFilterSequence compiledFilter = prepareCompiledFilter(filter); + + const TokenCollection & tokensInFile = fileTokens_[fileName]; + + TokenSequence ret; + + TokenCollection::const_iterator begin; + TokenCollection::const_iterator end; + + findRange(tokensInFile, fromLine, toLine, begin, end); + + for (TokenCollection::const_iterator it = begin; it != end; ++it) + { + const TokenRef & token = *it; + + const int line = token.line_; + const int column = token.column_; + + if ((line > fromLine || (line == fromLine && column >= fromColumn)) && + (toLine <= 0 || (line < toLine || (line == toLine && column < toColumn)))) + { + if (match(compiledFilter, token.id_)) + { + std::string tokenName = boost::wave::get_token_name(token.id_).c_str(); + boost::algorithm::to_lower(tokenName); + + std::string value; + if (tokenName != "eof") + { + value = token.getTokenValue(fileName); + } + + ret.push_back(Token(value, line, column, tokenName)); + } + } + } + + return ret; +} + +} +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extern/vera/src/structures/Tokens.h Wed Nov 22 20:10:03 2017 +0100 @@ -0,0 +1,72 @@ +// +// 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) +// + +#ifndef TOKENS_H_INCLUDED +#define TOKENS_H_INCLUDED + +#include "SourceFiles.h" +#include <string> +#include <vector> + + +namespace Vera +{ +namespace Structures +{ + +class TokensError : public std::runtime_error +{ +public: + TokensError(const std::string & msg) : std::runtime_error(msg) {} +}; + +struct Token +{ + Token(const std::string & v, int ln, int cl, const std::string & n) + : value_(v), line_(ln), column_(cl), name_(n) {} + + Token() + : value_(""), line_(0), column_(0), name_("") {} + + bool operator==(Token const& t) const + { + return value_ == t.value_ + && line_ == t.line_ + && column_ == t.column_ + && name_ == t.name_; + } + + std::string value_; + int line_; + int column_; + std::string name_; +}; + + +class Tokens +{ +public: + typedef std::string FileContent; + + typedef std::vector<Token> TokenSequence; + + typedef std::string TokenFilter; + + typedef std::vector<TokenFilter> FilterSequence; + + static void parse(const SourceFiles::FileName & name, const FileContent & src); + + static TokenSequence getTokens(const SourceFiles::FileName & name, + int fromLine, int fromColumn, int toLine, int toColumn, + const FilterSequence & filter); +}; + +} // namespace Structures + +} // namespace Vera + +#endif // TOKENS_H_INCLUDED