aboutsummaryrefslogtreecommitdiff
path: root/src/Ninja.cpp
diff options
context:
space:
mode:
authordec05eba <0xdec05eba@gmail.com>2018-09-20 14:55:58 +0200
committerdec05eba <0xdec05eba@gmail.com>2018-09-20 14:56:00 +0200
commitefd1bdf5576ddcff21fecc0ff5efa4d53aa8d08d (patch)
tree66a3b4df93927cf89648a5534e4b0429b355d812 /src/Ninja.cpp
parent64104c32c09d56a3a60aed2ac9096f0985f15e15 (diff)
Add raw arg type, validate names
Diffstat (limited to 'src/Ninja.cpp')
-rw-r--r--src/Ninja.cpp81
1 files changed, 71 insertions, 10 deletions
diff --git a/src/Ninja.cpp b/src/Ninja.cpp
index 7b3212e..f74ab04 100644
--- a/src/Ninja.cpp
+++ b/src/Ninja.cpp
@@ -10,15 +10,75 @@ namespace ninja
{
if(!result.empty())
result += ' ';
- result += '\'';
- if(arg.type == NinjaArg::Type::VARIABLE)
- result += "$";
- result += arg.arg;
- result += '\'';
+
+ NinjaArg::Type argType = arg.type;
+ if(!arg.arg.empty() && arg.arg[0] == '$')
+ argType = NinjaArg::Type::RAW;
+
+ switch(argType)
+ {
+ case NinjaArg::Type::VALUE:
+ {
+ result += '\'' + arg.arg + '\'';
+ break;
+ }
+ case NinjaArg::Type::VARIABLE:
+ {
+ result += '$' + arg.arg;
+ break;
+ }
+ case NinjaArg::Type::RAW:
+ {
+ result += arg.arg;
+ break;
+ }
+ }
}
return result;
}
+ static bool isAlpha(char c)
+ {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+ }
+
+ static bool isNum(char c)
+ {
+ return c >= '0' && c <= '9';
+ }
+
+ static bool isAlnum(char c)
+ {
+ return isAlpha(c) || isNum(c);
+ }
+
+ static bool isValidName(const std::string &name)
+ {
+ if(name.empty())
+ return false;
+
+ if(name.size() > 100)
+ return false;
+
+ if(!isAlpha(name[0]) && name[0] != '_')
+ return false;
+
+ for(int i = 1; i < name.size(); ++i)
+ {
+ if(!isAlnum(name[i]) && name[i] != '_')
+ return false;
+ }
+
+ return true;
+ }
+
+ NinjaVariable::NinjaVariable(const std::string &_name) :
+ name(_name)
+ {
+ if(!isValidName(name))
+ throw NinjaException(NinjaError::INVALID_NAME, "Invalid variable name, has to match [a-zA-Z_]{1}[a-zA-Z0-9_]{0,98}");
+ }
+
NinjaRule::NinjaRule(NinjaBuildFile *_buildFile, const std::string &_name, const std::string &_command) :
buildFile(_buildFile),
name(_name),
@@ -42,6 +102,9 @@ namespace ninja
void NinjaBuildFile::defineGlobalVariable(const std::string &name, const std::string &value)
{
+ if(!isValidName(name))
+ throw NinjaException(NinjaError::INVALID_NAME, "Invalid global variable name, has to match [a-zA-Z_]{1}[a-zA-Z0-9_]{0,98}");
+
auto it = globalVariables.find(name);
if(it != globalVariables.end())
throw NinjaException(NinjaError::VARIABLE_ALREADY_DEFINED, "Global variable already defined: " + name);
@@ -50,6 +113,9 @@ namespace ninja
NinjaRule* NinjaBuildFile::createRule(const std::string &name, const std::vector<NinjaArg> &commandArgs)
{
+ if(!isValidName(name))
+ throw NinjaException(NinjaError::INVALID_NAME, "Invalid rule name, has to match [a-zA-Z_]{1}[a-zA-Z0-9_]{0,98}");
+
auto it = rules.find(name);
if(it != rules.end())
throw NinjaException(NinjaError::RULE_ALREADY_DEFINED, "Rule already defined: " + name);
@@ -61,11 +127,6 @@ namespace ninja
void NinjaBuildFile::build(const NinjaRule *rule, const std::string &in, const std::string &out, const std::vector<ninja::NinjaArgValue> &additionalArgs)
{
- for(const NinjaBuild &build : builds)
- {
- if(build.rule == rule)
- throw NinjaException(NinjaError::RULE_AREADY_BUILT, "Rule already built: " + rule->name);
- }
builds.push_back({ rule, in, out, additionalArgs });
}