1ebc09c36SJim Ingham //===-- CommandObjectSource.cpp ---------------------------------*- C++ -*-===// 2ebc09c36SJim Ingham // 3ebc09c36SJim Ingham // The LLVM Compiler Infrastructure 4ebc09c36SJim Ingham // 5ebc09c36SJim Ingham // This file is distributed under the University of Illinois Open Source 6ebc09c36SJim Ingham // License. See LICENSE.TXT for details. 7ebc09c36SJim Ingham // 8ebc09c36SJim Ingham //===----------------------------------------------------------------------===// 9ebc09c36SJim Ingham 10ebc09c36SJim Ingham #include "CommandObjectCommands.h" 11ebc09c36SJim Ingham 12ebc09c36SJim Ingham // C Includes 13ebc09c36SJim Ingham // C++ Includes 14ebc09c36SJim Ingham // Other libraries and framework includes 150e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h" 160e5e5a79SGreg Clayton 17ebc09c36SJim Ingham // Project includes 18ebc09c36SJim Ingham #include "lldb/Core/Debugger.h" 1944d93782SGreg Clayton #include "lldb/Core/IOHandler.h" 20be93a35aSEnrico Granata #include "lldb/Core/StringList.h" 21de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h" 227594f14fSEnrico Granata #include "lldb/Interpreter/CommandHistory.h" 23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h" 24de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h" 25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h" 26012d4fcaSEnrico Granata #include "lldb/Interpreter/OptionValueBoolean.h" 277594f14fSEnrico Granata #include "lldb/Interpreter/OptionValueUInt64.h" 28ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h" 2999f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h" 30ebc09c36SJim Ingham 31ebc09c36SJim Ingham using namespace lldb; 32ebc09c36SJim Ingham using namespace lldb_private; 33ebc09c36SJim Ingham 34ebc09c36SJim Ingham //------------------------------------------------------------------------- 35ebc09c36SJim Ingham // CommandObjectCommandsSource 36ebc09c36SJim Ingham //------------------------------------------------------------------------- 37ebc09c36SJim Ingham 385a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed 39a5a97ebeSJim Ingham { 405a988416SJim Ingham public: 415a988416SJim Ingham CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 425a988416SJim Ingham CommandObjectParsed (interpreter, 435a988416SJim Ingham "command history", 445a988416SJim Ingham "Dump the history of commands in this session.", 455a988416SJim Ingham NULL), 465a988416SJim Ingham m_options (interpreter) 475a988416SJim Ingham { 485a988416SJim Ingham } 495a988416SJim Ingham 505a988416SJim Ingham ~CommandObjectCommandsHistory () {} 515a988416SJim Ingham 525a988416SJim Ingham virtual Options * 535a988416SJim Ingham GetOptions () 545a988416SJim Ingham { 555a988416SJim Ingham return &m_options; 565a988416SJim Ingham } 575a988416SJim Ingham 585a988416SJim Ingham protected: 59a5a97ebeSJim Ingham 60a5a97ebeSJim Ingham class CommandOptions : public Options 61a5a97ebeSJim Ingham { 62a5a97ebeSJim Ingham public: 63a5a97ebeSJim Ingham 64a5a97ebeSJim Ingham CommandOptions (CommandInterpreter &interpreter) : 657594f14fSEnrico Granata Options (interpreter), 667594f14fSEnrico Granata m_start_idx(0), 677594f14fSEnrico Granata m_stop_idx(0), 687594f14fSEnrico Granata m_count(0), 6963123b64SEnrico Granata m_clear(false) 70a5a97ebeSJim Ingham { 71a5a97ebeSJim Ingham } 72a5a97ebeSJim Ingham 73a5a97ebeSJim Ingham virtual 74a5a97ebeSJim Ingham ~CommandOptions (){} 75a5a97ebeSJim Ingham 76a5a97ebeSJim Ingham virtual Error 77a5a97ebeSJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 78a5a97ebeSJim Ingham { 79a5a97ebeSJim Ingham Error error; 803bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 81a5a97ebeSJim Ingham 82a5a97ebeSJim Ingham switch (short_option) 83a5a97ebeSJim Ingham { 84a5a97ebeSJim Ingham case 'c': 85c95f7e2aSPavel Labath error = m_count.SetValueFromString(option_arg,eVarSetOperationAssign); 86a5a97ebeSJim Ingham break; 87a5a97ebeSJim Ingham case 's': 887594f14fSEnrico Granata if (option_arg && strcmp("end", option_arg) == 0) 897594f14fSEnrico Granata { 907594f14fSEnrico Granata m_start_idx.SetCurrentValue(UINT64_MAX); 917594f14fSEnrico Granata m_start_idx.SetOptionWasSet(); 927594f14fSEnrico Granata } 937594f14fSEnrico Granata else 94c95f7e2aSPavel Labath error = m_start_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 957594f14fSEnrico Granata break; 967594f14fSEnrico Granata case 'e': 97c95f7e2aSPavel Labath error = m_stop_idx.SetValueFromString(option_arg,eVarSetOperationAssign); 987594f14fSEnrico Granata break; 9963123b64SEnrico Granata case 'C': 10063123b64SEnrico Granata m_clear.SetCurrentValue(true); 10163123b64SEnrico Granata m_clear.SetOptionWasSet(); 102a5a97ebeSJim Ingham break; 103a5a97ebeSJim Ingham default: 10486edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 105a5a97ebeSJim Ingham break; 106a5a97ebeSJim Ingham } 107a5a97ebeSJim Ingham 108a5a97ebeSJim Ingham return error; 109a5a97ebeSJim Ingham } 110a5a97ebeSJim Ingham 111a5a97ebeSJim Ingham void 112a5a97ebeSJim Ingham OptionParsingStarting () 113a5a97ebeSJim Ingham { 1147594f14fSEnrico Granata m_start_idx.Clear(); 1157594f14fSEnrico Granata m_stop_idx.Clear(); 1167594f14fSEnrico Granata m_count.Clear(); 11763123b64SEnrico Granata m_clear.Clear(); 118a5a97ebeSJim Ingham } 119a5a97ebeSJim Ingham 120a5a97ebeSJim Ingham const OptionDefinition* 121a5a97ebeSJim Ingham GetDefinitions () 122a5a97ebeSJim Ingham { 123a5a97ebeSJim Ingham return g_option_table; 124a5a97ebeSJim Ingham } 125a5a97ebeSJim Ingham 126a5a97ebeSJim Ingham // Options table: Required for subclasses of Options. 127a5a97ebeSJim Ingham 128a5a97ebeSJim Ingham static OptionDefinition g_option_table[]; 129a5a97ebeSJim Ingham 130a5a97ebeSJim Ingham // Instance variables to hold the values for command options. 131a5a97ebeSJim Ingham 1327594f14fSEnrico Granata OptionValueUInt64 m_start_idx; 1337594f14fSEnrico Granata OptionValueUInt64 m_stop_idx; 1347594f14fSEnrico Granata OptionValueUInt64 m_count; 13563123b64SEnrico Granata OptionValueBoolean m_clear; 136a5a97ebeSJim Ingham }; 137a5a97ebeSJim Ingham 138a5a97ebeSJim Ingham bool 1395a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 140a5a97ebeSJim Ingham { 14163123b64SEnrico Granata if (m_options.m_clear.GetCurrentValue() && m_options.m_clear.OptionWasSet()) 1427594f14fSEnrico Granata { 1437594f14fSEnrico Granata m_interpreter.GetCommandHistory().Clear(); 1447594f14fSEnrico Granata result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult); 1457594f14fSEnrico Granata } 1467594f14fSEnrico Granata else 1477594f14fSEnrico Granata { 1487594f14fSEnrico Granata if (m_options.m_start_idx.OptionWasSet() && m_options.m_stop_idx.OptionWasSet() && m_options.m_count.OptionWasSet()) 1497594f14fSEnrico Granata { 1507594f14fSEnrico Granata result.AppendError("--count, --start-index and --end-index cannot be all specified in the same invocation"); 1517594f14fSEnrico Granata result.SetStatus(lldb::eReturnStatusFailed); 1527594f14fSEnrico Granata } 1537594f14fSEnrico Granata else 1547594f14fSEnrico Granata { 15584400ec7SVirgile Bello std::pair<bool,uint64_t> start_idx(m_options.m_start_idx.OptionWasSet(),m_options.m_start_idx.GetCurrentValue()); 15684400ec7SVirgile Bello std::pair<bool,uint64_t> stop_idx(m_options.m_stop_idx.OptionWasSet(),m_options.m_stop_idx.GetCurrentValue()); 15784400ec7SVirgile Bello std::pair<bool,uint64_t> count(m_options.m_count.OptionWasSet(),m_options.m_count.GetCurrentValue()); 158a5a97ebeSJim Ingham 1597594f14fSEnrico Granata const CommandHistory& history(m_interpreter.GetCommandHistory()); 1607594f14fSEnrico Granata 1617594f14fSEnrico Granata if (start_idx.first && start_idx.second == UINT64_MAX) 1627594f14fSEnrico Granata { 1637594f14fSEnrico Granata if (count.first) 1647594f14fSEnrico Granata { 1657594f14fSEnrico Granata start_idx.second = history.GetSize() - count.second; 1667594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1677594f14fSEnrico Granata } 1687594f14fSEnrico Granata else if (stop_idx.first) 1697594f14fSEnrico Granata { 1707594f14fSEnrico Granata start_idx.second = stop_idx.second; 1717594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1727594f14fSEnrico Granata } 1737594f14fSEnrico Granata else 1747594f14fSEnrico Granata { 1757594f14fSEnrico Granata start_idx.second = 0; 1767594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1777594f14fSEnrico Granata } 1787594f14fSEnrico Granata } 1797594f14fSEnrico Granata else 1807594f14fSEnrico Granata { 1817594f14fSEnrico Granata if (!start_idx.first && !stop_idx.first && !count.first) 1827594f14fSEnrico Granata { 1837594f14fSEnrico Granata start_idx.second = 0; 1847594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1857594f14fSEnrico Granata } 1867594f14fSEnrico Granata else if (start_idx.first) 1877594f14fSEnrico Granata { 1887594f14fSEnrico Granata if (count.first) 1897594f14fSEnrico Granata { 1907594f14fSEnrico Granata stop_idx.second = start_idx.second + count.second - 1; 1917594f14fSEnrico Granata } 1927594f14fSEnrico Granata else if (!stop_idx.first) 1937594f14fSEnrico Granata { 1947594f14fSEnrico Granata stop_idx.second = history.GetSize() - 1; 1957594f14fSEnrico Granata } 1967594f14fSEnrico Granata } 1977594f14fSEnrico Granata else if (stop_idx.first) 1987594f14fSEnrico Granata { 1997594f14fSEnrico Granata if (count.first) 2007594f14fSEnrico Granata { 2017594f14fSEnrico Granata if (stop_idx.second >= count.second) 2027594f14fSEnrico Granata start_idx.second = stop_idx.second - count.second + 1; 2037594f14fSEnrico Granata else 2047594f14fSEnrico Granata start_idx.second = 0; 2057594f14fSEnrico Granata } 2067594f14fSEnrico Granata } 2077594f14fSEnrico Granata else /* if (count.first) */ 2087594f14fSEnrico Granata { 2097594f14fSEnrico Granata start_idx.second = 0; 2107594f14fSEnrico Granata stop_idx.second = count.second - 1; 2117594f14fSEnrico Granata } 2127594f14fSEnrico Granata } 2137594f14fSEnrico Granata history.Dump(result.GetOutputStream(), start_idx.second, stop_idx.second); 2147594f14fSEnrico Granata } 2157594f14fSEnrico Granata } 216a5a97ebeSJim Ingham return result.Succeeded(); 217a5a97ebeSJim Ingham 218a5a97ebeSJim Ingham } 2195a988416SJim Ingham 2205a988416SJim Ingham CommandOptions m_options; 221a5a97ebeSJim Ingham }; 222a5a97ebeSJim Ingham 223a5a97ebeSJim Ingham OptionDefinition 224a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 225a5a97ebeSJim Ingham { 226d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 227d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)."}, 228d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 229d37221dcSZachary Turner { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeBoolean, "Clears the current command history."}, 230d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 231a5a97ebeSJim Ingham }; 232a5a97ebeSJim Ingham 233a5a97ebeSJim Ingham 234a5a97ebeSJim Ingham //------------------------------------------------------------------------- 235a5a97ebeSJim Ingham // CommandObjectCommandsSource 236a5a97ebeSJim Ingham //------------------------------------------------------------------------- 237a5a97ebeSJim Ingham 2385a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed 239ebc09c36SJim Ingham { 2405a988416SJim Ingham public: 2415a988416SJim Ingham CommandObjectCommandsSource(CommandInterpreter &interpreter) : 2425a988416SJim Ingham CommandObjectParsed (interpreter, 2435a988416SJim Ingham "command source", 2445a988416SJim Ingham "Read in debugger commands from the file <filename> and execute them.", 2455a988416SJim Ingham NULL), 2465a988416SJim Ingham m_options (interpreter) 2475a988416SJim Ingham { 2485a988416SJim Ingham CommandArgumentEntry arg; 2495a988416SJim Ingham CommandArgumentData file_arg; 2505a988416SJim Ingham 2515a988416SJim Ingham // Define the first (and only) variant of this arg. 2525a988416SJim Ingham file_arg.arg_type = eArgTypeFilename; 2535a988416SJim Ingham file_arg.arg_repetition = eArgRepeatPlain; 2545a988416SJim Ingham 2555a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 2565a988416SJim Ingham arg.push_back (file_arg); 2575a988416SJim Ingham 2585a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 2595a988416SJim Ingham m_arguments.push_back (arg); 2605a988416SJim Ingham } 2615a988416SJim Ingham 2625a988416SJim Ingham ~CommandObjectCommandsSource () {} 2635a988416SJim Ingham 2645a988416SJim Ingham virtual const char* 2655a988416SJim Ingham GetRepeatCommand (Args ¤t_command_args, uint32_t index) 2665a988416SJim Ingham { 2675a988416SJim Ingham return ""; 2685a988416SJim Ingham } 2695a988416SJim Ingham 270c7bece56SGreg Clayton virtual int 2715a988416SJim Ingham HandleArgumentCompletion (Args &input, 2725a988416SJim Ingham int &cursor_index, 2735a988416SJim Ingham int &cursor_char_position, 2745a988416SJim Ingham OptionElementVector &opt_element_vector, 2755a988416SJim Ingham int match_start_point, 2765a988416SJim Ingham int max_return_elements, 2775a988416SJim Ingham bool &word_complete, 2785a988416SJim Ingham StringList &matches) 2795a988416SJim Ingham { 2805a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2815a988416SJim Ingham completion_str.erase (cursor_char_position); 2825a988416SJim Ingham 2835a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2845a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 2855a988416SJim Ingham completion_str.c_str(), 2865a988416SJim Ingham match_start_point, 2875a988416SJim Ingham max_return_elements, 2885a988416SJim Ingham NULL, 2895a988416SJim Ingham word_complete, 2905a988416SJim Ingham matches); 2915a988416SJim Ingham return matches.GetSize(); 2925a988416SJim Ingham } 2935a988416SJim Ingham 2945a988416SJim Ingham virtual Options * 2955a988416SJim Ingham GetOptions () 2965a988416SJim Ingham { 2975a988416SJim Ingham return &m_options; 2985a988416SJim Ingham } 2995a988416SJim Ingham 3005a988416SJim Ingham protected: 301e16c50a1SJim Ingham 302e16c50a1SJim Ingham class CommandOptions : public Options 303e16c50a1SJim Ingham { 304e16c50a1SJim Ingham public: 305e16c50a1SJim Ingham 306eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 307012d4fcaSEnrico Granata Options (interpreter), 308340b0309SGreg Clayton m_stop_on_error (true), 309340b0309SGreg Clayton m_silent_run (false), 310340b0309SGreg Clayton m_stop_on_continue (true) 311eb0103f2SGreg Clayton { 312eb0103f2SGreg Clayton } 313e16c50a1SJim Ingham 314e16c50a1SJim Ingham virtual 315e16c50a1SJim Ingham ~CommandOptions (){} 316e16c50a1SJim Ingham 317e16c50a1SJim Ingham virtual Error 318f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 319e16c50a1SJim Ingham { 320e16c50a1SJim Ingham Error error; 3213bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 322e16c50a1SJim Ingham 323e16c50a1SJim Ingham switch (short_option) 324e16c50a1SJim Ingham { 325e16c50a1SJim Ingham case 'e': 326c95f7e2aSPavel Labath error = m_stop_on_error.SetValueFromString(option_arg); 327e16c50a1SJim Ingham break; 328340b0309SGreg Clayton 329e16c50a1SJim Ingham case 'c': 330c95f7e2aSPavel Labath error = m_stop_on_continue.SetValueFromString(option_arg); 331e16c50a1SJim Ingham break; 332340b0309SGreg Clayton 33360986174SMichael Sartain case 's': 334c95f7e2aSPavel Labath error = m_silent_run.SetValueFromString(option_arg); 33560986174SMichael Sartain break; 336340b0309SGreg Clayton 337e16c50a1SJim Ingham default: 33886edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 339e16c50a1SJim Ingham break; 340e16c50a1SJim Ingham } 341e16c50a1SJim Ingham 342e16c50a1SJim Ingham return error; 343e16c50a1SJim Ingham } 344e16c50a1SJim Ingham 345e16c50a1SJim Ingham void 346f6b8b581SGreg Clayton OptionParsingStarting () 347e16c50a1SJim Ingham { 348012d4fcaSEnrico Granata m_stop_on_error.Clear(); 349340b0309SGreg Clayton m_silent_run.Clear(); 350340b0309SGreg Clayton m_stop_on_continue.Clear(); 351e16c50a1SJim Ingham } 352e16c50a1SJim Ingham 353e0d378b3SGreg Clayton const OptionDefinition* 354e16c50a1SJim Ingham GetDefinitions () 355e16c50a1SJim Ingham { 356e16c50a1SJim Ingham return g_option_table; 357e16c50a1SJim Ingham } 358e16c50a1SJim Ingham 359e16c50a1SJim Ingham // Options table: Required for subclasses of Options. 360e16c50a1SJim Ingham 361e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 362e16c50a1SJim Ingham 363e16c50a1SJim Ingham // Instance variables to hold the values for command options. 364e16c50a1SJim Ingham 365012d4fcaSEnrico Granata OptionValueBoolean m_stop_on_error; 366340b0309SGreg Clayton OptionValueBoolean m_silent_run; 367340b0309SGreg Clayton OptionValueBoolean m_stop_on_continue; 368e16c50a1SJim Ingham }; 369e16c50a1SJim Ingham 370ebc09c36SJim Ingham bool 3715a988416SJim Ingham DoExecute(Args& command, CommandReturnObject &result) 372ebc09c36SJim Ingham { 373c7bece56SGreg Clayton const size_t argc = command.GetArgumentCount(); 374ebc09c36SJim Ingham if (argc == 1) 375ebc09c36SJim Ingham { 3765a988416SJim Ingham const char *filename = command.GetArgumentAtIndex(0); 377ebc09c36SJim Ingham 3781ee3853fSJohnny Chen FileSpec cmd_file (filename, true); 379e16c50a1SJim Ingham ExecutionContext *exe_ctx = NULL; // Just use the default context. 380ebc09c36SJim Ingham 381340b0309SGreg Clayton // If any options were set, then use them 382340b0309SGreg Clayton if (m_options.m_stop_on_error.OptionWasSet() || 383340b0309SGreg Clayton m_options.m_silent_run.OptionWasSet() || 384340b0309SGreg Clayton m_options.m_stop_on_continue.OptionWasSet()) 385340b0309SGreg Clayton { 386340b0309SGreg Clayton // Use user set settings 38726c7bf93SJim Ingham CommandInterpreterRunOptions options; 38826c7bf93SJim Ingham options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue()); 38926c7bf93SJim Ingham options.SetStopOnError (m_options.m_stop_on_error.GetCurrentValue()); 3907d8555c4SJim Ingham options.SetEchoCommands (!m_options.m_silent_run.GetCurrentValue()); 3917d8555c4SJim Ingham options.SetPrintResults (!m_options.m_silent_run.GetCurrentValue()); 39226c7bf93SJim Ingham 393e16c50a1SJim Ingham m_interpreter.HandleCommandsFromFile (cmd_file, 394e16c50a1SJim Ingham exe_ctx, 39526c7bf93SJim Ingham options, 396e16c50a1SJim Ingham result); 397340b0309SGreg Clayton 398340b0309SGreg Clayton } 399340b0309SGreg Clayton else 400340b0309SGreg Clayton { 401340b0309SGreg Clayton // No options were set, inherit any settings from nested "command source" commands, 402340b0309SGreg Clayton // or set to sane default settings... 40326c7bf93SJim Ingham CommandInterpreterRunOptions options; 404340b0309SGreg Clayton m_interpreter.HandleCommandsFromFile (cmd_file, 405340b0309SGreg Clayton exe_ctx, 40626c7bf93SJim Ingham options, 407340b0309SGreg Clayton result); 408340b0309SGreg Clayton 409340b0309SGreg Clayton } 410ebc09c36SJim Ingham } 411ebc09c36SJim Ingham else 412ebc09c36SJim Ingham { 413ebc09c36SJim Ingham result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName()); 414ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 415ebc09c36SJim Ingham } 416ebc09c36SJim Ingham return result.Succeeded(); 417ebc09c36SJim Ingham 418ebc09c36SJim Ingham } 4195a988416SJim Ingham CommandOptions m_options; 420ebc09c36SJim Ingham }; 421ebc09c36SJim Ingham 422e0d378b3SGreg Clayton OptionDefinition 423e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] = 424e16c50a1SJim Ingham { 425d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 426d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 427d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true don't echo commands while executing."}, 428d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 429e16c50a1SJim Ingham }; 430e16c50a1SJim Ingham 431ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias 432ebc09c36SJim Ingham //------------------------------------------------------------------------- 433ebc09c36SJim Ingham // CommandObjectCommandsAlias 434ebc09c36SJim Ingham //------------------------------------------------------------------------- 435ebc09c36SJim Ingham 436be93a35aSEnrico Granata static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 437be93a35aSEnrico Granata "You must define a Python function with this signature:\n" 43844d93782SGreg Clayton "def my_command_impl(debugger, args, result, internal_dict):\n"; 439be93a35aSEnrico Granata 440be93a35aSEnrico Granata 4415a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw 442ebc09c36SJim Ingham { 443be93a35aSEnrico Granata 444be93a35aSEnrico Granata 445ebc09c36SJim Ingham public: 446a7015092SGreg Clayton CommandObjectCommandsAlias (CommandInterpreter &interpreter) : 4475a988416SJim Ingham CommandObjectRaw (interpreter, 4480e5e5a79SGreg Clayton "command alias", 449e3d26315SCaroline Tice "Allow users to define their own debugger command abbreviations.", 450405fe67fSCaroline Tice NULL) 451ebc09c36SJim Ingham { 452ebc09c36SJim Ingham SetHelpLong( 453*ea671fbdSKate Stone "'alias' allows the user to create a short-cut or abbreviation for long \ 454*ea671fbdSKate Stone commands, multi-word commands, and commands that take particular options. \ 455*ea671fbdSKate Stone Below are some simple examples of how one might use the 'alias' command:" R"( 456*ea671fbdSKate Stone 457*ea671fbdSKate Stone (lldb) command alias sc script 458*ea671fbdSKate Stone 459*ea671fbdSKate Stone Creates the abbreviation 'sc' for the 'script' command. 460*ea671fbdSKate Stone 461*ea671fbdSKate Stone (lldb) command alias bp breakpoint 462*ea671fbdSKate Stone 463*ea671fbdSKate Stone )" " Creates the abbreviation 'bp' for the 'breakpoint' command. Since \ 464*ea671fbdSKate Stone breakpoint commands are two-word commands, the user would still need to \ 465*ea671fbdSKate Stone enter the second word after 'bp', e.g. 'bp enable' or 'bp delete'." R"( 466*ea671fbdSKate Stone 467*ea671fbdSKate Stone (lldb) command alias bpl breakpoint list 468*ea671fbdSKate Stone 469*ea671fbdSKate Stone Creates the abbreviation 'bpl' for the two-word command 'breakpoint list'. 470*ea671fbdSKate Stone 471*ea671fbdSKate Stone )" "An alias can include some options for the command, with the values either \ 472*ea671fbdSKate Stone filled in at the time the alias is created, or specified as positional \ 473*ea671fbdSKate Stone arguments, to be filled in when the alias is invoked. The following example \ 474*ea671fbdSKate Stone shows how to create aliases with options:" R"( 475*ea671fbdSKate Stone 476*ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2 477*ea671fbdSKate Stone 478*ea671fbdSKate Stone )" " Creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \ 479*ea671fbdSKate Stone options already part of the alias. So if the user wants to set a breakpoint \ 480*ea671fbdSKate Stone by file and line without explicitly having to use the -f and -l options, the \ 481*ea671fbdSKate Stone user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \ 482*ea671fbdSKate Stone for the actual arguments that will be passed when the alias command is used. \ 483*ea671fbdSKate Stone The number in the placeholder refers to the position/order the actual value \ 484*ea671fbdSKate Stone occupies when the alias is used. All the occurrences of '%1' in the alias \ 485*ea671fbdSKate Stone will be replaced with the first argument, all the occurrences of '%2' in the \ 486*ea671fbdSKate Stone alias will be replaced with the second argument, and so on. This also allows \ 487*ea671fbdSKate Stone actual arguments to be used multiple times within an alias (see 'process \ 488*ea671fbdSKate Stone launch' example below)." R"( 489*ea671fbdSKate Stone 490*ea671fbdSKate Stone )" "Note: the positional arguments must substitute as whole words in the resultant \ 491*ea671fbdSKate Stone command, so you can't at present do something like this to append the file extension \ 492*ea671fbdSKate Stone \".cpp\":" R"( 493*ea671fbdSKate Stone 494*ea671fbdSKate Stone (lldb) command alias bcppfl breakpoint set -f %1.cpp -l %2 495*ea671fbdSKate Stone 496*ea671fbdSKate Stone )" "For more complex aliasing, use the \"command regex\" command instead. In the \ 497*ea671fbdSKate Stone 'bfl' case above, the actual file value will be filled in with the first argument \ 498*ea671fbdSKate Stone following 'bfl' and the actual line number value will be filled in with the second \ 499*ea671fbdSKate Stone argument. The user would use this alias as follows:" R"( 500*ea671fbdSKate Stone 501*ea671fbdSKate Stone (lldb) command alias bfl breakpoint set -f %1 -l %2 502*ea671fbdSKate Stone (lldb) bfl my-file.c 137 503*ea671fbdSKate Stone 504*ea671fbdSKate Stone This would be the same as if the user had entered 'breakpoint set -f my-file.c -l 137'. 505*ea671fbdSKate Stone 506*ea671fbdSKate Stone Another example: 507*ea671fbdSKate Stone 508*ea671fbdSKate Stone (lldb) command alias pltty process launch -s -o %1 -e %1 509*ea671fbdSKate Stone (lldb) pltty /dev/tty0 510*ea671fbdSKate Stone 511*ea671fbdSKate Stone Interpreted as 'process launch -s -o /dev/tty0 -e /dev/tty0' 512*ea671fbdSKate Stone 513*ea671fbdSKate Stone )" "If the user always wanted to pass the same value to a particular option, the \ 514*ea671fbdSKate Stone alias could be defined with that value directly in the alias as a constant, \ 515*ea671fbdSKate Stone rather than using a positional placeholder:" R"( 516*ea671fbdSKate Stone 517*ea671fbdSKate Stone (lldb) command alias bl3 breakpoint set -f %1 -l 3 518*ea671fbdSKate Stone 519*ea671fbdSKate Stone Always sets a breakpoint on line 3 of whatever file is indicated.)" 520*ea671fbdSKate Stone ); 521ebc09c36SJim Ingham 522405fe67fSCaroline Tice CommandArgumentEntry arg1; 523405fe67fSCaroline Tice CommandArgumentEntry arg2; 524405fe67fSCaroline Tice CommandArgumentEntry arg3; 525405fe67fSCaroline Tice CommandArgumentData alias_arg; 526405fe67fSCaroline Tice CommandArgumentData cmd_arg; 527405fe67fSCaroline Tice CommandArgumentData options_arg; 528405fe67fSCaroline Tice 529405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 530405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 531405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 532405fe67fSCaroline Tice 533405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 534405fe67fSCaroline Tice arg1.push_back (alias_arg); 535405fe67fSCaroline Tice 536405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 537405fe67fSCaroline Tice cmd_arg.arg_type = eArgTypeCommandName; 538405fe67fSCaroline Tice cmd_arg.arg_repetition = eArgRepeatPlain; 539405fe67fSCaroline Tice 540405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 541405fe67fSCaroline Tice arg2.push_back (cmd_arg); 542405fe67fSCaroline Tice 543405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 544405fe67fSCaroline Tice options_arg.arg_type = eArgTypeAliasOptions; 545405fe67fSCaroline Tice options_arg.arg_repetition = eArgRepeatOptional; 546405fe67fSCaroline Tice 547405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 548405fe67fSCaroline Tice arg3.push_back (options_arg); 549405fe67fSCaroline Tice 550405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 551405fe67fSCaroline Tice m_arguments.push_back (arg1); 552405fe67fSCaroline Tice m_arguments.push_back (arg2); 553405fe67fSCaroline Tice m_arguments.push_back (arg3); 554ebc09c36SJim Ingham } 555ebc09c36SJim Ingham 556ebc09c36SJim Ingham ~CommandObjectCommandsAlias () 557ebc09c36SJim Ingham { 558ebc09c36SJim Ingham } 559ebc09c36SJim Ingham 5605a988416SJim Ingham protected: 5615a988416SJim Ingham virtual bool 5625a988416SJim Ingham DoExecute (const char *raw_command_line, CommandReturnObject &result) 563844d2303SCaroline Tice { 564844d2303SCaroline Tice Args args (raw_command_line); 565844d2303SCaroline Tice std::string raw_command_string (raw_command_line); 566844d2303SCaroline Tice 567844d2303SCaroline Tice size_t argc = args.GetArgumentCount(); 568844d2303SCaroline Tice 569844d2303SCaroline Tice if (argc < 2) 570844d2303SCaroline Tice { 571844d2303SCaroline Tice result.AppendError ("'alias' requires at least two arguments"); 572844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 573844d2303SCaroline Tice return false; 574844d2303SCaroline Tice } 575844d2303SCaroline Tice 576844d2303SCaroline Tice // Get the alias command. 577844d2303SCaroline Tice 578844d2303SCaroline Tice const std::string alias_command = args.GetArgumentAtIndex (0); 579844d2303SCaroline Tice 580844d2303SCaroline Tice // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 581844d2303SCaroline Tice // does the stripping itself. 582844d2303SCaroline Tice size_t pos = raw_command_string.find (alias_command); 583844d2303SCaroline Tice if (pos == 0) 584844d2303SCaroline Tice { 585844d2303SCaroline Tice raw_command_string = raw_command_string.substr (alias_command.size()); 586844d2303SCaroline Tice pos = raw_command_string.find_first_not_of (' '); 587844d2303SCaroline Tice if ((pos != std::string::npos) && (pos > 0)) 588844d2303SCaroline Tice raw_command_string = raw_command_string.substr (pos); 589844d2303SCaroline Tice } 590844d2303SCaroline Tice else 591844d2303SCaroline Tice { 592844d2303SCaroline Tice result.AppendError ("Error parsing command string. No alias created."); 593844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 594844d2303SCaroline Tice return false; 595844d2303SCaroline Tice } 596844d2303SCaroline Tice 597844d2303SCaroline Tice 598844d2303SCaroline Tice // Verify that the command is alias-able. 599844d2303SCaroline Tice if (m_interpreter.CommandExists (alias_command.c_str())) 600844d2303SCaroline Tice { 601844d2303SCaroline Tice result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 602844d2303SCaroline Tice alias_command.c_str()); 603844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 604844d2303SCaroline Tice return false; 605844d2303SCaroline Tice } 606844d2303SCaroline Tice 607844d2303SCaroline Tice // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 608844d2303SCaroline Tice // raw_command_string is returned with the name of the command object stripped off the front. 609844d2303SCaroline Tice CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 610844d2303SCaroline Tice 611844d2303SCaroline Tice if (!cmd_obj) 612844d2303SCaroline Tice { 61386edbf41SGreg Clayton result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command." 614844d2303SCaroline Tice " No alias created.", raw_command_string.c_str()); 615844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 616844d2303SCaroline Tice return false; 617844d2303SCaroline Tice } 618844d2303SCaroline Tice else if (!cmd_obj->WantsRawCommandString ()) 619844d2303SCaroline Tice { 620844d2303SCaroline Tice // Note that args was initialized with the original command, and has not been updated to this point. 621844d2303SCaroline Tice // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 6225a988416SJim Ingham return HandleAliasingNormalCommand (args, result); 623844d2303SCaroline Tice } 624844d2303SCaroline Tice else 625844d2303SCaroline Tice { 6265a988416SJim Ingham return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result); 6275a988416SJim Ingham } 6285a988416SJim Ingham return result.Succeeded(); 6295a988416SJim Ingham } 6305a988416SJim Ingham 6315a988416SJim Ingham bool 6325a988416SJim Ingham HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result) 6335a988416SJim Ingham { 634844d2303SCaroline Tice // Verify & handle any options/arguments passed to the alias command 635844d2303SCaroline Tice 636844d2303SCaroline Tice OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 637844d2303SCaroline Tice OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 638844d2303SCaroline Tice 6395a988416SJim Ingham CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false); 640844d2303SCaroline Tice 641ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp)) 642844d2303SCaroline Tice { 643844d2303SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 644ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 645844d2303SCaroline Tice return false; 646844d2303SCaroline Tice } 647844d2303SCaroline Tice 648844d2303SCaroline Tice // Create the alias 649844d2303SCaroline Tice if (m_interpreter.AliasExists (alias_command.c_str()) 650844d2303SCaroline Tice || m_interpreter.UserCommandExists (alias_command.c_str())) 651844d2303SCaroline Tice { 652844d2303SCaroline Tice OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 653844d2303SCaroline Tice if (temp_option_arg_sp.get()) 654844d2303SCaroline Tice { 655844d2303SCaroline Tice if (option_arg_vector->size() == 0) 656844d2303SCaroline Tice m_interpreter.RemoveAliasOptions (alias_command.c_str()); 657844d2303SCaroline Tice } 658844d2303SCaroline Tice result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 659844d2303SCaroline Tice alias_command.c_str()); 660844d2303SCaroline Tice } 661844d2303SCaroline Tice 662472362e6SCaroline Tice if (cmd_obj_sp) 663472362e6SCaroline Tice { 664844d2303SCaroline Tice m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); 665844d2303SCaroline Tice if (option_arg_vector->size() > 0) 666844d2303SCaroline Tice m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 667844d2303SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 668844d2303SCaroline Tice } 669472362e6SCaroline Tice else 670472362e6SCaroline Tice { 671472362e6SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 672472362e6SCaroline Tice result.SetStatus (eReturnStatusFailed); 673472362e6SCaroline Tice } 674844d2303SCaroline Tice return result.Succeeded (); 675844d2303SCaroline Tice } 676ebc09c36SJim Ingham 677ebc09c36SJim Ingham bool 6785a988416SJim Ingham HandleAliasingNormalCommand (Args& args, CommandReturnObject &result) 679ebc09c36SJim Ingham { 680867b185dSCaroline Tice size_t argc = args.GetArgumentCount(); 681ebc09c36SJim Ingham 682ebc09c36SJim Ingham if (argc < 2) 683ebc09c36SJim Ingham { 684ebc09c36SJim Ingham result.AppendError ("'alias' requires at least two arguments"); 685ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 686ebc09c36SJim Ingham return false; 687ebc09c36SJim Ingham } 688ebc09c36SJim Ingham 689ebc09c36SJim Ingham const std::string alias_command = args.GetArgumentAtIndex(0); 690ebc09c36SJim Ingham const std::string actual_command = args.GetArgumentAtIndex(1); 691ebc09c36SJim Ingham 692ebc09c36SJim Ingham args.Shift(); // Shift the alias command word off the argument vector. 693ebc09c36SJim Ingham args.Shift(); // Shift the old command word off the argument vector. 694ebc09c36SJim Ingham 695ebc09c36SJim Ingham // Verify that the command is alias'able, and get the appropriate command object. 696ebc09c36SJim Ingham 697a7015092SGreg Clayton if (m_interpreter.CommandExists (alias_command.c_str())) 698ebc09c36SJim Ingham { 699ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 700ebc09c36SJim Ingham alias_command.c_str()); 701ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 702ebc09c36SJim Ingham } 703ebc09c36SJim Ingham else 704ebc09c36SJim Ingham { 705a7015092SGreg Clayton CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 706ebc09c36SJim Ingham CommandObjectSP subcommand_obj_sp; 707ebc09c36SJim Ingham bool use_subcommand = false; 708ebc09c36SJim Ingham if (command_obj_sp.get()) 709ebc09c36SJim Ingham { 710ebc09c36SJim Ingham CommandObject *cmd_obj = command_obj_sp.get(); 711c982c768SGreg Clayton CommandObject *sub_cmd_obj = NULL; 712ebc09c36SJim Ingham OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 713ebc09c36SJim Ingham OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 714ebc09c36SJim Ingham 715844d2303SCaroline Tice while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 716ebc09c36SJim Ingham { 717ebc09c36SJim Ingham if (argc >= 3) 718ebc09c36SJim Ingham { 719ebc09c36SJim Ingham const std::string sub_command = args.GetArgumentAtIndex(0); 720ebc09c36SJim Ingham assert (sub_command.length() != 0); 721998255bfSGreg Clayton subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str()); 722ebc09c36SJim Ingham if (subcommand_obj_sp.get()) 723ebc09c36SJim Ingham { 724ebc09c36SJim Ingham sub_cmd_obj = subcommand_obj_sp.get(); 725ebc09c36SJim Ingham use_subcommand = true; 726ebc09c36SJim Ingham args.Shift(); // Shift the sub_command word off the argument vector. 727844d2303SCaroline Tice cmd_obj = sub_cmd_obj; 728ebc09c36SJim Ingham } 729ebc09c36SJim Ingham else 730ebc09c36SJim Ingham { 731f415eeb4SCaroline Tice result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 732f415eeb4SCaroline Tice "Unable to create alias.\n", 733f415eeb4SCaroline Tice sub_command.c_str(), actual_command.c_str()); 734ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 735ebc09c36SJim Ingham return false; 736ebc09c36SJim Ingham } 737ebc09c36SJim Ingham } 738ebc09c36SJim Ingham } 739ebc09c36SJim Ingham 740ebc09c36SJim Ingham // Verify & handle any options/arguments passed to the alias command 741ebc09c36SJim Ingham 742ebc09c36SJim Ingham if (args.GetArgumentCount () > 0) 743ebc09c36SJim Ingham { 744ca90c47eSCaroline Tice CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 745ebc09c36SJim Ingham if (use_subcommand) 746ca90c47eSCaroline Tice tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 747ca90c47eSCaroline Tice 748ca90c47eSCaroline Tice std::string args_string; 749ca90c47eSCaroline Tice args.GetCommandString (args_string); 750ca90c47eSCaroline Tice 751ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp)) 752ebc09c36SJim Ingham { 753ca90c47eSCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 754ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 755e7941795SCaroline Tice return false; 756867b185dSCaroline Tice } 757867b185dSCaroline Tice } 758867b185dSCaroline Tice 759ebc09c36SJim Ingham // Create the alias. 760ebc09c36SJim Ingham 761a7015092SGreg Clayton if (m_interpreter.AliasExists (alias_command.c_str()) 762a7015092SGreg Clayton || m_interpreter.UserCommandExists (alias_command.c_str())) 763ebc09c36SJim Ingham { 764a7015092SGreg Clayton OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 765ebc09c36SJim Ingham if (tmp_option_arg_sp.get()) 766ebc09c36SJim Ingham { 767ebc09c36SJim Ingham if (option_arg_vector->size() == 0) 768a7015092SGreg Clayton m_interpreter.RemoveAliasOptions (alias_command.c_str()); 769ebc09c36SJim Ingham } 770ebc09c36SJim Ingham result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 771ebc09c36SJim Ingham alias_command.c_str()); 772ebc09c36SJim Ingham } 773ebc09c36SJim Ingham 774ebc09c36SJim Ingham if (use_subcommand) 775a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp); 776ebc09c36SJim Ingham else 777a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp); 778ebc09c36SJim Ingham if (option_arg_vector->size() > 0) 779a7015092SGreg Clayton m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 780ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 781ebc09c36SJim Ingham } 782ebc09c36SJim Ingham else 783ebc09c36SJim Ingham { 784ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 785ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 786e7941795SCaroline Tice return false; 787ebc09c36SJim Ingham } 788ebc09c36SJim Ingham } 789ebc09c36SJim Ingham 790ebc09c36SJim Ingham return result.Succeeded(); 791ebc09c36SJim Ingham } 7925a988416SJim Ingham 793ebc09c36SJim Ingham }; 794ebc09c36SJim Ingham 795ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias 796ebc09c36SJim Ingham //------------------------------------------------------------------------- 797ebc09c36SJim Ingham // CommandObjectCommandsUnalias 798ebc09c36SJim Ingham //------------------------------------------------------------------------- 799ebc09c36SJim Ingham 8005a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed 801ebc09c36SJim Ingham { 802ebc09c36SJim Ingham public: 803a7015092SGreg Clayton CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 8045a988416SJim Ingham CommandObjectParsed (interpreter, 8050e5e5a79SGreg Clayton "command unalias", 80686ddae50SCaroline Tice "Allow the user to remove/delete a user-defined command abbreviation.", 807405fe67fSCaroline Tice NULL) 808ebc09c36SJim Ingham { 809405fe67fSCaroline Tice CommandArgumentEntry arg; 810405fe67fSCaroline Tice CommandArgumentData alias_arg; 811405fe67fSCaroline Tice 812405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 813405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 814405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 815405fe67fSCaroline Tice 816405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 817405fe67fSCaroline Tice arg.push_back (alias_arg); 818405fe67fSCaroline Tice 819405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 820405fe67fSCaroline Tice m_arguments.push_back (arg); 821ebc09c36SJim Ingham } 822ebc09c36SJim Ingham 823ebc09c36SJim Ingham ~CommandObjectCommandsUnalias() 824ebc09c36SJim Ingham { 825ebc09c36SJim Ingham } 826ebc09c36SJim Ingham 8275a988416SJim Ingham protected: 828ebc09c36SJim Ingham bool 8295a988416SJim Ingham DoExecute (Args& args, CommandReturnObject &result) 830ebc09c36SJim Ingham { 831ebc09c36SJim Ingham CommandObject::CommandMap::iterator pos; 832ebc09c36SJim Ingham CommandObject *cmd_obj; 833ebc09c36SJim Ingham 834ebc09c36SJim Ingham if (args.GetArgumentCount() != 0) 835ebc09c36SJim Ingham { 836ebc09c36SJim Ingham const char *command_name = args.GetArgumentAtIndex(0); 837a7015092SGreg Clayton cmd_obj = m_interpreter.GetCommandObject(command_name); 838ebc09c36SJim Ingham if (cmd_obj) 839ebc09c36SJim Ingham { 840a7015092SGreg Clayton if (m_interpreter.CommandExists (command_name)) 841ebc09c36SJim Ingham { 842b547278cSGreg Clayton if (cmd_obj->IsRemovable()) 843b547278cSGreg Clayton { 844b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is not an alias, it is a debugger command which can be removed using the 'command delete' command.\n", 845b547278cSGreg Clayton command_name); 846b547278cSGreg Clayton } 847b547278cSGreg Clayton else 848b547278cSGreg Clayton { 849ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 850ebc09c36SJim Ingham command_name); 851b547278cSGreg Clayton } 852ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 853ebc09c36SJim Ingham } 854ebc09c36SJim Ingham else 855ebc09c36SJim Ingham { 856ebc09c36SJim Ingham 857a7015092SGreg Clayton if (m_interpreter.RemoveAlias (command_name) == false) 858ebc09c36SJim Ingham { 859a7015092SGreg Clayton if (m_interpreter.AliasExists (command_name)) 860ebc09c36SJim Ingham result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 861ebc09c36SJim Ingham command_name); 862ebc09c36SJim Ingham else 863ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 864ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 865ebc09c36SJim Ingham } 866ebc09c36SJim Ingham else 867ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 868ebc09c36SJim Ingham } 869ebc09c36SJim Ingham } 870ebc09c36SJim Ingham else 871ebc09c36SJim Ingham { 872ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 873ebc09c36SJim Ingham "current list of commands.\n", 874ebc09c36SJim Ingham command_name); 875ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 876ebc09c36SJim Ingham } 877ebc09c36SJim Ingham } 878ebc09c36SJim Ingham else 879ebc09c36SJim Ingham { 880ebc09c36SJim Ingham result.AppendError ("must call 'unalias' with a valid alias"); 881ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 882ebc09c36SJim Ingham } 883ebc09c36SJim Ingham 884ebc09c36SJim Ingham return result.Succeeded(); 885ebc09c36SJim Ingham } 886ebc09c36SJim Ingham }; 887ebc09c36SJim Ingham 888b547278cSGreg Clayton #pragma mark CommandObjectCommandsDelete 889b547278cSGreg Clayton //------------------------------------------------------------------------- 890b547278cSGreg Clayton // CommandObjectCommandsDelete 891b547278cSGreg Clayton //------------------------------------------------------------------------- 892b547278cSGreg Clayton 893b547278cSGreg Clayton class CommandObjectCommandsDelete : public CommandObjectParsed 894b547278cSGreg Clayton { 895b547278cSGreg Clayton public: 896b547278cSGreg Clayton CommandObjectCommandsDelete (CommandInterpreter &interpreter) : 897b547278cSGreg Clayton CommandObjectParsed (interpreter, 898b547278cSGreg Clayton "command delete", 899b547278cSGreg Clayton "Allow the user to delete user-defined regular expression, python or multi-word commands.", 900b547278cSGreg Clayton NULL) 901b547278cSGreg Clayton { 902b547278cSGreg Clayton CommandArgumentEntry arg; 903b547278cSGreg Clayton CommandArgumentData alias_arg; 904b547278cSGreg Clayton 905b547278cSGreg Clayton // Define the first (and only) variant of this arg. 906b547278cSGreg Clayton alias_arg.arg_type = eArgTypeCommandName; 907b547278cSGreg Clayton alias_arg.arg_repetition = eArgRepeatPlain; 908b547278cSGreg Clayton 909b547278cSGreg Clayton // There is only one variant this argument could be; put it into the argument entry. 910b547278cSGreg Clayton arg.push_back (alias_arg); 911b547278cSGreg Clayton 912b547278cSGreg Clayton // Push the data for the first argument into the m_arguments vector. 913b547278cSGreg Clayton m_arguments.push_back (arg); 914b547278cSGreg Clayton } 915b547278cSGreg Clayton 916b547278cSGreg Clayton ~CommandObjectCommandsDelete() 917b547278cSGreg Clayton { 918b547278cSGreg Clayton } 919b547278cSGreg Clayton 920b547278cSGreg Clayton protected: 921b547278cSGreg Clayton bool 922b547278cSGreg Clayton DoExecute (Args& args, CommandReturnObject &result) 923b547278cSGreg Clayton { 924b547278cSGreg Clayton CommandObject::CommandMap::iterator pos; 925b547278cSGreg Clayton 926b547278cSGreg Clayton if (args.GetArgumentCount() != 0) 927b547278cSGreg Clayton { 928b547278cSGreg Clayton const char *command_name = args.GetArgumentAtIndex(0); 929b547278cSGreg Clayton if (m_interpreter.CommandExists (command_name)) 930b547278cSGreg Clayton { 931b547278cSGreg Clayton if (m_interpreter.RemoveCommand (command_name)) 932b547278cSGreg Clayton { 933b547278cSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 934b547278cSGreg Clayton } 935b547278cSGreg Clayton else 936b547278cSGreg Clayton { 937b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 938b547278cSGreg Clayton command_name); 939b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 940b547278cSGreg Clayton } 941b547278cSGreg Clayton } 942b547278cSGreg Clayton else 943b547278cSGreg Clayton { 944b547278cSGreg Clayton result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a current list of commands.\n", 945b547278cSGreg Clayton command_name); 946b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 947b547278cSGreg Clayton } 948b547278cSGreg Clayton } 949b547278cSGreg Clayton else 950b547278cSGreg Clayton { 951b547278cSGreg Clayton result.AppendErrorWithFormat ("must call '%s' with one or more valid user defined regular expression, python or multi-word command names", GetCommandName ()); 952b547278cSGreg Clayton result.SetStatus (eReturnStatusFailed); 953b547278cSGreg Clayton } 954b547278cSGreg Clayton 955b547278cSGreg Clayton return result.Succeeded(); 956b547278cSGreg Clayton } 957b547278cSGreg Clayton }; 958b547278cSGreg Clayton 959de164aaaSGreg Clayton //------------------------------------------------------------------------- 960de164aaaSGreg Clayton // CommandObjectCommandsAddRegex 961de164aaaSGreg Clayton //------------------------------------------------------------------------- 9625a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex 963de164aaaSGreg Clayton 96444d93782SGreg Clayton class CommandObjectCommandsAddRegex : 96544d93782SGreg Clayton public CommandObjectParsed, 966ea508635SGreg Clayton public IOHandlerDelegateMultiline 967de164aaaSGreg Clayton { 968de164aaaSGreg Clayton public: 969de164aaaSGreg Clayton CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 9705a988416SJim Ingham CommandObjectParsed (interpreter, 9710e5e5a79SGreg Clayton "command regex", 972de164aaaSGreg Clayton "Allow the user to create a regular expression command.", 9730e5e5a79SGreg Clayton "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 974ea508635SGreg Clayton IOHandlerDelegateMultiline ("", IOHandlerDelegate::Completion::LLDBCommand), 975de164aaaSGreg Clayton m_options (interpreter) 976de164aaaSGreg Clayton { 977*ea671fbdSKate Stone SetHelpLong(R"( 978*ea671fbdSKate Stone )" "This command allows the user to create powerful regular expression commands \ 979*ea671fbdSKate Stone with substitutions. The regular expressions and substitutions are specified \ 980*ea671fbdSKate Stone using the regular expression substitution format of:" R"( 981*ea671fbdSKate Stone 982*ea671fbdSKate Stone s/<regex>/<subst>/ 983*ea671fbdSKate Stone 984*ea671fbdSKate Stone )" "<regex> is a regular expression that can use parenthesis to capture regular \ 985*ea671fbdSKate Stone expression input and substitute the captured matches in the output using %1 \ 986*ea671fbdSKate Stone for the first match, %2 for the second, and so on." R"( 987*ea671fbdSKate Stone 988*ea671fbdSKate Stone )" "The regular expressions can all be specified on the command line if more than \ 989*ea671fbdSKate Stone one argument is provided. If just the command name is provided on the command \ 990*ea671fbdSKate Stone line, then the regular expressions and substitutions can be entered on separate \ 991*ea671fbdSKate Stone lines, followed by an empty line to terminate the command definition." R"( 992*ea671fbdSKate Stone 993*ea671fbdSKate Stone EXAMPLES 994*ea671fbdSKate Stone 995*ea671fbdSKate Stone )" "The following example will define a regular expression command named 'f' that \ 996*ea671fbdSKate Stone will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if \ 997*ea671fbdSKate Stone a number follows 'f':" R"( 998*ea671fbdSKate Stone 999*ea671fbdSKate Stone (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/')" 10000e5e5a79SGreg Clayton ); 1001de164aaaSGreg Clayton } 1002de164aaaSGreg Clayton 1003de164aaaSGreg Clayton ~CommandObjectCommandsAddRegex() 1004de164aaaSGreg Clayton { 1005de164aaaSGreg Clayton } 1006de164aaaSGreg Clayton 1007de164aaaSGreg Clayton 10085a988416SJim Ingham protected: 100944d93782SGreg Clayton 1010ea508635SGreg Clayton void 1011ea508635SGreg Clayton IOHandlerActivated (IOHandler &io_handler) override 101244d93782SGreg Clayton { 101344d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 101444d93782SGreg Clayton if (output_sp) 101544d93782SGreg Clayton { 101644d93782SGreg Clayton output_sp->PutCString("Enter one of more sed substitution commands in the form: 's/<regex>/<subst>/'.\nTerminate the substitution list with an empty line.\n"); 101744d93782SGreg Clayton output_sp->Flush(); 101844d93782SGreg Clayton } 101944d93782SGreg Clayton } 102044d93782SGreg Clayton 1021ea508635SGreg Clayton void 1022ea508635SGreg Clayton IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override 102344d93782SGreg Clayton { 102444d93782SGreg Clayton io_handler.SetIsDone(true); 102544d93782SGreg Clayton if (m_regex_cmd_ap.get()) 102644d93782SGreg Clayton { 102744d93782SGreg Clayton StringList lines; 102844d93782SGreg Clayton if (lines.SplitIntoLines (data)) 102944d93782SGreg Clayton { 103044d93782SGreg Clayton const size_t num_lines = lines.GetSize(); 103144d93782SGreg Clayton bool check_only = false; 103244d93782SGreg Clayton for (size_t i=0; i<num_lines; ++i) 103344d93782SGreg Clayton { 103444d93782SGreg Clayton llvm::StringRef bytes_strref (lines[i]); 103544d93782SGreg Clayton Error error = AppendRegexSubstitution (bytes_strref, check_only); 103644d93782SGreg Clayton if (error.Fail()) 103744d93782SGreg Clayton { 103844d93782SGreg Clayton if (!m_interpreter.GetDebugger().GetCommandInterpreter().GetBatchCommandMode()) 103944d93782SGreg Clayton { 104044d93782SGreg Clayton StreamSP out_stream = m_interpreter.GetDebugger().GetAsyncOutputStream(); 104144d93782SGreg Clayton out_stream->Printf("error: %s\n", error.AsCString()); 104244d93782SGreg Clayton } 104344d93782SGreg Clayton } 104444d93782SGreg Clayton } 104544d93782SGreg Clayton } 104644d93782SGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 104744d93782SGreg Clayton { 104844d93782SGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 104944d93782SGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 105044d93782SGreg Clayton } 105144d93782SGreg Clayton } 105244d93782SGreg Clayton } 105344d93782SGreg Clayton 1054de164aaaSGreg Clayton bool 1055b0a1814fSEric Christopher DoExecute (Args& command, CommandReturnObject &result) override 1056de164aaaSGreg Clayton { 10575a988416SJim Ingham const size_t argc = command.GetArgumentCount(); 10580e5e5a79SGreg Clayton if (argc == 0) 1059de164aaaSGreg Clayton { 106069c12ccbSJason Molenda result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 10610e5e5a79SGreg Clayton result.SetStatus (eReturnStatusFailed); 10620e5e5a79SGreg Clayton } 10630e5e5a79SGreg Clayton else 10640e5e5a79SGreg Clayton { 10650e5e5a79SGreg Clayton Error error; 10665a988416SJim Ingham const char *name = command.GetArgumentAtIndex(0); 1067de164aaaSGreg Clayton m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 1068de164aaaSGreg Clayton name, 1069de164aaaSGreg Clayton m_options.GetHelp (), 1070de164aaaSGreg Clayton m_options.GetSyntax (), 1071b547278cSGreg Clayton 10, 1072b547278cSGreg Clayton 0, 1073b547278cSGreg Clayton true)); 10740e5e5a79SGreg Clayton 10750e5e5a79SGreg Clayton if (argc == 1) 10760e5e5a79SGreg Clayton { 107744d93782SGreg Clayton Debugger &debugger = m_interpreter.GetDebugger(); 1078e30f11d9SKate Stone bool color_prompt = debugger.GetUseColor(); 107944d93782SGreg Clayton const bool multiple_lines = true; // Get multiple lines 108044d93782SGreg Clayton IOHandlerSP io_handler_sp (new IOHandlerEditline (debugger, 1081e30f11d9SKate Stone IOHandler::Type::Other, 108273d80faaSGreg Clayton "lldb-regex", // Name of input reader for history 1083ea508635SGreg Clayton "> ", // Prompt 1084e30f11d9SKate Stone NULL, // Continuation prompt 108544d93782SGreg Clayton multiple_lines, 1086e30f11d9SKate Stone color_prompt, 1087f6913cd7SGreg Clayton 0, // Don't show line numbers 108844d93782SGreg Clayton *this)); 108944d93782SGreg Clayton 109044d93782SGreg Clayton if (io_handler_sp) 1091de164aaaSGreg Clayton { 109244d93782SGreg Clayton debugger.PushIOHandler(io_handler_sp); 1093de164aaaSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 1094de164aaaSGreg Clayton } 1095de164aaaSGreg Clayton } 1096de164aaaSGreg Clayton else 1097de164aaaSGreg Clayton { 10980e5e5a79SGreg Clayton for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 10990e5e5a79SGreg Clayton { 11005a988416SJim Ingham llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 110144d93782SGreg Clayton bool check_only = false; 110244d93782SGreg Clayton error = AppendRegexSubstitution (arg_strref, check_only); 11030e5e5a79SGreg Clayton if (error.Fail()) 11040e5e5a79SGreg Clayton break; 11050e5e5a79SGreg Clayton } 11060e5e5a79SGreg Clayton 11070e5e5a79SGreg Clayton if (error.Success()) 11080e5e5a79SGreg Clayton { 11090e5e5a79SGreg Clayton AddRegexCommandToInterpreter(); 11100e5e5a79SGreg Clayton } 11110e5e5a79SGreg Clayton } 11120e5e5a79SGreg Clayton if (error.Fail()) 11130e5e5a79SGreg Clayton { 11140e5e5a79SGreg Clayton result.AppendError (error.AsCString()); 1115de164aaaSGreg Clayton result.SetStatus (eReturnStatusFailed); 1116de164aaaSGreg Clayton } 11170e5e5a79SGreg Clayton } 11180e5e5a79SGreg Clayton 1119de164aaaSGreg Clayton return result.Succeeded(); 1120de164aaaSGreg Clayton } 1121de164aaaSGreg Clayton 11220e5e5a79SGreg Clayton Error 112344d93782SGreg Clayton AppendRegexSubstitution (const llvm::StringRef ®ex_sed, bool check_only) 1124de164aaaSGreg Clayton { 11250e5e5a79SGreg Clayton Error error; 11260e5e5a79SGreg Clayton 11270e5e5a79SGreg Clayton if (m_regex_cmd_ap.get() == NULL) 1128de164aaaSGreg Clayton { 11290e5e5a79SGreg Clayton error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 11300e5e5a79SGreg Clayton (int)regex_sed.size(), 11310e5e5a79SGreg Clayton regex_sed.data()); 11320e5e5a79SGreg Clayton return error; 1133de164aaaSGreg Clayton } 11340e5e5a79SGreg Clayton 11350e5e5a79SGreg Clayton size_t regex_sed_size = regex_sed.size(); 11360e5e5a79SGreg Clayton 11370e5e5a79SGreg Clayton if (regex_sed_size <= 1) 11380e5e5a79SGreg Clayton { 11390e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 11400e5e5a79SGreg Clayton (int)regex_sed.size(), 11410e5e5a79SGreg Clayton regex_sed.data()); 11420e5e5a79SGreg Clayton return error; 11430e5e5a79SGreg Clayton } 11440e5e5a79SGreg Clayton 11450e5e5a79SGreg Clayton if (regex_sed[0] != 's') 11460e5e5a79SGreg Clayton { 11470e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 11480e5e5a79SGreg Clayton (int)regex_sed.size(), 11490e5e5a79SGreg Clayton regex_sed.data()); 11500e5e5a79SGreg Clayton return error; 11510e5e5a79SGreg Clayton } 11520e5e5a79SGreg Clayton const size_t first_separator_char_pos = 1; 11530e5e5a79SGreg Clayton // use the char that follows 's' as the regex separator character 11540e5e5a79SGreg Clayton // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 11550e5e5a79SGreg Clayton const char separator_char = regex_sed[first_separator_char_pos]; 11560e5e5a79SGreg Clayton const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 11570e5e5a79SGreg Clayton 11580e5e5a79SGreg Clayton if (second_separator_char_pos == std::string::npos) 11590e5e5a79SGreg Clayton { 1160ea508635SGreg Clayton error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s' in '%.*s'", 11610e5e5a79SGreg Clayton separator_char, 11620e5e5a79SGreg Clayton (int)(regex_sed.size() - first_separator_char_pos - 1), 1163ea508635SGreg Clayton regex_sed.data() + (first_separator_char_pos + 1), 1164ea508635SGreg Clayton (int)regex_sed.size(), 1165ea508635SGreg Clayton regex_sed.data()); 11660e5e5a79SGreg Clayton return error; 11670e5e5a79SGreg Clayton } 11680e5e5a79SGreg Clayton 11690e5e5a79SGreg Clayton const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 11700e5e5a79SGreg Clayton 11710e5e5a79SGreg Clayton if (third_separator_char_pos == std::string::npos) 11720e5e5a79SGreg Clayton { 1173ea508635SGreg Clayton error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s' in '%.*s'", 11740e5e5a79SGreg Clayton separator_char, 11750e5e5a79SGreg Clayton (int)(regex_sed.size() - second_separator_char_pos - 1), 1176ea508635SGreg Clayton regex_sed.data() + (second_separator_char_pos + 1), 1177ea508635SGreg Clayton (int)regex_sed.size(), 1178ea508635SGreg Clayton regex_sed.data()); 11790e5e5a79SGreg Clayton return error; 11800e5e5a79SGreg Clayton } 11810e5e5a79SGreg Clayton 11820e5e5a79SGreg Clayton if (third_separator_char_pos != regex_sed_size - 1) 11830e5e5a79SGreg Clayton { 11840e5e5a79SGreg Clayton // Make sure that everything that follows the last regex 11850e5e5a79SGreg Clayton // separator char 11860e5e5a79SGreg Clayton if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 11870e5e5a79SGreg Clayton { 11880e5e5a79SGreg Clayton error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 11890e5e5a79SGreg Clayton (int)third_separator_char_pos + 1, 11900e5e5a79SGreg Clayton regex_sed.data(), 11910e5e5a79SGreg Clayton (int)(regex_sed.size() - third_separator_char_pos - 1), 11920e5e5a79SGreg Clayton regex_sed.data() + (third_separator_char_pos + 1)); 11930e5e5a79SGreg Clayton return error; 11940e5e5a79SGreg Clayton } 11950e5e5a79SGreg Clayton 11960e5e5a79SGreg Clayton } 11970e5e5a79SGreg Clayton else if (first_separator_char_pos + 1 == second_separator_char_pos) 11980e5e5a79SGreg Clayton { 11990e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 12000e5e5a79SGreg Clayton separator_char, 12010e5e5a79SGreg Clayton separator_char, 12020e5e5a79SGreg Clayton separator_char, 12030e5e5a79SGreg Clayton (int)regex_sed.size(), 12040e5e5a79SGreg Clayton regex_sed.data()); 12050e5e5a79SGreg Clayton return error; 12060e5e5a79SGreg Clayton } 12070e5e5a79SGreg Clayton else if (second_separator_char_pos + 1 == third_separator_char_pos) 12080e5e5a79SGreg Clayton { 12090e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 12100e5e5a79SGreg Clayton separator_char, 12110e5e5a79SGreg Clayton separator_char, 12120e5e5a79SGreg Clayton separator_char, 12130e5e5a79SGreg Clayton (int)regex_sed.size(), 12140e5e5a79SGreg Clayton regex_sed.data()); 12150e5e5a79SGreg Clayton return error; 12160e5e5a79SGreg Clayton } 121744d93782SGreg Clayton 121844d93782SGreg Clayton if (check_only == false) 121944d93782SGreg Clayton { 12200e5e5a79SGreg Clayton std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 12210e5e5a79SGreg Clayton std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 12220e5e5a79SGreg Clayton m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 12230e5e5a79SGreg Clayton subst.c_str()); 122444d93782SGreg Clayton } 12250e5e5a79SGreg Clayton return error; 1226de164aaaSGreg Clayton } 1227de164aaaSGreg Clayton 1228de164aaaSGreg Clayton void 12290e5e5a79SGreg Clayton AddRegexCommandToInterpreter() 1230de164aaaSGreg Clayton { 1231de164aaaSGreg Clayton if (m_regex_cmd_ap.get()) 1232de164aaaSGreg Clayton { 1233de164aaaSGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 1234de164aaaSGreg Clayton { 1235de164aaaSGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 1236de164aaaSGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 1237de164aaaSGreg Clayton } 1238de164aaaSGreg Clayton } 1239de164aaaSGreg Clayton } 1240de164aaaSGreg Clayton 1241de164aaaSGreg Clayton private: 12427b0992d9SGreg Clayton std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1243de164aaaSGreg Clayton 1244de164aaaSGreg Clayton class CommandOptions : public Options 1245de164aaaSGreg Clayton { 1246de164aaaSGreg Clayton public: 1247de164aaaSGreg Clayton 1248de164aaaSGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1249de164aaaSGreg Clayton Options (interpreter) 1250de164aaaSGreg Clayton { 1251de164aaaSGreg Clayton } 1252de164aaaSGreg Clayton 1253de164aaaSGreg Clayton virtual 1254de164aaaSGreg Clayton ~CommandOptions (){} 1255de164aaaSGreg Clayton 1256de164aaaSGreg Clayton virtual Error 1257de164aaaSGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 1258de164aaaSGreg Clayton { 1259de164aaaSGreg Clayton Error error; 12603bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1261de164aaaSGreg Clayton 1262de164aaaSGreg Clayton switch (short_option) 1263de164aaaSGreg Clayton { 1264de164aaaSGreg Clayton case 'h': 1265de164aaaSGreg Clayton m_help.assign (option_arg); 1266de164aaaSGreg Clayton break; 1267de164aaaSGreg Clayton case 's': 1268de164aaaSGreg Clayton m_syntax.assign (option_arg); 1269de164aaaSGreg Clayton break; 1270de164aaaSGreg Clayton 1271de164aaaSGreg Clayton default: 127286edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1273de164aaaSGreg Clayton break; 1274de164aaaSGreg Clayton } 1275de164aaaSGreg Clayton 1276de164aaaSGreg Clayton return error; 1277de164aaaSGreg Clayton } 1278de164aaaSGreg Clayton 1279de164aaaSGreg Clayton void 1280de164aaaSGreg Clayton OptionParsingStarting () 1281de164aaaSGreg Clayton { 1282de164aaaSGreg Clayton m_help.clear(); 1283de164aaaSGreg Clayton m_syntax.clear(); 1284de164aaaSGreg Clayton } 1285de164aaaSGreg Clayton 1286de164aaaSGreg Clayton const OptionDefinition* 1287de164aaaSGreg Clayton GetDefinitions () 1288de164aaaSGreg Clayton { 1289de164aaaSGreg Clayton return g_option_table; 1290de164aaaSGreg Clayton } 1291de164aaaSGreg Clayton 1292de164aaaSGreg Clayton // Options table: Required for subclasses of Options. 1293de164aaaSGreg Clayton 1294de164aaaSGreg Clayton static OptionDefinition g_option_table[]; 1295de164aaaSGreg Clayton 1296de164aaaSGreg Clayton const char * 1297de164aaaSGreg Clayton GetHelp () 1298de164aaaSGreg Clayton { 1299de164aaaSGreg Clayton if (m_help.empty()) 1300de164aaaSGreg Clayton return NULL; 1301de164aaaSGreg Clayton return m_help.c_str(); 1302de164aaaSGreg Clayton } 1303de164aaaSGreg Clayton const char * 1304de164aaaSGreg Clayton GetSyntax () 1305de164aaaSGreg Clayton { 1306de164aaaSGreg Clayton if (m_syntax.empty()) 1307de164aaaSGreg Clayton return NULL; 1308de164aaaSGreg Clayton return m_syntax.c_str(); 1309de164aaaSGreg Clayton } 1310de164aaaSGreg Clayton // Instance variables to hold the values for command options. 1311de164aaaSGreg Clayton protected: 1312de164aaaSGreg Clayton std::string m_help; 1313de164aaaSGreg Clayton std::string m_syntax; 1314de164aaaSGreg Clayton }; 1315de164aaaSGreg Clayton 1316b0a1814fSEric Christopher Options * 1317b0a1814fSEric Christopher GetOptions () override 1318de164aaaSGreg Clayton { 1319de164aaaSGreg Clayton return &m_options; 1320de164aaaSGreg Clayton } 1321de164aaaSGreg Clayton 13225a988416SJim Ingham CommandOptions m_options; 1323de164aaaSGreg Clayton }; 1324de164aaaSGreg Clayton 1325de164aaaSGreg Clayton OptionDefinition 1326de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1327de164aaaSGreg Clayton { 1328d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1329d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1330d37221dcSZachary Turner { 0 , false, NULL , 0 , 0 , NULL, NULL, 0, eArgTypeNone, NULL } 1331de164aaaSGreg Clayton }; 1332de164aaaSGreg Clayton 1333de164aaaSGreg Clayton 13345a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw 1335223383edSEnrico Granata { 1336223383edSEnrico Granata private: 1337223383edSEnrico Granata std::string m_function_name; 13380a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchro; 1339fac939e9SEnrico Granata bool m_fetched_help_long; 1340223383edSEnrico Granata 1341223383edSEnrico Granata public: 1342223383edSEnrico Granata 1343223383edSEnrico Granata CommandObjectPythonFunction (CommandInterpreter &interpreter, 1344223383edSEnrico Granata std::string name, 13450a305db7SEnrico Granata std::string funct, 1346735152e3SEnrico Granata std::string help, 13470a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 13485a988416SJim Ingham CommandObjectRaw (interpreter, 1349223383edSEnrico Granata name.c_str(), 1350735152e3SEnrico Granata NULL, 1351223383edSEnrico Granata NULL), 13520a305db7SEnrico Granata m_function_name(funct), 1353fac939e9SEnrico Granata m_synchro(synch), 1354fac939e9SEnrico Granata m_fetched_help_long(false) 1355223383edSEnrico Granata { 1356735152e3SEnrico Granata if (!help.empty()) 1357735152e3SEnrico Granata SetHelp(help.c_str()); 1358735152e3SEnrico Granata else 1359735152e3SEnrico Granata { 1360735152e3SEnrico Granata StreamString stream; 1361735152e3SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 1362735152e3SEnrico Granata SetHelp(stream.GetData()); 1363735152e3SEnrico Granata } 1364223383edSEnrico Granata } 1365223383edSEnrico Granata 1366223383edSEnrico Granata virtual 1367223383edSEnrico Granata ~CommandObjectPythonFunction () 1368223383edSEnrico Granata { 1369223383edSEnrico Granata } 1370223383edSEnrico Granata 1371223383edSEnrico Granata virtual bool 13723a18e319SGreg Clayton IsRemovable () const 13735a988416SJim Ingham { 13745a988416SJim Ingham return true; 13755a988416SJim Ingham } 13765a988416SJim Ingham 13775a988416SJim Ingham const std::string& 13785a988416SJim Ingham GetFunctionName () 13795a988416SJim Ingham { 13805a988416SJim Ingham return m_function_name; 13815a988416SJim Ingham } 13825a988416SJim Ingham 13835a988416SJim Ingham ScriptedCommandSynchronicity 13845a988416SJim Ingham GetSynchronicity () 13855a988416SJim Ingham { 13865a988416SJim Ingham return m_synchro; 13875a988416SJim Ingham } 13885a988416SJim Ingham 1389fac939e9SEnrico Granata virtual const char * 1390fac939e9SEnrico Granata GetHelpLong () 1391fac939e9SEnrico Granata { 1392fac939e9SEnrico Granata if (!m_fetched_help_long) 1393fac939e9SEnrico Granata { 1394fac939e9SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1395fac939e9SEnrico Granata if (scripter) 1396fac939e9SEnrico Granata { 1397fac939e9SEnrico Granata std::string docstring; 1398fac939e9SEnrico Granata m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1399fac939e9SEnrico Granata if (!docstring.empty()) 1400fac939e9SEnrico Granata SetHelpLong(docstring); 1401fac939e9SEnrico Granata } 1402fac939e9SEnrico Granata } 1403fac939e9SEnrico Granata return CommandObjectRaw::GetHelpLong(); 1404fac939e9SEnrico Granata } 1405fac939e9SEnrico Granata 14065a988416SJim Ingham protected: 14075a988416SJim Ingham virtual bool 14085a988416SJim Ingham DoExecute (const char *raw_command_line, CommandReturnObject &result) 1409223383edSEnrico Granata { 1410223383edSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1411223383edSEnrico Granata 1412223383edSEnrico Granata Error error; 1413223383edSEnrico Granata 141470f11f88SJim Ingham result.SetStatus(eReturnStatusInvalid); 141570f11f88SJim Ingham 1416223383edSEnrico Granata if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1417223383edSEnrico Granata raw_command_line, 14180a305db7SEnrico Granata m_synchro, 1419223383edSEnrico Granata result, 142006be059aSEnrico Granata error, 142106be059aSEnrico Granata m_exe_ctx) == false) 1422223383edSEnrico Granata { 1423223383edSEnrico Granata result.AppendError(error.AsCString()); 1424223383edSEnrico Granata result.SetStatus(eReturnStatusFailed); 1425223383edSEnrico Granata } 1426223383edSEnrico Granata else 142770f11f88SJim Ingham { 142870f11f88SJim Ingham // Don't change the status if the command already set it... 142970f11f88SJim Ingham if (result.GetStatus() == eReturnStatusInvalid) 143070f11f88SJim Ingham { 14319a71a7d8SDaniel Malea if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1432223383edSEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 143370f11f88SJim Ingham else 143470f11f88SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 143570f11f88SJim Ingham } 143670f11f88SJim Ingham } 1437223383edSEnrico Granata 1438223383edSEnrico Granata return result.Succeeded(); 1439223383edSEnrico Granata } 1440223383edSEnrico Granata 1441223383edSEnrico Granata }; 1442223383edSEnrico Granata 14439fe00e52SEnrico Granata class CommandObjectScriptingObject : public CommandObjectRaw 14449fe00e52SEnrico Granata { 14459fe00e52SEnrico Granata private: 14460641ca1aSZachary Turner StructuredData::GenericSP m_cmd_obj_sp; 14479fe00e52SEnrico Granata ScriptedCommandSynchronicity m_synchro; 14486f79bb2dSEnrico Granata bool m_fetched_help_short:1; 14496f79bb2dSEnrico Granata bool m_fetched_help_long:1; 14509fe00e52SEnrico Granata 14519fe00e52SEnrico Granata public: 14529fe00e52SEnrico Granata 14539fe00e52SEnrico Granata CommandObjectScriptingObject (CommandInterpreter &interpreter, 14549fe00e52SEnrico Granata std::string name, 14550641ca1aSZachary Turner StructuredData::GenericSP cmd_obj_sp, 14569fe00e52SEnrico Granata ScriptedCommandSynchronicity synch) : 14579fe00e52SEnrico Granata CommandObjectRaw (interpreter, 14589fe00e52SEnrico Granata name.c_str(), 14599fe00e52SEnrico Granata NULL, 14609fe00e52SEnrico Granata NULL), 14619fe00e52SEnrico Granata m_cmd_obj_sp(cmd_obj_sp), 14626f79bb2dSEnrico Granata m_synchro(synch), 14636f79bb2dSEnrico Granata m_fetched_help_short(false), 14646f79bb2dSEnrico Granata m_fetched_help_long(false) 14659fe00e52SEnrico Granata { 14669fe00e52SEnrico Granata StreamString stream; 14679fe00e52SEnrico Granata stream.Printf("For more information run 'help %s'",name.c_str()); 14689fe00e52SEnrico Granata SetHelp(stream.GetData()); 1469e87764f2SEnrico Granata if (ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter()) 1470e87764f2SEnrico Granata GetFlags().Set(scripter->GetFlagsForCommandObject(cmd_obj_sp)); 14719fe00e52SEnrico Granata } 14729fe00e52SEnrico Granata 14739fe00e52SEnrico Granata virtual 14749fe00e52SEnrico Granata ~CommandObjectScriptingObject () 14759fe00e52SEnrico Granata { 14769fe00e52SEnrico Granata } 14779fe00e52SEnrico Granata 14789fe00e52SEnrico Granata virtual bool 14799fe00e52SEnrico Granata IsRemovable () const 14809fe00e52SEnrico Granata { 14819fe00e52SEnrico Granata return true; 14829fe00e52SEnrico Granata } 14839fe00e52SEnrico Granata 14840641ca1aSZachary Turner StructuredData::GenericSP 14859fe00e52SEnrico Granata GetImplementingObject () 14869fe00e52SEnrico Granata { 14879fe00e52SEnrico Granata return m_cmd_obj_sp; 14889fe00e52SEnrico Granata } 14899fe00e52SEnrico Granata 14909fe00e52SEnrico Granata ScriptedCommandSynchronicity 14919fe00e52SEnrico Granata GetSynchronicity () 14929fe00e52SEnrico Granata { 14939fe00e52SEnrico Granata return m_synchro; 14949fe00e52SEnrico Granata } 14959fe00e52SEnrico Granata 14969fe00e52SEnrico Granata virtual const char * 14976f79bb2dSEnrico Granata GetHelp () 14986f79bb2dSEnrico Granata { 14996f79bb2dSEnrico Granata if (!m_fetched_help_short) 15006f79bb2dSEnrico Granata { 15016f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 15026f79bb2dSEnrico Granata if (scripter) 15036f79bb2dSEnrico Granata { 15046f79bb2dSEnrico Granata std::string docstring; 15056f79bb2dSEnrico Granata m_fetched_help_short = scripter->GetShortHelpForCommandObject(m_cmd_obj_sp,docstring); 15066f79bb2dSEnrico Granata if (!docstring.empty()) 15076f79bb2dSEnrico Granata SetHelp(docstring); 15086f79bb2dSEnrico Granata } 15096f79bb2dSEnrico Granata } 15106f79bb2dSEnrico Granata return CommandObjectRaw::GetHelp(); 15116f79bb2dSEnrico Granata } 15126f79bb2dSEnrico Granata 15136f79bb2dSEnrico Granata virtual const char * 15149fe00e52SEnrico Granata GetHelpLong () 15159fe00e52SEnrico Granata { 15166f79bb2dSEnrico Granata if (!m_fetched_help_long) 15176f79bb2dSEnrico Granata { 15186f79bb2dSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 15196f79bb2dSEnrico Granata if (scripter) 15206f79bb2dSEnrico Granata { 15216f79bb2dSEnrico Granata std::string docstring; 15226f79bb2dSEnrico Granata m_fetched_help_long = scripter->GetLongHelpForCommandObject(m_cmd_obj_sp,docstring); 15236f79bb2dSEnrico Granata if (!docstring.empty()) 15246f79bb2dSEnrico Granata SetHelpLong(docstring); 15256f79bb2dSEnrico Granata } 15266f79bb2dSEnrico Granata } 15279fe00e52SEnrico Granata return CommandObjectRaw::GetHelpLong(); 15289fe00e52SEnrico Granata } 15299fe00e52SEnrico Granata 15309fe00e52SEnrico Granata protected: 15319fe00e52SEnrico Granata virtual bool 15329fe00e52SEnrico Granata DoExecute (const char *raw_command_line, CommandReturnObject &result) 15339fe00e52SEnrico Granata { 15349fe00e52SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 15359fe00e52SEnrico Granata 15369fe00e52SEnrico Granata Error error; 15379fe00e52SEnrico Granata 15389fe00e52SEnrico Granata result.SetStatus(eReturnStatusInvalid); 15399fe00e52SEnrico Granata 15409fe00e52SEnrico Granata if (!scripter || scripter->RunScriptBasedCommand(m_cmd_obj_sp, 15419fe00e52SEnrico Granata raw_command_line, 15429fe00e52SEnrico Granata m_synchro, 15439fe00e52SEnrico Granata result, 15449fe00e52SEnrico Granata error, 15459fe00e52SEnrico Granata m_exe_ctx) == false) 15469fe00e52SEnrico Granata { 15479fe00e52SEnrico Granata result.AppendError(error.AsCString()); 15489fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 15499fe00e52SEnrico Granata } 15509fe00e52SEnrico Granata else 15519fe00e52SEnrico Granata { 15529fe00e52SEnrico Granata // Don't change the status if the command already set it... 15539fe00e52SEnrico Granata if (result.GetStatus() == eReturnStatusInvalid) 15549fe00e52SEnrico Granata { 15559fe00e52SEnrico Granata if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 15569fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 15579fe00e52SEnrico Granata else 15589fe00e52SEnrico Granata result.SetStatus(eReturnStatusSuccessFinishResult); 15599fe00e52SEnrico Granata } 15609fe00e52SEnrico Granata } 15619fe00e52SEnrico Granata 15629fe00e52SEnrico Granata return result.Succeeded(); 15639fe00e52SEnrico Granata } 15649fe00e52SEnrico Granata 15659fe00e52SEnrico Granata }; 15669fe00e52SEnrico Granata 1567a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1568a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport 1569a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1570a9dbf432SEnrico Granata 15715a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed 1572a9dbf432SEnrico Granata { 15735a988416SJim Ingham public: 15745a988416SJim Ingham CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 15755a988416SJim Ingham CommandObjectParsed (interpreter, 15765a988416SJim Ingham "command script import", 15775a988416SJim Ingham "Import a scripting module in LLDB.", 15785a988416SJim Ingham NULL), 15795a988416SJim Ingham m_options(interpreter) 15805a988416SJim Ingham { 15815a988416SJim Ingham CommandArgumentEntry arg1; 15825a988416SJim Ingham CommandArgumentData cmd_arg; 15835a988416SJim Ingham 15845a988416SJim Ingham // Define the first (and only) variant of this arg. 15855a988416SJim Ingham cmd_arg.arg_type = eArgTypeFilename; 15863b00e35bSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlus; 15875a988416SJim Ingham 15885a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 15895a988416SJim Ingham arg1.push_back (cmd_arg); 15905a988416SJim Ingham 15915a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 15925a988416SJim Ingham m_arguments.push_back (arg1); 15935a988416SJim Ingham } 15945a988416SJim Ingham 15955a988416SJim Ingham ~CommandObjectCommandsScriptImport () 15965a988416SJim Ingham { 15975a988416SJim Ingham } 15985a988416SJim Ingham 1599c7bece56SGreg Clayton virtual int 16005a988416SJim Ingham HandleArgumentCompletion (Args &input, 16015a988416SJim Ingham int &cursor_index, 16025a988416SJim Ingham int &cursor_char_position, 16035a988416SJim Ingham OptionElementVector &opt_element_vector, 16045a988416SJim Ingham int match_start_point, 16055a988416SJim Ingham int max_return_elements, 16065a988416SJim Ingham bool &word_complete, 16075a988416SJim Ingham StringList &matches) 16085a988416SJim Ingham { 16095a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 16105a988416SJim Ingham completion_str.erase (cursor_char_position); 16115a988416SJim Ingham 16125a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 16135a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 16145a988416SJim Ingham completion_str.c_str(), 16155a988416SJim Ingham match_start_point, 16165a988416SJim Ingham max_return_elements, 16175a988416SJim Ingham NULL, 16185a988416SJim Ingham word_complete, 16195a988416SJim Ingham matches); 16205a988416SJim Ingham return matches.GetSize(); 16215a988416SJim Ingham } 16225a988416SJim Ingham 16235a988416SJim Ingham virtual Options * 16245a988416SJim Ingham GetOptions () 16255a988416SJim Ingham { 16265a988416SJim Ingham return &m_options; 16275a988416SJim Ingham } 16285a988416SJim Ingham 16295a988416SJim Ingham protected: 16300a305db7SEnrico Granata 16310a305db7SEnrico Granata class CommandOptions : public Options 16320a305db7SEnrico Granata { 16330a305db7SEnrico Granata public: 16340a305db7SEnrico Granata 16350a305db7SEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 16360a305db7SEnrico Granata Options (interpreter) 16370a305db7SEnrico Granata { 16380a305db7SEnrico Granata } 16390a305db7SEnrico Granata 16400a305db7SEnrico Granata virtual 16410a305db7SEnrico Granata ~CommandOptions (){} 16420a305db7SEnrico Granata 16430a305db7SEnrico Granata virtual Error 16440a305db7SEnrico Granata SetOptionValue (uint32_t option_idx, const char *option_arg) 16450a305db7SEnrico Granata { 16460a305db7SEnrico Granata Error error; 16473bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 16480a305db7SEnrico Granata 16490a305db7SEnrico Granata switch (short_option) 16500a305db7SEnrico Granata { 16510a305db7SEnrico Granata case 'r': 16520a305db7SEnrico Granata m_allow_reload = true; 16530a305db7SEnrico Granata break; 16540a305db7SEnrico Granata default: 16550a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 16560a305db7SEnrico Granata break; 16570a305db7SEnrico Granata } 16580a305db7SEnrico Granata 16590a305db7SEnrico Granata return error; 16600a305db7SEnrico Granata } 16610a305db7SEnrico Granata 16620a305db7SEnrico Granata void 16630a305db7SEnrico Granata OptionParsingStarting () 16640a305db7SEnrico Granata { 1665e0c70f1bSEnrico Granata m_allow_reload = true; 16660a305db7SEnrico Granata } 16670a305db7SEnrico Granata 16680a305db7SEnrico Granata const OptionDefinition* 16690a305db7SEnrico Granata GetDefinitions () 16700a305db7SEnrico Granata { 16710a305db7SEnrico Granata return g_option_table; 16720a305db7SEnrico Granata } 16730a305db7SEnrico Granata 16740a305db7SEnrico Granata // Options table: Required for subclasses of Options. 16750a305db7SEnrico Granata 16760a305db7SEnrico Granata static OptionDefinition g_option_table[]; 16770a305db7SEnrico Granata 16780a305db7SEnrico Granata // Instance variables to hold the values for command options. 16790a305db7SEnrico Granata 16800a305db7SEnrico Granata bool m_allow_reload; 16810a305db7SEnrico Granata }; 16820a305db7SEnrico Granata 1683a9dbf432SEnrico Granata bool 16845a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1685a9dbf432SEnrico Granata { 1686a9dbf432SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1687a9dbf432SEnrico Granata { 1688a9dbf432SEnrico Granata result.AppendError ("only scripting language supported for module importing is currently Python"); 1689a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1690a9dbf432SEnrico Granata return false; 1691a9dbf432SEnrico Granata } 1692a9dbf432SEnrico Granata 16935a988416SJim Ingham size_t argc = command.GetArgumentCount(); 16943b00e35bSEnrico Granata if (0 == argc) 1695a9dbf432SEnrico Granata { 16963b00e35bSEnrico Granata result.AppendError("command script import needs one or more arguments"); 1697a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1698a9dbf432SEnrico Granata return false; 1699a9dbf432SEnrico Granata } 1700a9dbf432SEnrico Granata 17010e978481SEd Maste for (size_t i = 0; 17023b00e35bSEnrico Granata i < argc; 17033b00e35bSEnrico Granata i++) 17043b00e35bSEnrico Granata { 17053b00e35bSEnrico Granata std::string path = command.GetArgumentAtIndex(i); 1706a9dbf432SEnrico Granata Error error; 1707a9dbf432SEnrico Granata 1708c9d645d3SGreg Clayton const bool init_session = true; 1709078551c7SEnrico Granata // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1710078551c7SEnrico Granata // commands won't ever be recursively invoked, but it's actually possible to craft 1711078551c7SEnrico Granata // a Python script that does other "command script imports" in __lldb_init_module 1712078551c7SEnrico Granata // the real fix is to have recursive commands possible with a CommandInvocation object 1713078551c7SEnrico Granata // separate from the CommandObject itself, so that recursive command invocations 1714078551c7SEnrico Granata // won't stomp on each other (wrt to execution contents, options, and more) 1715078551c7SEnrico Granata m_exe_ctx.Clear(); 1716a9dbf432SEnrico Granata if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 17170a305db7SEnrico Granata m_options.m_allow_reload, 1718c9d645d3SGreg Clayton init_session, 1719a9dbf432SEnrico Granata error)) 1720a9dbf432SEnrico Granata { 1721a9dbf432SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1722a9dbf432SEnrico Granata } 1723a9dbf432SEnrico Granata else 1724a9dbf432SEnrico Granata { 1725a9dbf432SEnrico Granata result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1726a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1727a9dbf432SEnrico Granata } 17283b00e35bSEnrico Granata } 1729a9dbf432SEnrico Granata 1730a9dbf432SEnrico Granata return result.Succeeded(); 1731a9dbf432SEnrico Granata } 17320a305db7SEnrico Granata 17335a988416SJim Ingham CommandOptions m_options; 1734a9dbf432SEnrico Granata }; 1735223383edSEnrico Granata 17360a305db7SEnrico Granata OptionDefinition 17370a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 17380a305db7SEnrico Granata { 1739d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."}, 1740d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 17410a305db7SEnrico Granata }; 17420a305db7SEnrico Granata 17430a305db7SEnrico Granata 1744223383edSEnrico Granata //------------------------------------------------------------------------- 1745223383edSEnrico Granata // CommandObjectCommandsScriptAdd 1746223383edSEnrico Granata //------------------------------------------------------------------------- 1747223383edSEnrico Granata 174844d93782SGreg Clayton class CommandObjectCommandsScriptAdd : 174944d93782SGreg Clayton public CommandObjectParsed, 175044d93782SGreg Clayton public IOHandlerDelegateMultiline 1751223383edSEnrico Granata { 17525a988416SJim Ingham public: 17535a988416SJim Ingham CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 17545a988416SJim Ingham CommandObjectParsed (interpreter, 17555a988416SJim Ingham "command script add", 17565a988416SJim Ingham "Add a scripted function as an LLDB command.", 17575a988416SJim Ingham NULL), 1758c3d874a5SGreg Clayton IOHandlerDelegateMultiline ("DONE"), 17595a988416SJim Ingham m_options (interpreter) 17605a988416SJim Ingham { 17615a988416SJim Ingham CommandArgumentEntry arg1; 17625a988416SJim Ingham CommandArgumentData cmd_arg; 17635a988416SJim Ingham 17645a988416SJim Ingham // Define the first (and only) variant of this arg. 17655a988416SJim Ingham cmd_arg.arg_type = eArgTypeCommandName; 17665a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 17675a988416SJim Ingham 17685a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 17695a988416SJim Ingham arg1.push_back (cmd_arg); 17705a988416SJim Ingham 17715a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 17725a988416SJim Ingham m_arguments.push_back (arg1); 17735a988416SJim Ingham } 17745a988416SJim Ingham 17755a988416SJim Ingham ~CommandObjectCommandsScriptAdd () 17765a988416SJim Ingham { 17775a988416SJim Ingham } 17785a988416SJim Ingham 17795a988416SJim Ingham virtual Options * 17805a988416SJim Ingham GetOptions () 17815a988416SJim Ingham { 17825a988416SJim Ingham return &m_options; 17835a988416SJim Ingham } 17845a988416SJim Ingham 17855a988416SJim Ingham protected: 1786223383edSEnrico Granata 1787223383edSEnrico Granata class CommandOptions : public Options 1788223383edSEnrico Granata { 1789223383edSEnrico Granata public: 1790223383edSEnrico Granata 1791223383edSEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 17929fe00e52SEnrico Granata Options (interpreter), 17939fe00e52SEnrico Granata m_class_name(), 17949fe00e52SEnrico Granata m_funct_name(), 17959fe00e52SEnrico Granata m_short_help(), 17969fe00e52SEnrico Granata m_synchronicity(eScriptedCommandSynchronicitySynchronous) 1797223383edSEnrico Granata { 1798223383edSEnrico Granata } 1799223383edSEnrico Granata 1800223383edSEnrico Granata virtual 1801223383edSEnrico Granata ~CommandOptions (){} 1802223383edSEnrico Granata 1803223383edSEnrico Granata virtual Error 1804223383edSEnrico Granata SetOptionValue (uint32_t option_idx, const char *option_arg) 1805223383edSEnrico Granata { 1806223383edSEnrico Granata Error error; 18073bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1808223383edSEnrico Granata 1809223383edSEnrico Granata switch (short_option) 1810223383edSEnrico Granata { 1811223383edSEnrico Granata case 'f': 1812735152e3SEnrico Granata if (option_arg) 1813735152e3SEnrico Granata m_funct_name.assign(option_arg); 1814735152e3SEnrico Granata break; 18159fe00e52SEnrico Granata case 'c': 18169fe00e52SEnrico Granata if (option_arg) 18179fe00e52SEnrico Granata m_class_name.assign(option_arg); 18189fe00e52SEnrico Granata break; 1819735152e3SEnrico Granata case 'h': 1820735152e3SEnrico Granata if (option_arg) 1821735152e3SEnrico Granata m_short_help.assign(option_arg); 1822223383edSEnrico Granata break; 18230a305db7SEnrico Granata case 's': 182444d93782SGreg Clayton m_synchronicity = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 18250a305db7SEnrico Granata if (!error.Success()) 18260a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 18270a305db7SEnrico Granata break; 1828223383edSEnrico Granata default: 182986edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1830223383edSEnrico Granata break; 1831223383edSEnrico Granata } 1832223383edSEnrico Granata 1833223383edSEnrico Granata return error; 1834223383edSEnrico Granata } 1835223383edSEnrico Granata 1836223383edSEnrico Granata void 1837223383edSEnrico Granata OptionParsingStarting () 1838223383edSEnrico Granata { 18399fe00e52SEnrico Granata m_class_name.clear(); 1840735152e3SEnrico Granata m_funct_name.clear(); 1841735152e3SEnrico Granata m_short_help.clear(); 184244d93782SGreg Clayton m_synchronicity = eScriptedCommandSynchronicitySynchronous; 1843223383edSEnrico Granata } 1844223383edSEnrico Granata 1845223383edSEnrico Granata const OptionDefinition* 1846223383edSEnrico Granata GetDefinitions () 1847223383edSEnrico Granata { 1848223383edSEnrico Granata return g_option_table; 1849223383edSEnrico Granata } 1850223383edSEnrico Granata 1851223383edSEnrico Granata // Options table: Required for subclasses of Options. 1852223383edSEnrico Granata 1853223383edSEnrico Granata static OptionDefinition g_option_table[]; 1854223383edSEnrico Granata 1855223383edSEnrico Granata // Instance variables to hold the values for command options. 1856223383edSEnrico Granata 18579fe00e52SEnrico Granata std::string m_class_name; 1858223383edSEnrico Granata std::string m_funct_name; 1859735152e3SEnrico Granata std::string m_short_help; 186044d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 1861223383edSEnrico Granata }; 1862223383edSEnrico Granata 186344d93782SGreg Clayton virtual void 186444d93782SGreg Clayton IOHandlerActivated (IOHandler &io_handler) 1865223383edSEnrico Granata { 186644d93782SGreg Clayton StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 186744d93782SGreg Clayton if (output_sp) 1868223383edSEnrico Granata { 186944d93782SGreg Clayton output_sp->PutCString(g_python_command_instructions); 187044d93782SGreg Clayton output_sp->Flush(); 1871223383edSEnrico Granata } 1872223383edSEnrico Granata } 1873223383edSEnrico Granata 1874223383edSEnrico Granata 187544d93782SGreg Clayton virtual void 187644d93782SGreg Clayton IOHandlerInputComplete (IOHandler &io_handler, std::string &data) 1877223383edSEnrico Granata { 187844d93782SGreg Clayton StreamFileSP error_sp = io_handler.GetErrorStreamFile(); 187944d93782SGreg Clayton 188044d93782SGreg Clayton ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); 188144d93782SGreg Clayton if (interpreter) 188244d93782SGreg Clayton { 188344d93782SGreg Clayton 188444d93782SGreg Clayton StringList lines; 188544d93782SGreg Clayton lines.SplitIntoLines(data); 188644d93782SGreg Clayton if (lines.GetSize() > 0) 188744d93782SGreg Clayton { 1888a73b7df7SEnrico Granata std::string funct_name_str; 188944d93782SGreg Clayton if (interpreter->GenerateScriptAliasFunction (lines, funct_name_str)) 1890223383edSEnrico Granata { 1891a73b7df7SEnrico Granata if (funct_name_str.empty()) 1892223383edSEnrico Granata { 189344d93782SGreg Clayton error_sp->Printf ("error: unable to obtain a function name, didn't add python command.\n"); 189444d93782SGreg Clayton error_sp->Flush(); 1895223383edSEnrico Granata } 189644d93782SGreg Clayton else 189744d93782SGreg Clayton { 1898223383edSEnrico Granata // everything should be fine now, let's add this alias 1899223383edSEnrico Granata 1900223383edSEnrico Granata CommandObjectSP command_obj_sp(new CommandObjectPythonFunction (m_interpreter, 1901223383edSEnrico Granata m_cmd_name, 1902a73b7df7SEnrico Granata funct_name_str.c_str(), 1903735152e3SEnrico Granata m_short_help, 190444d93782SGreg Clayton m_synchronicity)); 1905223383edSEnrico Granata 19060a305db7SEnrico Granata if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1907223383edSEnrico Granata { 190844d93782SGreg Clayton error_sp->Printf ("error: unable to add selected command, didn't add python command.\n"); 190944d93782SGreg Clayton error_sp->Flush(); 1910223383edSEnrico Granata } 1911223383edSEnrico Granata } 191244d93782SGreg Clayton } 191344d93782SGreg Clayton else 191444d93782SGreg Clayton { 191544d93782SGreg Clayton error_sp->Printf ("error: unable to create function, didn't add python command.\n"); 191644d93782SGreg Clayton error_sp->Flush(); 191744d93782SGreg Clayton } 191844d93782SGreg Clayton } 191944d93782SGreg Clayton else 192044d93782SGreg Clayton { 192144d93782SGreg Clayton error_sp->Printf ("error: empty function, didn't add python command.\n"); 192244d93782SGreg Clayton error_sp->Flush(); 192344d93782SGreg Clayton } 192444d93782SGreg Clayton } 192544d93782SGreg Clayton else 192644d93782SGreg Clayton { 192744d93782SGreg Clayton error_sp->Printf ("error: script interpreter missing, didn't add python command.\n"); 192844d93782SGreg Clayton error_sp->Flush(); 192944d93782SGreg Clayton } 193044d93782SGreg Clayton 193144d93782SGreg Clayton io_handler.SetIsDone(true); 193244d93782SGreg Clayton 193344d93782SGreg Clayton 193444d93782SGreg Clayton } 1935223383edSEnrico Granata 19365a988416SJim Ingham protected: 1937223383edSEnrico Granata bool 19385a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1939223383edSEnrico Granata { 194099f0b8f9SEnrico Granata 194199f0b8f9SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 194299f0b8f9SEnrico Granata { 194399f0b8f9SEnrico Granata result.AppendError ("only scripting language supported for scripted commands is currently Python"); 194499f0b8f9SEnrico Granata result.SetStatus (eReturnStatusFailed); 194599f0b8f9SEnrico Granata return false; 194699f0b8f9SEnrico Granata } 194799f0b8f9SEnrico Granata 19485a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1949223383edSEnrico Granata 1950223383edSEnrico Granata if (argc != 1) 1951223383edSEnrico Granata { 1952223383edSEnrico Granata result.AppendError ("'command script add' requires one argument"); 1953223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1954223383edSEnrico Granata return false; 1955223383edSEnrico Granata } 1956223383edSEnrico Granata 1957735152e3SEnrico Granata // Store the options in case we get multi-line input 195844d93782SGreg Clayton m_cmd_name = command.GetArgumentAtIndex(0); 1959735152e3SEnrico Granata m_short_help.assign(m_options.m_short_help); 196044d93782SGreg Clayton m_synchronicity = m_options.m_synchronicity; 1961223383edSEnrico Granata 19629fe00e52SEnrico Granata if (m_options.m_class_name.empty()) 19639fe00e52SEnrico Granata { 1964223383edSEnrico Granata if (m_options.m_funct_name.empty()) 1965223383edSEnrico Granata { 196644d93782SGreg Clayton m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt 196744d93782SGreg Clayton *this, // IOHandlerDelegate 196844d93782SGreg Clayton true, // Run IOHandler in async mode 196944d93782SGreg Clayton NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 1970223383edSEnrico Granata } 1971223383edSEnrico Granata else 1972223383edSEnrico Granata { 19730a305db7SEnrico Granata CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 197444d93782SGreg Clayton m_cmd_name, 19750a305db7SEnrico Granata m_options.m_funct_name, 1976735152e3SEnrico Granata m_options.m_short_help, 197744d93782SGreg Clayton m_synchronicity)); 197844d93782SGreg Clayton if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 1979223383edSEnrico Granata { 1980223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1981223383edSEnrico Granata } 1982223383edSEnrico Granata else 1983223383edSEnrico Granata { 1984223383edSEnrico Granata result.AppendError("cannot add command"); 1985223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1986223383edSEnrico Granata } 1987223383edSEnrico Granata } 19889fe00e52SEnrico Granata } 19899fe00e52SEnrico Granata else 19909fe00e52SEnrico Granata { 19919fe00e52SEnrico Granata ScriptInterpreter *interpreter = GetCommandInterpreter().GetScriptInterpreter(); 19929fe00e52SEnrico Granata if (!interpreter) 19939fe00e52SEnrico Granata { 19949fe00e52SEnrico Granata result.AppendError("cannot find ScriptInterpreter"); 19959fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 19969fe00e52SEnrico Granata return false; 19979fe00e52SEnrico Granata } 19989fe00e52SEnrico Granata 19999fe00e52SEnrico Granata auto cmd_obj_sp = interpreter->CreateScriptCommandObject(m_options.m_class_name.c_str()); 20009fe00e52SEnrico Granata if (!cmd_obj_sp) 20019fe00e52SEnrico Granata { 20029fe00e52SEnrico Granata result.AppendError("cannot create helper object"); 20039fe00e52SEnrico Granata result.SetStatus(eReturnStatusFailed); 20049fe00e52SEnrico Granata return false; 20059fe00e52SEnrico Granata } 20069fe00e52SEnrico Granata 20079fe00e52SEnrico Granata CommandObjectSP new_cmd(new CommandObjectScriptingObject(m_interpreter, 20089fe00e52SEnrico Granata m_cmd_name, 20099fe00e52SEnrico Granata cmd_obj_sp, 20109fe00e52SEnrico Granata m_synchronicity)); 20119fe00e52SEnrico Granata if (m_interpreter.AddUserCommand(m_cmd_name, new_cmd, true)) 20129fe00e52SEnrico Granata { 20139fe00e52SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 20149fe00e52SEnrico Granata } 20159fe00e52SEnrico Granata else 20169fe00e52SEnrico Granata { 20179fe00e52SEnrico Granata result.AppendError("cannot add command"); 20189fe00e52SEnrico Granata result.SetStatus (eReturnStatusFailed); 20199fe00e52SEnrico Granata } 20209fe00e52SEnrico Granata } 2021223383edSEnrico Granata 2022223383edSEnrico Granata return result.Succeeded(); 2023223383edSEnrico Granata 2024223383edSEnrico Granata } 20255a988416SJim Ingham 20265a988416SJim Ingham CommandOptions m_options; 202744d93782SGreg Clayton std::string m_cmd_name; 2028735152e3SEnrico Granata std::string m_short_help; 202944d93782SGreg Clayton ScriptedCommandSynchronicity m_synchronicity; 2030223383edSEnrico Granata }; 2031223383edSEnrico Granata 20320a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] = 20330a305db7SEnrico Granata { 20340a305db7SEnrico Granata { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 20350a305db7SEnrico Granata { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 20360a305db7SEnrico Granata { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 20370a305db7SEnrico Granata { 0, NULL, NULL } 20380a305db7SEnrico Granata }; 20390a305db7SEnrico Granata 2040223383edSEnrico Granata OptionDefinition 2041223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 2042223383edSEnrico Granata { 2043d37221dcSZachary Turner { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 20449fe00e52SEnrico Granata { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name."}, 20459370d278SEnrico Granata { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeHelpText, "The help text to display for this command."}, 20469fe00e52SEnrico Granata { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, NULL, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, 2047d37221dcSZachary Turner { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2048223383edSEnrico Granata }; 2049223383edSEnrico Granata 2050223383edSEnrico Granata //------------------------------------------------------------------------- 2051223383edSEnrico Granata // CommandObjectCommandsScriptList 2052223383edSEnrico Granata //------------------------------------------------------------------------- 2053223383edSEnrico Granata 20545a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed 2055223383edSEnrico Granata { 2056223383edSEnrico Granata private: 2057223383edSEnrico Granata 2058223383edSEnrico Granata public: 2059223383edSEnrico Granata CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 20605a988416SJim Ingham CommandObjectParsed (interpreter, 2061223383edSEnrico Granata "command script list", 2062223383edSEnrico Granata "List defined scripted commands.", 2063223383edSEnrico Granata NULL) 2064223383edSEnrico Granata { 2065223383edSEnrico Granata } 2066223383edSEnrico Granata 2067223383edSEnrico Granata ~CommandObjectCommandsScriptList () 2068223383edSEnrico Granata { 2069223383edSEnrico Granata } 2070223383edSEnrico Granata 2071223383edSEnrico Granata bool 20725a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 2073223383edSEnrico Granata { 2074223383edSEnrico Granata 2075223383edSEnrico Granata m_interpreter.GetHelp(result, 2076223383edSEnrico Granata CommandInterpreter::eCommandTypesUserDef); 2077223383edSEnrico Granata 2078223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2079223383edSEnrico Granata 2080223383edSEnrico Granata return true; 2081223383edSEnrico Granata 2082223383edSEnrico Granata 2083223383edSEnrico Granata } 2084223383edSEnrico Granata }; 2085223383edSEnrico Granata 2086223383edSEnrico Granata //------------------------------------------------------------------------- 2087223383edSEnrico Granata // CommandObjectCommandsScriptClear 2088223383edSEnrico Granata //------------------------------------------------------------------------- 2089223383edSEnrico Granata 20905a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed 2091223383edSEnrico Granata { 2092223383edSEnrico Granata private: 2093223383edSEnrico Granata 2094223383edSEnrico Granata public: 2095223383edSEnrico Granata CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 20965a988416SJim Ingham CommandObjectParsed (interpreter, 2097223383edSEnrico Granata "command script clear", 2098223383edSEnrico Granata "Delete all scripted commands.", 2099223383edSEnrico Granata NULL) 2100223383edSEnrico Granata { 2101223383edSEnrico Granata } 2102223383edSEnrico Granata 2103223383edSEnrico Granata ~CommandObjectCommandsScriptClear () 2104223383edSEnrico Granata { 2105223383edSEnrico Granata } 2106223383edSEnrico Granata 21075a988416SJim Ingham protected: 2108223383edSEnrico Granata bool 21095a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 2110223383edSEnrico Granata { 2111223383edSEnrico Granata 2112223383edSEnrico Granata m_interpreter.RemoveAllUser(); 2113223383edSEnrico Granata 2114223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2115223383edSEnrico Granata 2116223383edSEnrico Granata return true; 2117223383edSEnrico Granata } 2118223383edSEnrico Granata }; 2119223383edSEnrico Granata 2120223383edSEnrico Granata //------------------------------------------------------------------------- 2121223383edSEnrico Granata // CommandObjectCommandsScriptDelete 2122223383edSEnrico Granata //------------------------------------------------------------------------- 2123223383edSEnrico Granata 21245a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed 2125223383edSEnrico Granata { 2126223383edSEnrico Granata public: 2127223383edSEnrico Granata CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 21285a988416SJim Ingham CommandObjectParsed (interpreter, 2129223383edSEnrico Granata "command script delete", 2130223383edSEnrico Granata "Delete a scripted command.", 2131223383edSEnrico Granata NULL) 2132223383edSEnrico Granata { 2133223383edSEnrico Granata CommandArgumentEntry arg1; 2134223383edSEnrico Granata CommandArgumentData cmd_arg; 2135223383edSEnrico Granata 2136223383edSEnrico Granata // Define the first (and only) variant of this arg. 2137223383edSEnrico Granata cmd_arg.arg_type = eArgTypeCommandName; 2138223383edSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlain; 2139223383edSEnrico Granata 2140223383edSEnrico Granata // There is only one variant this argument could be; put it into the argument entry. 2141223383edSEnrico Granata arg1.push_back (cmd_arg); 2142223383edSEnrico Granata 2143223383edSEnrico Granata // Push the data for the first argument into the m_arguments vector. 2144223383edSEnrico Granata m_arguments.push_back (arg1); 2145223383edSEnrico Granata } 2146223383edSEnrico Granata 2147223383edSEnrico Granata ~CommandObjectCommandsScriptDelete () 2148223383edSEnrico Granata { 2149223383edSEnrico Granata } 2150223383edSEnrico Granata 21515a988416SJim Ingham protected: 2152223383edSEnrico Granata bool 21535a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 2154223383edSEnrico Granata { 2155223383edSEnrico Granata 21565a988416SJim Ingham size_t argc = command.GetArgumentCount(); 2157223383edSEnrico Granata 2158223383edSEnrico Granata if (argc != 1) 2159223383edSEnrico Granata { 2160223383edSEnrico Granata result.AppendError ("'command script delete' requires one argument"); 2161223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2162223383edSEnrico Granata return false; 2163223383edSEnrico Granata } 2164223383edSEnrico Granata 21655a988416SJim Ingham const char* cmd_name = command.GetArgumentAtIndex(0); 2166223383edSEnrico Granata 2167223383edSEnrico Granata if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 2168223383edSEnrico Granata { 2169223383edSEnrico Granata m_interpreter.RemoveUser(cmd_name); 2170223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 2171223383edSEnrico Granata } 2172223383edSEnrico Granata else 2173223383edSEnrico Granata { 2174223383edSEnrico Granata result.AppendErrorWithFormat ("command %s not found", cmd_name); 2175223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 2176223383edSEnrico Granata } 2177223383edSEnrico Granata 2178223383edSEnrico Granata return result.Succeeded(); 2179223383edSEnrico Granata 2180223383edSEnrico Granata } 2181223383edSEnrico Granata }; 2182223383edSEnrico Granata 2183223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript 2184223383edSEnrico Granata 2185223383edSEnrico Granata //------------------------------------------------------------------------- 2186223383edSEnrico Granata // CommandObjectMultiwordCommandsScript 2187223383edSEnrico Granata //------------------------------------------------------------------------- 2188223383edSEnrico Granata 2189223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 2190223383edSEnrico Granata { 2191223383edSEnrico Granata public: 2192223383edSEnrico Granata CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 2193223383edSEnrico Granata CommandObjectMultiword (interpreter, 2194223383edSEnrico Granata "command script", 2195223383edSEnrico Granata "A set of commands for managing or customizing script commands.", 2196223383edSEnrico Granata "command script <subcommand> [<subcommand-options>]") 2197223383edSEnrico Granata { 2198223383edSEnrico Granata LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 2199223383edSEnrico Granata LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 2200223383edSEnrico Granata LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 2201223383edSEnrico Granata LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 2202a9dbf432SEnrico Granata LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 2203223383edSEnrico Granata } 2204223383edSEnrico Granata 2205223383edSEnrico Granata ~CommandObjectMultiwordCommandsScript () 2206223383edSEnrico Granata { 2207223383edSEnrico Granata } 2208223383edSEnrico Granata 2209223383edSEnrico Granata }; 2210223383edSEnrico Granata 2211223383edSEnrico Granata 2212ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands 2213ebc09c36SJim Ingham 2214ebc09c36SJim Ingham //------------------------------------------------------------------------- 2215ebc09c36SJim Ingham // CommandObjectMultiwordCommands 2216ebc09c36SJim Ingham //------------------------------------------------------------------------- 2217ebc09c36SJim Ingham 2218ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 2219a7015092SGreg Clayton CommandObjectMultiword (interpreter, 22200e5e5a79SGreg Clayton "command", 22213f4c09c1SCaroline Tice "A set of commands for managing or customizing the debugger commands.", 22220e5e5a79SGreg Clayton "command <subcommand> [<subcommand-options>]") 2223ebc09c36SJim Ingham { 2224a7015092SGreg Clayton LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 2225a7015092SGreg Clayton LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 2226a7015092SGreg Clayton LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 2227b547278cSGreg Clayton LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsDelete (interpreter))); 2228de164aaaSGreg Clayton LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 2229a5a97ebeSJim Ingham LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 2230223383edSEnrico Granata LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 2231ebc09c36SJim Ingham } 2232ebc09c36SJim Ingham 2233ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 2234ebc09c36SJim Ingham { 2235ebc09c36SJim Ingham } 2236ebc09c36SJim Ingham 2237