aboutsummaryrefslogtreecommitdiff
path: root/source/Interpreter/Args.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Interpreter/Args.cpp')
-rw-r--r--source/Interpreter/Args.cpp100
1 files changed, 86 insertions, 14 deletions
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp
index 81e6b0aa1dbc..d90ef1d256a4 100644
--- a/source/Interpreter/Args.cpp
+++ b/source/Interpreter/Args.cpp
@@ -83,19 +83,22 @@ Args::~Args ()
}
void
-Args::Dump (Stream *s)
+Args::Dump (Stream &s, const char *label_name) const
{
+ if (!label_name)
+ return;
+
const size_t argc = m_argv.size();
for (size_t i=0; i<argc; ++i)
{
- s->Indent();
+ s.Indent();
const char *arg_cstr = m_argv[i];
if (arg_cstr)
- s->Printf("argv[%zi]=\"%s\"\n", i, arg_cstr);
+ s.Printf("%s[%zi]=\"%s\"\n", label_name, i, arg_cstr);
else
- s->Printf("argv[%zi]=NULL\n", i);
+ s.Printf("%s[%zi]=NULL\n", label_name, i);
}
- s->EOL();
+ s.EOL();
}
bool
@@ -575,8 +578,8 @@ Args::ParseOptions (Options &options)
}
}
}
- Mutex::Locker options_locker(NULL);
- OptionParser::Prepare(options_locker);
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
int val;
while (1)
{
@@ -887,14 +890,43 @@ Args::StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t
}
const char *
-Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)
+Args::GetShellSafeArgument (const FileSpec& shell,
+ const char *unsafe_arg,
+ std::string &safe_arg)
{
+ struct ShellDescriptor
+ {
+ ConstString m_basename;
+ const char* m_escapables;
+ };
+
+ static ShellDescriptor g_Shells[] = {
+ {ConstString("bash")," '\"<>()&"},
+ {ConstString("tcsh")," '\"<>()&$"},
+ {ConstString("sh")," '\"<>()&"}
+ };
+
+ // safe minimal set
+ const char* escapables = " '\"";
+
+ if (auto basename = shell.GetFilename())
+ {
+ for (const auto& Shell : g_Shells)
+ {
+ if (Shell.m_basename == basename)
+ {
+ escapables = Shell.m_escapables;
+ break;
+ }
+ }
+ }
+
safe_arg.assign (unsafe_arg);
size_t prev_pos = 0;
while (prev_pos < safe_arg.size())
{
// Escape spaces and quotes
- size_t pos = safe_arg.find_first_of(" '\"", prev_pos);
+ size_t pos = safe_arg.find_first_of(escapables, prev_pos);
if (pos != std::string::npos)
{
safe_arg.insert (pos, 1, '\\');
@@ -906,7 +938,6 @@ Args::GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg)
return safe_arg.c_str();
}
-
int64_t
Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
{
@@ -1108,6 +1139,47 @@ Args::LongestCommonPrefix (std::string &common_prefix)
}
}
+bool
+Args::ContainsEnvironmentVariable(const char *env_var_name) const
+{
+ // Validate args.
+ if (!env_var_name)
+ return false;
+
+ // Check each arg to see if it matches the env var name.
+ for (size_t i = 0; i < GetArgumentCount(); ++i)
+ {
+ // Get the arg value.
+ const char *argument_value = GetArgumentAtIndex(i);
+ if (!argument_value)
+ continue;
+
+ // Check if we are the "{env_var_name}={env_var_value}" style.
+ const char *equal_p = strchr(argument_value, '=');
+ if (equal_p)
+ {
+ if (strncmp(env_var_name, argument_value,
+ equal_p - argument_value) == 0)
+ {
+ // We matched.
+ return true;
+ }
+ }
+ else
+ {
+ // We're a simple {env_var_name}-style entry.
+ if (strcmp(argument_value, env_var_name) == 0)
+ {
+ // We matched.
+ return true;
+ }
+ }
+ }
+
+ // We didn't find a match.
+ return false;
+}
+
size_t
Args::FindArgumentIndexForOption (Option *long_options, int long_options_index)
{
@@ -1190,8 +1262,8 @@ Args::ParseAliasOptions (Options &options,
}
}
- Mutex::Locker options_locker(NULL);
- OptionParser::Prepare(options_locker);
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
int val;
while (1)
{
@@ -1368,8 +1440,8 @@ Args::ParseArgsForCompletion
}
}
- Mutex::Locker options_locker(NULL);
- OptionParser::Prepare(options_locker);
+ std::unique_lock<std::mutex> lock;
+ OptionParser::Prepare(lock);
OptionParser::EnableError(false);
int val;