aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-09-24 15:19:56 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-06 07:28:02 +0200
commitd45e007aa8aee275904015bee5c114e95209a6db (patch)
treeb8b384f1048c6d5645dab74324eb5393d3350442
parenta64df87aa0cb30d3bbc755fc97eb782388b35b77 (diff)
Escape input arg, which usually is a filename
-rw-r--r--include/ninja/Ninja.hpp5
-rw-r--r--src/Ninja.cpp53
-rw-r--r--tests/main.cpp2
3 files changed, 55 insertions, 5 deletions
diff --git a/include/ninja/Ninja.hpp b/include/ninja/Ninja.hpp
index d0e3d50..3fed138 100644
--- a/include/ninja/Ninja.hpp
+++ b/include/ninja/Ninja.hpp
@@ -77,10 +77,12 @@ namespace ninja
public:
NinjaRule(NinjaBuildFile *buildFile, const std::string &name, const std::string &command);
NinjaBuild* build(const std::string &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
+ NinjaBuild* build(const std::vector<std::string> &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
const std::string name;
const std::string command;
std::string depFile;
+ std::string deps;
private:
NinjaBuildFile *buildFile;
};
@@ -88,7 +90,7 @@ namespace ninja
struct NinjaBuild
{
const NinjaRule *rule;
- const std::string in;
+ const std::vector<std::string> in;
const std::string out;
const std::vector<ninja::NinjaArgValue> additionalArgs;
const std::vector<NinjaBuild*> dependsOnBuilds;
@@ -103,6 +105,7 @@ namespace ninja
void defineGlobalVariable(const std::string &name, const std::string &value);
NinjaRule* createRule(const std::string &name, const std::vector<NinjaArg> &commandArgs);
NinjaBuild* build(const NinjaRule *rule, const std::string &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
+ NinjaBuild* build(const NinjaRule *rule, const std::vector<std::string> &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds = {});
std::string generate() const;
private:
diff --git a/src/Ninja.cpp b/src/Ninja.cpp
index 9b9e177..778e701 100644
--- a/src/Ninja.cpp
+++ b/src/Ninja.cpp
@@ -72,6 +72,32 @@ namespace ninja
return true;
}
+ static std::string escape(const std::string &str)
+ {
+ std::string result;
+ result.reserve(str.size());
+ for(char c : str)
+ {
+ if(c == '"')
+ result += "\\\"";
+ else
+ result += c;
+ }
+ return '"' + result + '"';
+ }
+
+ static std::string combine_escape(const std::vector<std::string> &strs)
+ {
+ std::string result;
+ for(const std::string &str : strs)
+ {
+ if(!result.empty())
+ result += ' ';
+ result += escape(str);
+ }
+ return result;
+ }
+
NinjaVariable::NinjaVariable(const std::string &_name) :
name(_name)
{
@@ -93,6 +119,11 @@ namespace ninja
{
delete rule.second;
}
+
+ for(NinjaBuild *build : builds)
+ {
+ delete build;
+ }
}
NinjaBuild* NinjaRule::build(const std::string &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds)
@@ -100,6 +131,11 @@ namespace ninja
return buildFile->build(this, in, out, additionalArgs, dependsOnBuilds);
}
+ NinjaBuild* NinjaRule::build(const std::vector<std::string> &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds)
+ {
+ return buildFile->build(this, in, out, additionalArgs, dependsOnBuilds);
+ }
+
void NinjaBuildFile::defineGlobalVariable(const std::string &name, const std::string &value)
{
if(!isValidName(name))
@@ -127,7 +163,14 @@ namespace ninja
NinjaBuild* NinjaBuildFile::build(const NinjaRule *rule, const std::string &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds)
{
- NinjaBuild *build = new NinjaBuild { rule, in, out, additionalArgs, dependsOnBuilds };
+ NinjaBuild *build = new NinjaBuild { rule, { in }, escape(out), additionalArgs, dependsOnBuilds };
+ builds.push_back(build);
+ return build;
+ }
+
+ NinjaBuild* NinjaBuildFile::build(const NinjaRule *rule, const std::vector<std::string> &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs, const std::vector<NinjaBuild*> &dependsOnBuilds)
+ {
+ NinjaBuild *build = new NinjaBuild { rule, in, escape(out), additionalArgs, dependsOnBuilds };
builds.push_back(build);
return build;
}
@@ -157,10 +200,14 @@ namespace ninja
result += "\n depfile = ";
result += rule.second->depFile;
}
+ if(!rule.second->deps.empty())
+ {
+ result += "\n deps = ";
+ result += rule.second->deps;
+ }
result += "\n\n";
}
- // TODO: enclose all names with quotes to escape whitespace?
for(const NinjaBuild *build : builds)
{
result += "build ";
@@ -168,7 +215,7 @@ namespace ninja
result += ": ";
result += build->rule->name;
result += ' ';
- result += build->in;
+ result += combine_escape(build->in);
if(!build->dependsOnBuilds.empty())
{
diff --git a/tests/main.cpp b/tests/main.cpp
index f0a9b5c..e89eb19 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -25,7 +25,7 @@ int main(int argc, char **argv)
NinjaArgValue argsValue = { argsVar, "$globalIncDir -std=c++14 -pedantic -fpie -MMD -MP '-Itest@exe' '-I..' -Wall -Wextra -Werror=return-type -fdiagnostics-show-option '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Winvalid-pch' -fstack-protector '-Og' -fexceptions -Wnon-virtual-dtor -g3 -D_FORTIFY_SOURCE=2 -D_GLIBCXX_ASSERTIONS -fasynchronous-unwind-tables" };
- compileCppRule->build("../../main.cpp", "test@exe/main.cpp.o", { argsValue });
+ compileCppRule->build("../../ma in\".cpp", "test@exe/main.cpp.o", { argsValue });
NinjaArgValue linkArgsValue = { linkArgsVar, "-Wl,--no-undefined,--as-needed -ldl -lm -pthread -pthread \"/home/dec05eba/git/libninja/sibs-build/debug/liblibninja.so\"" };
buildExeRule->build("test@exe/main.cpp.o", "test", { argsValue });