xaizek / zograscope (License: AGPLv3 only) (since 2018-12-07)
Mainly a syntax-aware diff that also provides a number of additional tools.
Commit ec1d0c4a99aa08a861cb08451580bdaa9afa23fb

Teach Traverser about lang attribute
Author: xaizek
Author date (UTC): 2022-04-25 11:49
Committer name: xaizek
Committer date (UTC): 2022-04-25 11:49
Parent(s): 2f0baa0071ef472026fa162ac8d9093761a9102a
Signing key: 99DC5E4DB05F6BE2
Tree: 194c7fea32b045be8836da06d03f55b20e1b10e5
File Lines added Lines deleted
src/Language.cpp 26 2
src/Language.hpp 2 0
src/tooling/Traverser.cpp 3 1
src/tooling/Traverser.hpp 2 2
tests/tests.hpp 22 0
tests/tooling/Traverser.cpp 46 0
tests/tooling/common.cpp 0 25
File src/Language.cpp changed (mode: 100644) (index f40d6f8..2b4b32a)
... ... namespace fs = boost::filesystem;
37 37
38 38 using boost::algorithm::to_lower_copy; using boost::algorithm::to_lower_copy;
39 39
40 static std::string simplifyLanguage(const std::string &lang);
40 41 static std::string detectLanguage(const std::string &stem, static std::string detectLanguage(const std::string &stem,
41 42 const std::string &ext); const std::string &ext);
42 43
 
... ... Language::create(const std::string &fileName, const std::string &l)
56 57 } }
57 58 } }
58 59
60 lang = simplifyLanguage(lang);
61
59 62 if (lang == "c") { if (lang == "c") {
60 63 return std::unique_ptr<C11Language>(new C11Language()); return std::unique_ptr<C11Language>(new C11Language());
61 64 } }
62 if (lang == "cxx" || lang == "srcml:cxx") {
65 if (lang == "cxx") {
63 66 return std::unique_ptr<SrcmlCxxLanguage>(new SrcmlCxxLanguage()); return std::unique_ptr<SrcmlCxxLanguage>(new SrcmlCxxLanguage());
64 67 } }
65 if (lang == "lua" || lang == "ts:lua") {
68 if (lang == "lua") {
66 69 return std::unique_ptr<TsLuaLanguage>(new TsLuaLanguage()); return std::unique_ptr<TsLuaLanguage>(new TsLuaLanguage());
67 70 } }
68 71 if (lang == "make") { if (lang == "make") {
 
... ... Language::matches(const std::string &fileName, const std::string &lang)
90 93 return false; return false;
91 94 } }
92 95
96 bool
97 Language::equal(const std::string &langA, const std::string &langB)
98 {
99 return !langA.empty()
100 && !langB.empty()
101 && simplifyLanguage(langA) == simplifyLanguage(langB);
102 }
103
104 // Removes parser prefixes from language ids or does nothing.
105 static std::string
106 simplifyLanguage(const std::string &lang)
107 {
108 if (lang == "srcml:cxx") {
109 return "cxx";
110 }
111 if (lang == "ts:lua") {
112 return "lua";
113 }
114 return lang;
115 }
116
93 117 // Determines language from normalized stem and extension of a file. // Determines language from normalized stem and extension of a file.
94 118 static std::string static std::string
95 119 detectLanguage(const std::string &stem, const std::string &ext) detectLanguage(const std::string &stem, const std::string &ext)
File src/Language.hpp changed (mode: 100644) (index 494fb7b..65c327a)
... ... public:
47 47 // Checks whether file matches given language. When `lang` is an empty // Checks whether file matches given language. When `lang` is an empty
48 48 // string any of supported languages is considered a match. // string any of supported languages is considered a match.
49 49 static bool matches(const std::string &fileName, const std::string &lang); static bool matches(const std::string &fileName, const std::string &lang);
50 // Checks whether two language ids are equal.
51 static bool equal(const std::string &langA, const std::string &langB);
50 52
51 53 public: public:
52 54 // Virtual destructor for a base class. // Virtual destructor for a base class.
File src/tooling/Traverser.cpp changed (mode: 100644) (index 671bb1f..dd0ada6)
... ... Traverser::search(const boost::filesystem::path &path)
57 57 if (!config.shouldProcessFile(file)) { if (!config.shouldProcessFile(file)) {
58 58 return false; return false;
59 59 } }
60 if (Language::matches(file, language)) {
60
61 if (Language::matches(file, language) ||
62 Language::equal(config.lookupAttrs(file).lang, language)) {
61 63 return callback(file); return callback(file);
62 64 } }
63 65 return false; return false;
File src/tooling/Traverser.hpp changed (mode: 100644) (index 782de6f..b559757)
... ... class Config;
28 28 // Discovers files matching specified arguments and invokes callback on them. // Discovers files matching specified arguments and invokes callback on them.
29 29 class Traverser class Traverser
30 30 { {
31 // Callback type.
31 // Callback type. Should return `true` to indicate positive visitation.
32 32 using callbackPrototype = bool(const std::string &path); using callbackPrototype = bool(const std::string &path);
33 33
34 34 public: public:
 
... ... public:
39 39 std::function<callbackPrototype> callback); std::function<callbackPrototype> callback);
40 40
41 41 public: public:
42 // Processes all specified paths.
42 // Processes all specified paths. Returns `true` if something was found.
43 43 bool search(); bool search();
44 44
45 45 private: private:
File tests/tests.hpp changed (mode: 100644) (index 79b79ee..4cf88d8)
26 26 #include <string> #include <string>
27 27 #include <vector> #include <vector>
28 28
29 #include <boost/filesystem/operations.hpp>
30
29 31 class Node; class Node;
30 32 class Tree; class Tree;
31 33
 
... ... private:
102 104 std::string path; // Path to the temporary directory. std::string path; // Path to the temporary directory.
103 105 }; };
104 106
107 class Chdir
108 {
109 public:
110 explicit Chdir(const std::string &where)
111 : previousPath(boost::filesystem::current_path())
112 { boost::filesystem::current_path(where); }
113
114 Chdir(const Chdir &rhs) = delete;
115 Chdir & operator=(const Chdir &rhs) = delete;
116
117 ~Chdir()
118 {
119 boost::system::error_code ec;
120 boost::filesystem::current_path(previousPath, ec);
121 }
122
123 private:
124 const boost::filesystem::path previousPath;
125 };
126
105 127 // Checks whether C source can be parsed or not. // Checks whether C source can be parsed or not.
106 128 bool cIsParsed(const std::string &str); bool cIsParsed(const std::string &str);
107 129
File tests/tooling/Traverser.cpp added (mode: 100644) (index 0000000..f508763)
1 // Copyright (C) 2022 xaizek <xaizek@posteo.net>
2 //
3 // This file is part of zograscope.
4 //
5 // zograscope is free software: you can redistribute it and/or modify
6 // it under the terms of version 3 of the GNU Affero General Public License as
7 // published by the Free Software Foundation.
8 //
9 // zograscope is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
13 //
14 // You should have received a copy of the GNU Affero General Public License
15 // along with zograscope. If not, see <http://www.gnu.org/licenses/>.
16
17 #include "Catch/catch.hpp"
18
19 #include <boost/filesystem/operations.hpp>
20
21 #include "tooling/Traverser.hpp"
22 #include "tooling/common.hpp"
23
24 #include "tests.hpp"
25
26 TEST_CASE("Traverser accounts for lang attribute", "[tooling][traverser]")
27 {
28 TempDir tempDir("config");
29 REQUIRE(boost::filesystem::create_directory(tempDir.str() + "/.zs"));
30 makeFile(tempDir.str() + "/test.c", { });
31 makeFile(tempDir.str() + "/.zs/attributes", { "test.c lang=make" });
32
33 std::vector<std::string> paths;
34 auto handler = [&](const std::string &path) {
35 paths.push_back(path);
36 return true;
37 };
38
39 Chdir chdirInsideTmpDir(tempDir.str());
40 Environment env;
41
42 Traverser traverser({ tempDir }, "make", env.getConfig(), handler);
43 CHECK(traverser.search());
44
45 CHECK(paths.size() == 1);
46 }
File tests/tooling/common.cpp changed (mode: 100644) (index ee2497e..0750cf1)
28 28
29 29 #include "tests.hpp" #include "tests.hpp"
30 30
31 namespace {
32
33 31 namespace fs = boost::filesystem; namespace fs = boost::filesystem;
34 32
35 class Chdir
36 {
37 public:
38 explicit Chdir(const std::string &where) : previousPath(fs::current_path())
39 {
40 fs::current_path(where);
41 }
42
43 Chdir(const Chdir &rhs) = delete;
44 Chdir & operator=(const Chdir &rhs) = delete;
45
46 ~Chdir()
47 {
48 boost::system::error_code ec;
49 fs::current_path(previousPath, ec);
50 }
51
52 private:
53 const fs::path previousPath;
54 };
55
56 }
57
58 33 TEST_CASE("Exception is thrown for files that don't exist", "[common]") TEST_CASE("Exception is thrown for files that don't exist", "[common]")
59 34 { {
60 35 Environment env; Environment env;
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/zograscope

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/zograscope

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master