Index: include/lldb/API/SBLaunchInfo.h =================================================================== --- include/lldb/API/SBLaunchInfo.h +++ include/lldb/API/SBLaunchInfo.h @@ -143,10 +143,9 @@ bool GetShellExpandArguments (); - - void - SetShellExpandArguments (bool glob); - + + void SetShellExpandArguments(bool expand); + uint32_t GetResumeCount (); Index: include/lldb/Host/Host.h =================================================================== --- include/lldb/Host/Host.h +++ include/lldb/Host/Host.h @@ -260,9 +260,8 @@ // argument magic the platform defines as part of its typical // user experience //------------------------------------------------------------------ - static Error - ShellExpandArguments (ProcessLaunchInfo &launch_info); - + static Error ShellExpandArguments(llvm::StringRef input, llvm::StringRef working_dir, std::vector &expanded); + static Error RunShellCommand (const char *command, // Shouldn't be NULL const char *working_dir, // Pass NULL to use the current working directory Index: include/lldb/Target/Platform.h =================================================================== --- include/lldb/Target/Platform.h +++ include/lldb/Target/Platform.h @@ -392,9 +392,8 @@ // argument magic the platform defines as part of its typical // user experience //------------------------------------------------------------------ - virtual Error - ShellExpandArguments (ProcessLaunchInfo &launch_info); - + virtual Error ShellExpandArguments(llvm::StringRef original, llvm::StringRef working_dir, std::vector &expanded); + //------------------------------------------------------------------ /// Kill process on a platform. //------------------------------------------------------------------ Index: source/Host/common/Host.cpp =================================================================== --- source/Host/common/Host.cpp +++ source/Host/common/Host.cpp @@ -48,6 +48,8 @@ #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Error.h" #include "lldb/Core/Log.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/MonitoringProcessLauncher.h" @@ -524,13 +526,83 @@ } Error -Host::RunShellCommand (const char *command, - const char *working_dir, - int *status_ptr, - int *signo_ptr, - std::string *command_output_ptr, - uint32_t timeout_sec, - bool run_in_default_shell) +Host::ShellExpandArguments(llvm::StringRef original, llvm::StringRef working_dir, std::vector &expanded) +{ + Error error; + FileSpec expand_tool_spec; + if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, expand_tool_spec)) + { + error.SetErrorString("could not find argdumper tool"); + return error; + } + expand_tool_spec.AppendPathComponent("argdumper"); + if (!expand_tool_spec.Exists()) + { + error.SetErrorString("could not find argdumper tool"); + return error; + } + + StreamString expand_command; + expand_command.Printf("%s %s", expand_tool_spec.GetPath().c_str(), original.data()); + + int status; + std::string output; + + RunShellCommand(expand_command.GetData(), working_dir.data(), &status, nullptr, &output, 10); + + if (status != 0) + { + error.SetErrorStringWithFormat("argdumper exited with error %d", status); + return error; + } + + auto data_sp = StructuredData::ParseJSON(output); + if (!data_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + auto dict_sp = data_sp->GetAsDictionary(); + if (!data_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments"); + if (!args_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + auto args_array_sp = args_sp->GetAsArray(); + if (!args_array_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + expanded.clear(); + for (size_t i = 0; i < args_array_sp->GetSize(); i++) + { + auto item_sp = args_array_sp->GetItemAtIndex(i); + if (!item_sp) + continue; + auto str_sp = item_sp->GetAsString(); + if (!str_sp) + continue; + + expanded.push_back(str_sp->GetValue()); + } + + return error; +} + +Error +Host::RunShellCommand(const char *command, const char *working_dir, int *status_ptr, int *signo_ptr, std::string *command_output_ptr, + uint32_t timeout_sec, bool run_in_default_shell) { Error error; ProcessLaunchInfo launch_info; Index: source/Host/freebsd/Host.cpp =================================================================== --- source/Host/freebsd/Host.cpp +++ source/Host/freebsd/Host.cpp @@ -311,10 +311,3 @@ static const lldb_private::UnixSignalsSP s_unix_signals_sp (new FreeBSDSignals ()); return s_unix_signals_sp; } - -Error -Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) -{ - return Error("unimplemented"); -} - Index: source/Host/linux/Host.cpp =================================================================== --- source/Host/linux/Host.cpp +++ source/Host/linux/Host.cpp @@ -416,9 +416,3 @@ static const lldb_private::UnixSignalsSP s_unix_signals_sp (new process_linux::LinuxSignals ()); return s_unix_signals_sp; } - -Error -Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) -{ - return Error("unimplemented"); -} Index: source/Host/macosx/Host.mm =================================================================== --- source/Host/macosx/Host.mm +++ source/Host/macosx/Host.mm @@ -45,7 +45,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" -#include "lldb/Core/StructuredData.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Endian.h" #include "lldb/Host/FileSpec.h" @@ -1352,91 +1351,6 @@ return error; } -Error -Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) -{ - Error error; - if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) - { - FileSpec expand_tool_spec; - if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, expand_tool_spec)) - { - error.SetErrorString("could not find argdumper tool"); - return error; - } - expand_tool_spec.AppendPathComponent("argdumper"); - if (!expand_tool_spec.Exists()) - { - error.SetErrorString("could not find argdumper tool"); - return error; - } - - std::string quoted_cmd_string; - launch_info.GetArguments().GetQuotedCommandString(quoted_cmd_string); - StreamString expand_command; - - expand_command.Printf("%s %s", - expand_tool_spec.GetPath().c_str(), - quoted_cmd_string.c_str()); - - int status; - std::string output; - RunShellCommand(expand_command.GetData(), launch_info.GetWorkingDirectory(), &status, nullptr, &output, 10); - - if (status != 0) - { - error.SetErrorStringWithFormat("argdumper exited with error %d", status); - return error; - } - - auto data_sp = StructuredData::ParseJSON(output); - if (!data_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto dict_sp = data_sp->GetAsDictionary(); - if (!data_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments"); - if (!args_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto args_array_sp = args_sp->GetAsArray(); - if (!args_array_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - launch_info.GetArguments().Clear(); - - for (size_t i = 0; - i < args_array_sp->GetSize(); - i++) - { - auto item_sp = args_array_sp->GetItemAtIndex(i); - if (!item_sp) - continue; - auto str_sp = item_sp->GetAsString(); - if (!str_sp) - continue; - - launch_info.GetArguments().AppendArgument(str_sp->GetValue().c_str()); - } - } - - return error; -} - HostThread Host::StartMonitoringChildProcess(Host::MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, bool monitor_signals) { Index: source/Host/windows/Host.cpp =================================================================== --- source/Host/windows/Host.cpp +++ source/Host/windows/Host.cpp @@ -220,89 +220,3 @@ { return HostThread(); } - -Error -Host::ShellExpandArguments (ProcessLaunchInfo &launch_info) -{ - Error error; - if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) - { - FileSpec expand_tool_spec; - if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, expand_tool_spec)) - { - error.SetErrorString("could not find argdumper tool"); - return error; - } - expand_tool_spec.AppendPathComponent("argdumper.exe"); - if (!expand_tool_spec.Exists()) - { - error.SetErrorString("could not find argdumper tool"); - return error; - } - - std::string quoted_cmd_string; - launch_info.GetArguments().GetQuotedCommandString(quoted_cmd_string); - std::replace(quoted_cmd_string.begin(), quoted_cmd_string.end(), '\\', '/'); - StreamString expand_command; - - expand_command.Printf("%s %s", - expand_tool_spec.GetPath().c_str(), - quoted_cmd_string.c_str()); - - int status; - std::string output; - RunShellCommand(expand_command.GetData(), launch_info.GetWorkingDirectory(), &status, nullptr, &output, 10); - - if (status != 0) - { - error.SetErrorStringWithFormat("argdumper exited with error %d", status); - return error; - } - - auto data_sp = StructuredData::ParseJSON(output); - if (!data_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto dict_sp = data_sp->GetAsDictionary(); - if (!data_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments"); - if (!args_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - auto args_array_sp = args_sp->GetAsArray(); - if (!args_array_sp) - { - error.SetErrorString("invalid JSON"); - return error; - } - - launch_info.GetArguments().Clear(); - - for (size_t i = 0; - i < args_array_sp->GetSize(); - i++) - { - auto item_sp = args_array_sp->GetItemAtIndex(i); - if (!item_sp) - continue; - auto str_sp = item_sp->GetAsString(); - if (!str_sp) - continue; - - launch_info.GetArguments().AppendArgument(str_sp->GetValue().c_str()); - } - } - - return error; -} Index: source/Target/Platform.cpp =================================================================== --- source/Target/Platform.cpp +++ source/Target/Platform.cpp @@ -1116,9 +1116,15 @@ } else if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) { - error = ShellExpandArguments(launch_info); + std::vector expanded_args; + std::string original_args; + launch_info.GetArguments().GetQuotedCommandString(original_args); + error = ShellExpandArguments(original_args.c_str(), launch_info.GetWorkingDirectory(), expanded_args); if (error.Fail()) return error; + launch_info.GetArguments().Clear(); + for (auto arg : expanded_args) + launch_info.GetArguments().AppendArgument(arg.c_str()); } if (log) @@ -1132,10 +1138,10 @@ } Error -Platform::ShellExpandArguments (ProcessLaunchInfo &launch_info) +Platform::ShellExpandArguments(llvm::StringRef original, llvm::StringRef working_dir, std::vector &expanded) { if (IsHost()) - return Host::ShellExpandArguments(launch_info); + return Host::ShellExpandArguments(original, working_dir, expanded); return Error("base lldb_private::Platform class can't expand arguments"); }