diff options
Diffstat (limited to 'source/Interpreter/Args.cpp')
-rw-r--r-- | source/Interpreter/Args.cpp | 100 |
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; |