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" 19de164aaaSGreg Clayton #include "lldb/Core/InputReader.h" 20be93a35aSEnrico Granata #include "lldb/Core/InputReaderEZ.h" 21be93a35aSEnrico Granata #include "lldb/Core/StringList.h" 22de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h" 23ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h" 24de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h" 25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h" 26ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h" 2799f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h" 2899f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreterPython.h" 29ebc09c36SJim Ingham 30ebc09c36SJim Ingham using namespace lldb; 31ebc09c36SJim Ingham using namespace lldb_private; 32ebc09c36SJim Ingham 33ebc09c36SJim Ingham //------------------------------------------------------------------------- 34ebc09c36SJim Ingham // CommandObjectCommandsSource 35ebc09c36SJim Ingham //------------------------------------------------------------------------- 36ebc09c36SJim Ingham 375a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed 38a5a97ebeSJim Ingham { 395a988416SJim Ingham public: 405a988416SJim Ingham CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 415a988416SJim Ingham CommandObjectParsed (interpreter, 425a988416SJim Ingham "command history", 435a988416SJim Ingham "Dump the history of commands in this session.", 445a988416SJim Ingham NULL), 455a988416SJim Ingham m_options (interpreter) 465a988416SJim Ingham { 475a988416SJim Ingham } 485a988416SJim Ingham 495a988416SJim Ingham ~CommandObjectCommandsHistory () {} 505a988416SJim Ingham 515a988416SJim Ingham virtual Options * 525a988416SJim Ingham GetOptions () 535a988416SJim Ingham { 545a988416SJim Ingham return &m_options; 555a988416SJim Ingham } 565a988416SJim Ingham 575a988416SJim Ingham protected: 58a5a97ebeSJim Ingham 59a5a97ebeSJim Ingham class CommandOptions : public Options 60a5a97ebeSJim Ingham { 61a5a97ebeSJim Ingham public: 62a5a97ebeSJim Ingham 63a5a97ebeSJim Ingham CommandOptions (CommandInterpreter &interpreter) : 64a5a97ebeSJim Ingham Options (interpreter) 65a5a97ebeSJim Ingham { 66a5a97ebeSJim Ingham } 67a5a97ebeSJim Ingham 68a5a97ebeSJim Ingham virtual 69a5a97ebeSJim Ingham ~CommandOptions (){} 70a5a97ebeSJim Ingham 71a5a97ebeSJim Ingham virtual Error 72a5a97ebeSJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 73a5a97ebeSJim Ingham { 74a5a97ebeSJim Ingham Error error; 75a5a97ebeSJim Ingham char short_option = (char) m_getopt_table[option_idx].val; 76a5a97ebeSJim Ingham bool success; 77a5a97ebeSJim Ingham 78a5a97ebeSJim Ingham switch (short_option) 79a5a97ebeSJim Ingham { 80a5a97ebeSJim Ingham case 'c': 81a5a97ebeSJim Ingham m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success); 82a5a97ebeSJim Ingham if (!success) 8386edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for count: %s", option_arg); 84a5a97ebeSJim Ingham if (m_end_idx != 0) 85a5a97ebeSJim Ingham m_end_idx--; 86a5a97ebeSJim Ingham m_start_idx = 0; 87a5a97ebeSJim Ingham break; 88a5a97ebeSJim Ingham case 'e': 89a5a97ebeSJim Ingham m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success); 90a5a97ebeSJim Ingham if (!success) 9186edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg); 92a5a97ebeSJim Ingham break; 93a5a97ebeSJim Ingham case 's': 94a5a97ebeSJim Ingham m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success); 95a5a97ebeSJim Ingham if (!success) 9686edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg); 97a5a97ebeSJim Ingham break; 98a5a97ebeSJim Ingham default: 9986edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 100a5a97ebeSJim Ingham break; 101a5a97ebeSJim Ingham } 102a5a97ebeSJim Ingham 103a5a97ebeSJim Ingham return error; 104a5a97ebeSJim Ingham } 105a5a97ebeSJim Ingham 106a5a97ebeSJim Ingham void 107a5a97ebeSJim Ingham OptionParsingStarting () 108a5a97ebeSJim Ingham { 109a5a97ebeSJim Ingham m_start_idx = 0; 110a5a97ebeSJim Ingham m_end_idx = UINT_MAX; 111a5a97ebeSJim Ingham } 112a5a97ebeSJim Ingham 113a5a97ebeSJim Ingham const OptionDefinition* 114a5a97ebeSJim Ingham GetDefinitions () 115a5a97ebeSJim Ingham { 116a5a97ebeSJim Ingham return g_option_table; 117a5a97ebeSJim Ingham } 118a5a97ebeSJim Ingham 119a5a97ebeSJim Ingham // Options table: Required for subclasses of Options. 120a5a97ebeSJim Ingham 121a5a97ebeSJim Ingham static OptionDefinition g_option_table[]; 122a5a97ebeSJim Ingham 123a5a97ebeSJim Ingham // Instance variables to hold the values for command options. 124a5a97ebeSJim Ingham 125a5a97ebeSJim Ingham uint32_t m_start_idx; 126a5a97ebeSJim Ingham uint32_t m_end_idx; 127a5a97ebeSJim Ingham }; 128a5a97ebeSJim Ingham 129a5a97ebeSJim Ingham bool 1305a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 131a5a97ebeSJim Ingham { 132a5a97ebeSJim Ingham 133a5a97ebeSJim Ingham m_interpreter.DumpHistory (result.GetOutputStream(), 134a5a97ebeSJim Ingham m_options.m_start_idx, 135a5a97ebeSJim Ingham m_options.m_end_idx); 136a5a97ebeSJim Ingham return result.Succeeded(); 137a5a97ebeSJim Ingham 138a5a97ebeSJim Ingham } 1395a988416SJim Ingham 1405a988416SJim Ingham CommandOptions m_options; 141a5a97ebeSJim Ingham }; 142a5a97ebeSJim Ingham 143a5a97ebeSJim Ingham OptionDefinition 144a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 145a5a97ebeSJim Ingham { 146a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 147a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."}, 148a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 149a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 150a5a97ebeSJim Ingham }; 151a5a97ebeSJim Ingham 152a5a97ebeSJim Ingham 153a5a97ebeSJim Ingham //------------------------------------------------------------------------- 154a5a97ebeSJim Ingham // CommandObjectCommandsSource 155a5a97ebeSJim Ingham //------------------------------------------------------------------------- 156a5a97ebeSJim Ingham 1575a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed 158ebc09c36SJim Ingham { 1595a988416SJim Ingham public: 1605a988416SJim Ingham CommandObjectCommandsSource(CommandInterpreter &interpreter) : 1615a988416SJim Ingham CommandObjectParsed (interpreter, 1625a988416SJim Ingham "command source", 1635a988416SJim Ingham "Read in debugger commands from the file <filename> and execute them.", 1645a988416SJim Ingham NULL), 1655a988416SJim Ingham m_options (interpreter) 1665a988416SJim Ingham { 1675a988416SJim Ingham CommandArgumentEntry arg; 1685a988416SJim Ingham CommandArgumentData file_arg; 1695a988416SJim Ingham 1705a988416SJim Ingham // Define the first (and only) variant of this arg. 1715a988416SJim Ingham file_arg.arg_type = eArgTypeFilename; 1725a988416SJim Ingham file_arg.arg_repetition = eArgRepeatPlain; 1735a988416SJim Ingham 1745a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 1755a988416SJim Ingham arg.push_back (file_arg); 1765a988416SJim Ingham 1775a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 1785a988416SJim Ingham m_arguments.push_back (arg); 1795a988416SJim Ingham } 1805a988416SJim Ingham 1815a988416SJim Ingham ~CommandObjectCommandsSource () {} 1825a988416SJim Ingham 1835a988416SJim Ingham virtual const char* 1845a988416SJim Ingham GetRepeatCommand (Args ¤t_command_args, uint32_t index) 1855a988416SJim Ingham { 1865a988416SJim Ingham return ""; 1875a988416SJim Ingham } 1885a988416SJim Ingham 1895a988416SJim Ingham int 1905a988416SJim Ingham HandleArgumentCompletion (Args &input, 1915a988416SJim Ingham int &cursor_index, 1925a988416SJim Ingham int &cursor_char_position, 1935a988416SJim Ingham OptionElementVector &opt_element_vector, 1945a988416SJim Ingham int match_start_point, 1955a988416SJim Ingham int max_return_elements, 1965a988416SJim Ingham bool &word_complete, 1975a988416SJim Ingham StringList &matches) 1985a988416SJim Ingham { 1995a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2005a988416SJim Ingham completion_str.erase (cursor_char_position); 2015a988416SJim Ingham 2025a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2035a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 2045a988416SJim Ingham completion_str.c_str(), 2055a988416SJim Ingham match_start_point, 2065a988416SJim Ingham max_return_elements, 2075a988416SJim Ingham NULL, 2085a988416SJim Ingham word_complete, 2095a988416SJim Ingham matches); 2105a988416SJim Ingham return matches.GetSize(); 2115a988416SJim Ingham } 2125a988416SJim Ingham 2135a988416SJim Ingham virtual Options * 2145a988416SJim Ingham GetOptions () 2155a988416SJim Ingham { 2165a988416SJim Ingham return &m_options; 2175a988416SJim Ingham } 2185a988416SJim Ingham 2195a988416SJim Ingham protected: 220e16c50a1SJim Ingham 221e16c50a1SJim Ingham class CommandOptions : public Options 222e16c50a1SJim Ingham { 223e16c50a1SJim Ingham public: 224e16c50a1SJim Ingham 225eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 226eb0103f2SGreg Clayton Options (interpreter) 227eb0103f2SGreg Clayton { 228eb0103f2SGreg Clayton } 229e16c50a1SJim Ingham 230e16c50a1SJim Ingham virtual 231e16c50a1SJim Ingham ~CommandOptions (){} 232e16c50a1SJim Ingham 233e16c50a1SJim Ingham virtual Error 234f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 235e16c50a1SJim Ingham { 236e16c50a1SJim Ingham Error error; 237e16c50a1SJim Ingham char short_option = (char) m_getopt_table[option_idx].val; 238e16c50a1SJim Ingham bool success; 239e16c50a1SJim Ingham 240e16c50a1SJim Ingham switch (short_option) 241e16c50a1SJim Ingham { 242e16c50a1SJim Ingham case 'e': 243e16c50a1SJim Ingham m_stop_on_error = Args::StringToBoolean(option_arg, true, &success); 244e16c50a1SJim Ingham if (!success) 24586edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg); 246e16c50a1SJim Ingham break; 247e16c50a1SJim Ingham case 'c': 248e16c50a1SJim Ingham m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success); 249e16c50a1SJim Ingham if (!success) 25086edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg); 251e16c50a1SJim Ingham break; 252e16c50a1SJim Ingham default: 25386edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 254e16c50a1SJim Ingham break; 255e16c50a1SJim Ingham } 256e16c50a1SJim Ingham 257e16c50a1SJim Ingham return error; 258e16c50a1SJim Ingham } 259e16c50a1SJim Ingham 260e16c50a1SJim Ingham void 261f6b8b581SGreg Clayton OptionParsingStarting () 262e16c50a1SJim Ingham { 263e16c50a1SJim Ingham m_stop_on_error = true; 264e16c50a1SJim Ingham m_stop_on_continue = true; 265e16c50a1SJim Ingham } 266e16c50a1SJim Ingham 267e0d378b3SGreg Clayton const OptionDefinition* 268e16c50a1SJim Ingham GetDefinitions () 269e16c50a1SJim Ingham { 270e16c50a1SJim Ingham return g_option_table; 271e16c50a1SJim Ingham } 272e16c50a1SJim Ingham 273e16c50a1SJim Ingham // Options table: Required for subclasses of Options. 274e16c50a1SJim Ingham 275e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 276e16c50a1SJim Ingham 277e16c50a1SJim Ingham // Instance variables to hold the values for command options. 278e16c50a1SJim Ingham 279e16c50a1SJim Ingham bool m_stop_on_error; 280e16c50a1SJim Ingham bool m_stop_on_continue; 281e16c50a1SJim Ingham }; 282e16c50a1SJim Ingham 283ebc09c36SJim Ingham bool 2845a988416SJim Ingham DoExecute(Args& command, CommandReturnObject &result) 285ebc09c36SJim Ingham { 2865a988416SJim Ingham const int argc = command.GetArgumentCount(); 287ebc09c36SJim Ingham if (argc == 1) 288ebc09c36SJim Ingham { 2895a988416SJim Ingham const char *filename = command.GetArgumentAtIndex(0); 290ebc09c36SJim Ingham 291ebc09c36SJim Ingham result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename); 292ebc09c36SJim Ingham 2931ee3853fSJohnny Chen FileSpec cmd_file (filename, true); 294e16c50a1SJim Ingham ExecutionContext *exe_ctx = NULL; // Just use the default context. 295e16c50a1SJim Ingham bool echo_commands = true; 296e16c50a1SJim Ingham bool print_results = true; 297ebc09c36SJim Ingham 298e16c50a1SJim Ingham m_interpreter.HandleCommandsFromFile (cmd_file, 299e16c50a1SJim Ingham exe_ctx, 300e16c50a1SJim Ingham m_options.m_stop_on_continue, 301e16c50a1SJim Ingham m_options.m_stop_on_error, 302e16c50a1SJim Ingham echo_commands, 303e16c50a1SJim Ingham print_results, 3045f5ab602SEnrico Granata eLazyBoolCalculate, 305e16c50a1SJim Ingham result); 306ebc09c36SJim Ingham } 307ebc09c36SJim Ingham else 308ebc09c36SJim Ingham { 309ebc09c36SJim Ingham result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName()); 310ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 311ebc09c36SJim Ingham } 312ebc09c36SJim Ingham return result.Succeeded(); 313ebc09c36SJim Ingham 314ebc09c36SJim Ingham } 3155a988416SJim Ingham CommandOptions m_options; 316ebc09c36SJim Ingham }; 317ebc09c36SJim Ingham 318e0d378b3SGreg Clayton OptionDefinition 319e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] = 320e16c50a1SJim Ingham { 321e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 322e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 323e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 324e16c50a1SJim Ingham }; 325e16c50a1SJim Ingham 326ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias 327ebc09c36SJim Ingham //------------------------------------------------------------------------- 328ebc09c36SJim Ingham // CommandObjectCommandsAlias 329ebc09c36SJim Ingham //------------------------------------------------------------------------- 330ebc09c36SJim Ingham 331be93a35aSEnrico Granata static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 332be93a35aSEnrico Granata "You must define a Python function with this signature:\n" 33340d55710SEnrico Granata "def my_command_impl(debugger, args, result, internal_dict):"; 334be93a35aSEnrico Granata 335be93a35aSEnrico Granata 3365a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw 337ebc09c36SJim Ingham { 338be93a35aSEnrico Granata 339be93a35aSEnrico Granata 340ebc09c36SJim Ingham public: 341a7015092SGreg Clayton CommandObjectCommandsAlias (CommandInterpreter &interpreter) : 3425a988416SJim Ingham CommandObjectRaw (interpreter, 3430e5e5a79SGreg Clayton "command alias", 344e3d26315SCaroline Tice "Allow users to define their own debugger command abbreviations.", 345405fe67fSCaroline Tice NULL) 346ebc09c36SJim Ingham { 347ebc09c36SJim Ingham SetHelpLong( 348ebc09c36SJim Ingham "'alias' allows the user to create a short-cut or abbreviation for long \n\ 349ebc09c36SJim Ingham commands, multi-word commands, and commands that take particular options. \n\ 350ebc09c36SJim Ingham Below are some simple examples of how one might use the 'alias' command: \n\ 35169c12ccbSJason Molenda \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ 352ebc09c36SJim Ingham // command. \n\ 35369c12ccbSJason Molenda 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ 354ebc09c36SJim Ingham // command. Since breakpoint commands are two-word \n\ 355ebc09c36SJim Ingham // commands, the user will still need to enter the \n\ 356ebc09c36SJim Ingham // second word after 'bp', e.g. 'bp enable' or \n\ 357ebc09c36SJim Ingham // 'bp delete'. \n\ 35869c12ccbSJason Molenda 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\ 359ebc09c36SJim Ingham // two-word command 'breakpoint list'. \n\ 360ebc09c36SJim Ingham \nAn alias can include some options for the command, with the values either \n\ 361ebc09c36SJim Ingham filled in at the time the alias is created, or specified as positional \n\ 362ebc09c36SJim Ingham arguments, to be filled in when the alias is invoked. The following example \n\ 363ebc09c36SJim Ingham shows how to create aliases with options: \n\ 364ebc09c36SJim Ingham \n\ 36569c12ccbSJason Molenda 'command alias bfl breakpoint set -f %1 -l %2' \n\ 366ebc09c36SJim Ingham \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ 367ebc09c36SJim Ingham options already part of the alias. So if the user wants to set a breakpoint \n\ 368ebc09c36SJim Ingham by file and line without explicitly having to use the -f and -l options, the \n\ 369ebc09c36SJim Ingham user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\ 370ebc09c36SJim Ingham for the actual arguments that will be passed when the alias command is used. \n\ 371ebc09c36SJim Ingham The number in the placeholder refers to the position/order the actual value \n\ 37281ded935SJim Ingham occupies when the alias is used. All the occurrences of '%1' in the alias \n\ 373ebc09c36SJim Ingham will be replaced with the first argument, all the occurrences of '%2' in the \n\ 374ebc09c36SJim Ingham alias will be replaced with the second argument, and so on. This also allows \n\ 375ebc09c36SJim Ingham actual arguments to be used multiple times within an alias (see 'process \n\ 37681ded935SJim Ingham launch' example below). \n\ 37781ded935SJim Ingham Note: the positional arguments must substitute as whole words in the resultant\n\ 37881ded935SJim Ingham command, so you can't at present do something like:\n\ 37981ded935SJim Ingham \n\ 38069c12ccbSJason Molenda command alias bcppfl breakpoint set -f %1.cpp -l %2\n\ 38181ded935SJim Ingham \n\ 38281ded935SJim Ingham to get the file extension \".cpp\" automatically appended. For more complex\n\ 38381ded935SJim Ingham aliasing, use the \"command regex\" command instead.\n\ 38481ded935SJim Ingham \nSo in the 'bfl' case, the actual file value will be \n\ 385ebc09c36SJim Ingham filled in with the first argument following 'bfl' and the actual line number \n\ 386ebc09c36SJim Ingham value will be filled in with the second argument. The user would use this \n\ 387ebc09c36SJim Ingham alias as follows: \n\ 38869c12ccbSJason Molenda \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\ 389ebc09c36SJim Ingham <... some time later ...> \n\ 39009799af6SCaroline Tice (lldb) bfl my-file.c 137 \n\ 391ebc09c36SJim Ingham \nThis would be the same as if the user had entered \n\ 392ebc09c36SJim Ingham 'breakpoint set -f my-file.c -l 137'. \n\ 393ebc09c36SJim Ingham \nAnother example: \n\ 39469c12ccbSJason Molenda \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\ 39509799af6SCaroline Tice (lldb) pltty /dev/tty0 \n\ 396ebc09c36SJim Ingham // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ 397ebc09c36SJim Ingham \nIf the user always wanted to pass the same value to a particular option, the \n\ 398ebc09c36SJim Ingham alias could be defined with that value directly in the alias as a constant, \n\ 399ebc09c36SJim Ingham rather than using a positional placeholder: \n\ 40069c12ccbSJason Molenda \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ 401ebc09c36SJim Ingham // 3 of whatever file is indicated. \n"); 402ebc09c36SJim Ingham 403405fe67fSCaroline Tice CommandArgumentEntry arg1; 404405fe67fSCaroline Tice CommandArgumentEntry arg2; 405405fe67fSCaroline Tice CommandArgumentEntry arg3; 406405fe67fSCaroline Tice CommandArgumentData alias_arg; 407405fe67fSCaroline Tice CommandArgumentData cmd_arg; 408405fe67fSCaroline Tice CommandArgumentData options_arg; 409405fe67fSCaroline Tice 410405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 411405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 412405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 413405fe67fSCaroline Tice 414405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 415405fe67fSCaroline Tice arg1.push_back (alias_arg); 416405fe67fSCaroline Tice 417405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 418405fe67fSCaroline Tice cmd_arg.arg_type = eArgTypeCommandName; 419405fe67fSCaroline Tice cmd_arg.arg_repetition = eArgRepeatPlain; 420405fe67fSCaroline Tice 421405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 422405fe67fSCaroline Tice arg2.push_back (cmd_arg); 423405fe67fSCaroline Tice 424405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 425405fe67fSCaroline Tice options_arg.arg_type = eArgTypeAliasOptions; 426405fe67fSCaroline Tice options_arg.arg_repetition = eArgRepeatOptional; 427405fe67fSCaroline Tice 428405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 429405fe67fSCaroline Tice arg3.push_back (options_arg); 430405fe67fSCaroline Tice 431405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 432405fe67fSCaroline Tice m_arguments.push_back (arg1); 433405fe67fSCaroline Tice m_arguments.push_back (arg2); 434405fe67fSCaroline Tice m_arguments.push_back (arg3); 435ebc09c36SJim Ingham } 436ebc09c36SJim Ingham 437ebc09c36SJim Ingham ~CommandObjectCommandsAlias () 438ebc09c36SJim Ingham { 439ebc09c36SJim Ingham } 440ebc09c36SJim Ingham 4415a988416SJim Ingham protected: 4425a988416SJim Ingham virtual bool 4435a988416SJim Ingham DoExecute (const char *raw_command_line, CommandReturnObject &result) 444844d2303SCaroline Tice { 445844d2303SCaroline Tice Args args (raw_command_line); 446844d2303SCaroline Tice std::string raw_command_string (raw_command_line); 447844d2303SCaroline Tice 448844d2303SCaroline Tice size_t argc = args.GetArgumentCount(); 449844d2303SCaroline Tice 450844d2303SCaroline Tice if (argc < 2) 451844d2303SCaroline Tice { 452844d2303SCaroline Tice result.AppendError ("'alias' requires at least two arguments"); 453844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 454844d2303SCaroline Tice return false; 455844d2303SCaroline Tice } 456844d2303SCaroline Tice 457844d2303SCaroline Tice // Get the alias command. 458844d2303SCaroline Tice 459844d2303SCaroline Tice const std::string alias_command = args.GetArgumentAtIndex (0); 460844d2303SCaroline Tice 461844d2303SCaroline Tice // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 462844d2303SCaroline Tice // does the stripping itself. 463844d2303SCaroline Tice size_t pos = raw_command_string.find (alias_command); 464844d2303SCaroline Tice if (pos == 0) 465844d2303SCaroline Tice { 466844d2303SCaroline Tice raw_command_string = raw_command_string.substr (alias_command.size()); 467844d2303SCaroline Tice pos = raw_command_string.find_first_not_of (' '); 468844d2303SCaroline Tice if ((pos != std::string::npos) && (pos > 0)) 469844d2303SCaroline Tice raw_command_string = raw_command_string.substr (pos); 470844d2303SCaroline Tice } 471844d2303SCaroline Tice else 472844d2303SCaroline Tice { 473844d2303SCaroline Tice result.AppendError ("Error parsing command string. No alias created."); 474844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 475844d2303SCaroline Tice return false; 476844d2303SCaroline Tice } 477844d2303SCaroline Tice 478844d2303SCaroline Tice 479844d2303SCaroline Tice // Verify that the command is alias-able. 480844d2303SCaroline Tice if (m_interpreter.CommandExists (alias_command.c_str())) 481844d2303SCaroline Tice { 482844d2303SCaroline Tice result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 483844d2303SCaroline Tice alias_command.c_str()); 484844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 485844d2303SCaroline Tice return false; 486844d2303SCaroline Tice } 487844d2303SCaroline Tice 488844d2303SCaroline Tice // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 489844d2303SCaroline Tice // raw_command_string is returned with the name of the command object stripped off the front. 490844d2303SCaroline Tice CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 491844d2303SCaroline Tice 492844d2303SCaroline Tice if (!cmd_obj) 493844d2303SCaroline Tice { 49486edbf41SGreg Clayton result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command." 495844d2303SCaroline Tice " No alias created.", raw_command_string.c_str()); 496844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 497844d2303SCaroline Tice return false; 498844d2303SCaroline Tice } 499844d2303SCaroline Tice else if (!cmd_obj->WantsRawCommandString ()) 500844d2303SCaroline Tice { 501844d2303SCaroline Tice // Note that args was initialized with the original command, and has not been updated to this point. 502844d2303SCaroline Tice // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 5035a988416SJim Ingham return HandleAliasingNormalCommand (args, result); 504844d2303SCaroline Tice } 505844d2303SCaroline Tice else 506844d2303SCaroline Tice { 5075a988416SJim Ingham return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result); 5085a988416SJim Ingham } 5095a988416SJim Ingham return result.Succeeded(); 5105a988416SJim Ingham } 5115a988416SJim Ingham 5125a988416SJim Ingham bool 5135a988416SJim Ingham HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result) 5145a988416SJim Ingham { 515844d2303SCaroline Tice // Verify & handle any options/arguments passed to the alias command 516844d2303SCaroline Tice 517844d2303SCaroline Tice OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 518844d2303SCaroline Tice OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 519844d2303SCaroline Tice 5205a988416SJim Ingham CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false); 521844d2303SCaroline Tice 522ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp)) 523844d2303SCaroline Tice { 524844d2303SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 525ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 526844d2303SCaroline Tice return false; 527844d2303SCaroline Tice } 528844d2303SCaroline Tice 529844d2303SCaroline Tice // Create the alias 530844d2303SCaroline Tice if (m_interpreter.AliasExists (alias_command.c_str()) 531844d2303SCaroline Tice || m_interpreter.UserCommandExists (alias_command.c_str())) 532844d2303SCaroline Tice { 533844d2303SCaroline Tice OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 534844d2303SCaroline Tice if (temp_option_arg_sp.get()) 535844d2303SCaroline Tice { 536844d2303SCaroline Tice if (option_arg_vector->size() == 0) 537844d2303SCaroline Tice m_interpreter.RemoveAliasOptions (alias_command.c_str()); 538844d2303SCaroline Tice } 539844d2303SCaroline Tice result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 540844d2303SCaroline Tice alias_command.c_str()); 541844d2303SCaroline Tice } 542844d2303SCaroline Tice 543472362e6SCaroline Tice if (cmd_obj_sp) 544472362e6SCaroline Tice { 545844d2303SCaroline Tice m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); 546844d2303SCaroline Tice if (option_arg_vector->size() > 0) 547844d2303SCaroline Tice m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 548844d2303SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 549844d2303SCaroline Tice } 550472362e6SCaroline Tice else 551472362e6SCaroline Tice { 552472362e6SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 553472362e6SCaroline Tice result.SetStatus (eReturnStatusFailed); 554472362e6SCaroline Tice } 555844d2303SCaroline Tice return result.Succeeded (); 556844d2303SCaroline Tice } 557ebc09c36SJim Ingham 558ebc09c36SJim Ingham bool 5595a988416SJim Ingham HandleAliasingNormalCommand (Args& args, CommandReturnObject &result) 560ebc09c36SJim Ingham { 561867b185dSCaroline Tice size_t argc = args.GetArgumentCount(); 562ebc09c36SJim Ingham 563ebc09c36SJim Ingham if (argc < 2) 564ebc09c36SJim Ingham { 565ebc09c36SJim Ingham result.AppendError ("'alias' requires at least two arguments"); 566ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 567ebc09c36SJim Ingham return false; 568ebc09c36SJim Ingham } 569ebc09c36SJim Ingham 570ebc09c36SJim Ingham const std::string alias_command = args.GetArgumentAtIndex(0); 571ebc09c36SJim Ingham const std::string actual_command = args.GetArgumentAtIndex(1); 572ebc09c36SJim Ingham 573ebc09c36SJim Ingham args.Shift(); // Shift the alias command word off the argument vector. 574ebc09c36SJim Ingham args.Shift(); // Shift the old command word off the argument vector. 575ebc09c36SJim Ingham 576ebc09c36SJim Ingham // Verify that the command is alias'able, and get the appropriate command object. 577ebc09c36SJim Ingham 578a7015092SGreg Clayton if (m_interpreter.CommandExists (alias_command.c_str())) 579ebc09c36SJim Ingham { 580ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 581ebc09c36SJim Ingham alias_command.c_str()); 582ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 583ebc09c36SJim Ingham } 584ebc09c36SJim Ingham else 585ebc09c36SJim Ingham { 586a7015092SGreg Clayton CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 587ebc09c36SJim Ingham CommandObjectSP subcommand_obj_sp; 588ebc09c36SJim Ingham bool use_subcommand = false; 589ebc09c36SJim Ingham if (command_obj_sp.get()) 590ebc09c36SJim Ingham { 591ebc09c36SJim Ingham CommandObject *cmd_obj = command_obj_sp.get(); 592c982c768SGreg Clayton CommandObject *sub_cmd_obj = NULL; 593ebc09c36SJim Ingham OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 594ebc09c36SJim Ingham OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 595ebc09c36SJim Ingham 596844d2303SCaroline Tice while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 597ebc09c36SJim Ingham { 598ebc09c36SJim Ingham if (argc >= 3) 599ebc09c36SJim Ingham { 600ebc09c36SJim Ingham const std::string sub_command = args.GetArgumentAtIndex(0); 601ebc09c36SJim Ingham assert (sub_command.length() != 0); 602ebc09c36SJim Ingham subcommand_obj_sp = 603ebc09c36SJim Ingham (((CommandObjectMultiword *) cmd_obj)->GetSubcommandSP (sub_command.c_str())); 604ebc09c36SJim Ingham if (subcommand_obj_sp.get()) 605ebc09c36SJim Ingham { 606ebc09c36SJim Ingham sub_cmd_obj = subcommand_obj_sp.get(); 607ebc09c36SJim Ingham use_subcommand = true; 608ebc09c36SJim Ingham args.Shift(); // Shift the sub_command word off the argument vector. 609844d2303SCaroline Tice cmd_obj = sub_cmd_obj; 610ebc09c36SJim Ingham } 611ebc09c36SJim Ingham else 612ebc09c36SJim Ingham { 613f415eeb4SCaroline Tice result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 614f415eeb4SCaroline Tice "Unable to create alias.\n", 615f415eeb4SCaroline Tice sub_command.c_str(), actual_command.c_str()); 616ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 617ebc09c36SJim Ingham return false; 618ebc09c36SJim Ingham } 619ebc09c36SJim Ingham } 620ebc09c36SJim Ingham } 621ebc09c36SJim Ingham 622ebc09c36SJim Ingham // Verify & handle any options/arguments passed to the alias command 623ebc09c36SJim Ingham 624ebc09c36SJim Ingham if (args.GetArgumentCount () > 0) 625ebc09c36SJim Ingham { 626ca90c47eSCaroline Tice CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 627ebc09c36SJim Ingham if (use_subcommand) 628ca90c47eSCaroline Tice tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 629ca90c47eSCaroline Tice 630ca90c47eSCaroline Tice std::string args_string; 631ca90c47eSCaroline Tice args.GetCommandString (args_string); 632ca90c47eSCaroline Tice 633ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp)) 634ebc09c36SJim Ingham { 635ca90c47eSCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 636ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 637e7941795SCaroline Tice return false; 638867b185dSCaroline Tice } 639867b185dSCaroline Tice } 640867b185dSCaroline Tice 641ebc09c36SJim Ingham // Create the alias. 642ebc09c36SJim Ingham 643a7015092SGreg Clayton if (m_interpreter.AliasExists (alias_command.c_str()) 644a7015092SGreg Clayton || m_interpreter.UserCommandExists (alias_command.c_str())) 645ebc09c36SJim Ingham { 646a7015092SGreg Clayton OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 647ebc09c36SJim Ingham if (tmp_option_arg_sp.get()) 648ebc09c36SJim Ingham { 649ebc09c36SJim Ingham if (option_arg_vector->size() == 0) 650a7015092SGreg Clayton m_interpreter.RemoveAliasOptions (alias_command.c_str()); 651ebc09c36SJim Ingham } 652ebc09c36SJim Ingham result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 653ebc09c36SJim Ingham alias_command.c_str()); 654ebc09c36SJim Ingham } 655ebc09c36SJim Ingham 656ebc09c36SJim Ingham if (use_subcommand) 657a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp); 658ebc09c36SJim Ingham else 659a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp); 660ebc09c36SJim Ingham if (option_arg_vector->size() > 0) 661a7015092SGreg Clayton m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 662ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 663ebc09c36SJim Ingham } 664ebc09c36SJim Ingham else 665ebc09c36SJim Ingham { 666ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 667ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 668e7941795SCaroline Tice return false; 669ebc09c36SJim Ingham } 670ebc09c36SJim Ingham } 671ebc09c36SJim Ingham 672ebc09c36SJim Ingham return result.Succeeded(); 673ebc09c36SJim Ingham } 6745a988416SJim Ingham 675ebc09c36SJim Ingham }; 676ebc09c36SJim Ingham 677ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias 678ebc09c36SJim Ingham //------------------------------------------------------------------------- 679ebc09c36SJim Ingham // CommandObjectCommandsUnalias 680ebc09c36SJim Ingham //------------------------------------------------------------------------- 681ebc09c36SJim Ingham 6825a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed 683ebc09c36SJim Ingham { 684ebc09c36SJim Ingham public: 685a7015092SGreg Clayton CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 6865a988416SJim Ingham CommandObjectParsed (interpreter, 6870e5e5a79SGreg Clayton "command unalias", 68886ddae50SCaroline Tice "Allow the user to remove/delete a user-defined command abbreviation.", 689405fe67fSCaroline Tice NULL) 690ebc09c36SJim Ingham { 691405fe67fSCaroline Tice CommandArgumentEntry arg; 692405fe67fSCaroline Tice CommandArgumentData alias_arg; 693405fe67fSCaroline Tice 694405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 695405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 696405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 697405fe67fSCaroline Tice 698405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 699405fe67fSCaroline Tice arg.push_back (alias_arg); 700405fe67fSCaroline Tice 701405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 702405fe67fSCaroline Tice m_arguments.push_back (arg); 703ebc09c36SJim Ingham } 704ebc09c36SJim Ingham 705ebc09c36SJim Ingham ~CommandObjectCommandsUnalias() 706ebc09c36SJim Ingham { 707ebc09c36SJim Ingham } 708ebc09c36SJim Ingham 7095a988416SJim Ingham protected: 710ebc09c36SJim Ingham bool 7115a988416SJim Ingham DoExecute (Args& args, CommandReturnObject &result) 712ebc09c36SJim Ingham { 713ebc09c36SJim Ingham CommandObject::CommandMap::iterator pos; 714ebc09c36SJim Ingham CommandObject *cmd_obj; 715ebc09c36SJim Ingham 716ebc09c36SJim Ingham if (args.GetArgumentCount() != 0) 717ebc09c36SJim Ingham { 718ebc09c36SJim Ingham const char *command_name = args.GetArgumentAtIndex(0); 719a7015092SGreg Clayton cmd_obj = m_interpreter.GetCommandObject(command_name); 720ebc09c36SJim Ingham if (cmd_obj) 721ebc09c36SJim Ingham { 722a7015092SGreg Clayton if (m_interpreter.CommandExists (command_name)) 723ebc09c36SJim Ingham { 724ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 725ebc09c36SJim Ingham command_name); 726ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 727ebc09c36SJim Ingham } 728ebc09c36SJim Ingham else 729ebc09c36SJim Ingham { 730ebc09c36SJim Ingham 731a7015092SGreg Clayton if (m_interpreter.RemoveAlias (command_name) == false) 732ebc09c36SJim Ingham { 733a7015092SGreg Clayton if (m_interpreter.AliasExists (command_name)) 734ebc09c36SJim Ingham result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 735ebc09c36SJim Ingham command_name); 736ebc09c36SJim Ingham else 737ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 738ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 739ebc09c36SJim Ingham } 740ebc09c36SJim Ingham else 741ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 742ebc09c36SJim Ingham } 743ebc09c36SJim Ingham } 744ebc09c36SJim Ingham else 745ebc09c36SJim Ingham { 746ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 747ebc09c36SJim Ingham "current list of commands.\n", 748ebc09c36SJim Ingham command_name); 749ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 750ebc09c36SJim Ingham } 751ebc09c36SJim Ingham } 752ebc09c36SJim Ingham else 753ebc09c36SJim Ingham { 754ebc09c36SJim Ingham result.AppendError ("must call 'unalias' with a valid alias"); 755ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 756ebc09c36SJim Ingham } 757ebc09c36SJim Ingham 758ebc09c36SJim Ingham return result.Succeeded(); 759ebc09c36SJim Ingham } 760ebc09c36SJim Ingham }; 761ebc09c36SJim Ingham 762de164aaaSGreg Clayton //------------------------------------------------------------------------- 763de164aaaSGreg Clayton // CommandObjectCommandsAddRegex 764de164aaaSGreg Clayton //------------------------------------------------------------------------- 7655a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex 766de164aaaSGreg Clayton 7675a988416SJim Ingham class CommandObjectCommandsAddRegex : public CommandObjectParsed 768de164aaaSGreg Clayton { 769de164aaaSGreg Clayton public: 770de164aaaSGreg Clayton CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 7715a988416SJim Ingham CommandObjectParsed (interpreter, 7720e5e5a79SGreg Clayton "command regex", 773de164aaaSGreg Clayton "Allow the user to create a regular expression command.", 7740e5e5a79SGreg Clayton "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 775de164aaaSGreg Clayton m_options (interpreter) 776de164aaaSGreg Clayton { 7770e5e5a79SGreg Clayton SetHelpLong( 7780e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n" 7790e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n" 7800e5e5a79SGreg Clayton "using the regular exression substitution format of:\n" 7810e5e5a79SGreg Clayton "\n" 7820e5e5a79SGreg Clayton " s/<regex>/<subst>/\n" 7830e5e5a79SGreg Clayton "\n" 7840e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n" 7850e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n" 7860e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n" 7870e5e5a79SGreg Clayton "\n" 7880e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n" 7890e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n" 7900e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n" 7910e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n" 7920e5e5a79SGreg Clayton "\n" 7930e5e5a79SGreg Clayton "EXAMPLES\n" 7940e5e5a79SGreg Clayton "\n" 795adc43c99SSean Callanan "The following example will define a regular expression command named 'f' that\n" 7960e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n" 7970e5e5a79SGreg Clayton "a number follows 'f':\n" 798adc43c99SSean Callanan "\n" 7990e5e5a79SGreg Clayton " (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" 800adc43c99SSean Callanan "\n" 8010e5e5a79SGreg Clayton ); 802de164aaaSGreg Clayton } 803de164aaaSGreg Clayton 804de164aaaSGreg Clayton ~CommandObjectCommandsAddRegex() 805de164aaaSGreg Clayton { 806de164aaaSGreg Clayton } 807de164aaaSGreg Clayton 808de164aaaSGreg Clayton 8095a988416SJim Ingham protected: 810de164aaaSGreg Clayton bool 8115a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 812de164aaaSGreg Clayton { 8135a988416SJim Ingham const size_t argc = command.GetArgumentCount(); 8140e5e5a79SGreg Clayton if (argc == 0) 815de164aaaSGreg Clayton { 81669c12ccbSJason Molenda result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 8170e5e5a79SGreg Clayton result.SetStatus (eReturnStatusFailed); 8180e5e5a79SGreg Clayton } 8190e5e5a79SGreg Clayton else 8200e5e5a79SGreg Clayton { 8210e5e5a79SGreg Clayton Error error; 8225a988416SJim Ingham const char *name = command.GetArgumentAtIndex(0); 823de164aaaSGreg Clayton m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 824de164aaaSGreg Clayton name, 825de164aaaSGreg Clayton m_options.GetHelp (), 826de164aaaSGreg Clayton m_options.GetSyntax (), 827de164aaaSGreg Clayton 10)); 8280e5e5a79SGreg Clayton 8290e5e5a79SGreg Clayton if (argc == 1) 8300e5e5a79SGreg Clayton { 8310e5e5a79SGreg Clayton InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 832de164aaaSGreg Clayton if (reader_sp) 833de164aaaSGreg Clayton { 8340e5e5a79SGreg Clayton error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback, 835de164aaaSGreg Clayton this, // baton 836de164aaaSGreg Clayton eInputReaderGranularityLine, // token size, to pass to callback function 8370e5e5a79SGreg Clayton NULL, // end token 838de164aaaSGreg Clayton "> ", // prompt 8390e5e5a79SGreg Clayton true); // echo input 8400e5e5a79SGreg Clayton if (error.Success()) 841de164aaaSGreg Clayton { 842de164aaaSGreg Clayton m_interpreter.GetDebugger().PushInputReader (reader_sp); 843de164aaaSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 8440e5e5a79SGreg Clayton return true; 845de164aaaSGreg Clayton } 846de164aaaSGreg Clayton } 847de164aaaSGreg Clayton } 848de164aaaSGreg Clayton else 849de164aaaSGreg Clayton { 8500e5e5a79SGreg Clayton for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 8510e5e5a79SGreg Clayton { 8525a988416SJim Ingham llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 8530e5e5a79SGreg Clayton error = AppendRegexSubstitution (arg_strref); 8540e5e5a79SGreg Clayton if (error.Fail()) 8550e5e5a79SGreg Clayton break; 8560e5e5a79SGreg Clayton } 8570e5e5a79SGreg Clayton 8580e5e5a79SGreg Clayton if (error.Success()) 8590e5e5a79SGreg Clayton { 8600e5e5a79SGreg Clayton AddRegexCommandToInterpreter(); 8610e5e5a79SGreg Clayton } 8620e5e5a79SGreg Clayton } 8630e5e5a79SGreg Clayton if (error.Fail()) 8640e5e5a79SGreg Clayton { 8650e5e5a79SGreg Clayton result.AppendError (error.AsCString()); 866de164aaaSGreg Clayton result.SetStatus (eReturnStatusFailed); 867de164aaaSGreg Clayton } 8680e5e5a79SGreg Clayton } 8690e5e5a79SGreg Clayton 870de164aaaSGreg Clayton return result.Succeeded(); 871de164aaaSGreg Clayton } 872de164aaaSGreg Clayton 8730e5e5a79SGreg Clayton Error 8740e5e5a79SGreg Clayton AppendRegexSubstitution (const llvm::StringRef ®ex_sed) 875de164aaaSGreg Clayton { 8760e5e5a79SGreg Clayton Error error; 8770e5e5a79SGreg Clayton 8780e5e5a79SGreg Clayton if (m_regex_cmd_ap.get() == NULL) 879de164aaaSGreg Clayton { 8800e5e5a79SGreg Clayton error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 8810e5e5a79SGreg Clayton (int)regex_sed.size(), 8820e5e5a79SGreg Clayton regex_sed.data()); 8830e5e5a79SGreg Clayton return error; 884de164aaaSGreg Clayton } 8850e5e5a79SGreg Clayton 8860e5e5a79SGreg Clayton size_t regex_sed_size = regex_sed.size(); 8870e5e5a79SGreg Clayton 8880e5e5a79SGreg Clayton if (regex_sed_size <= 1) 8890e5e5a79SGreg Clayton { 8900e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 8910e5e5a79SGreg Clayton (int)regex_sed.size(), 8920e5e5a79SGreg Clayton regex_sed.data()); 8930e5e5a79SGreg Clayton return error; 8940e5e5a79SGreg Clayton } 8950e5e5a79SGreg Clayton 8960e5e5a79SGreg Clayton if (regex_sed[0] != 's') 8970e5e5a79SGreg Clayton { 8980e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 8990e5e5a79SGreg Clayton (int)regex_sed.size(), 9000e5e5a79SGreg Clayton regex_sed.data()); 9010e5e5a79SGreg Clayton return error; 9020e5e5a79SGreg Clayton } 9030e5e5a79SGreg Clayton const size_t first_separator_char_pos = 1; 9040e5e5a79SGreg Clayton // use the char that follows 's' as the regex separator character 9050e5e5a79SGreg Clayton // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 9060e5e5a79SGreg Clayton const char separator_char = regex_sed[first_separator_char_pos]; 9070e5e5a79SGreg Clayton const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 9080e5e5a79SGreg Clayton 9090e5e5a79SGreg Clayton if (second_separator_char_pos == std::string::npos) 9100e5e5a79SGreg Clayton { 9110e5e5a79SGreg Clayton error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'", 9120e5e5a79SGreg Clayton separator_char, 9130e5e5a79SGreg Clayton (int)(regex_sed.size() - first_separator_char_pos - 1), 9140e5e5a79SGreg Clayton regex_sed.data() + (first_separator_char_pos + 1)); 9150e5e5a79SGreg Clayton return error; 9160e5e5a79SGreg Clayton } 9170e5e5a79SGreg Clayton 9180e5e5a79SGreg Clayton const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 9190e5e5a79SGreg Clayton 9200e5e5a79SGreg Clayton if (third_separator_char_pos == std::string::npos) 9210e5e5a79SGreg Clayton { 9220e5e5a79SGreg Clayton error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'", 9230e5e5a79SGreg Clayton separator_char, 9240e5e5a79SGreg Clayton (int)(regex_sed.size() - second_separator_char_pos - 1), 9250e5e5a79SGreg Clayton regex_sed.data() + (second_separator_char_pos + 1)); 9260e5e5a79SGreg Clayton return error; 9270e5e5a79SGreg Clayton } 9280e5e5a79SGreg Clayton 9290e5e5a79SGreg Clayton if (third_separator_char_pos != regex_sed_size - 1) 9300e5e5a79SGreg Clayton { 9310e5e5a79SGreg Clayton // Make sure that everything that follows the last regex 9320e5e5a79SGreg Clayton // separator char 9330e5e5a79SGreg Clayton if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 9340e5e5a79SGreg Clayton { 9350e5e5a79SGreg Clayton error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 9360e5e5a79SGreg Clayton (int)third_separator_char_pos + 1, 9370e5e5a79SGreg Clayton regex_sed.data(), 9380e5e5a79SGreg Clayton (int)(regex_sed.size() - third_separator_char_pos - 1), 9390e5e5a79SGreg Clayton regex_sed.data() + (third_separator_char_pos + 1)); 9400e5e5a79SGreg Clayton return error; 9410e5e5a79SGreg Clayton } 9420e5e5a79SGreg Clayton 9430e5e5a79SGreg Clayton } 9440e5e5a79SGreg Clayton else if (first_separator_char_pos + 1 == second_separator_char_pos) 9450e5e5a79SGreg Clayton { 9460e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 9470e5e5a79SGreg Clayton separator_char, 9480e5e5a79SGreg Clayton separator_char, 9490e5e5a79SGreg Clayton separator_char, 9500e5e5a79SGreg Clayton (int)regex_sed.size(), 9510e5e5a79SGreg Clayton regex_sed.data()); 9520e5e5a79SGreg Clayton return error; 9530e5e5a79SGreg Clayton } 9540e5e5a79SGreg Clayton else if (second_separator_char_pos + 1 == third_separator_char_pos) 9550e5e5a79SGreg Clayton { 9560e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 9570e5e5a79SGreg Clayton separator_char, 9580e5e5a79SGreg Clayton separator_char, 9590e5e5a79SGreg Clayton separator_char, 9600e5e5a79SGreg Clayton (int)regex_sed.size(), 9610e5e5a79SGreg Clayton regex_sed.data()); 9620e5e5a79SGreg Clayton return error; 9630e5e5a79SGreg Clayton } 9640e5e5a79SGreg Clayton std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 9650e5e5a79SGreg Clayton std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 9660e5e5a79SGreg Clayton m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 9670e5e5a79SGreg Clayton subst.c_str()); 9680e5e5a79SGreg Clayton return error; 969de164aaaSGreg Clayton } 970de164aaaSGreg Clayton 971de164aaaSGreg Clayton void 9720e5e5a79SGreg Clayton AddRegexCommandToInterpreter() 973de164aaaSGreg Clayton { 974de164aaaSGreg Clayton if (m_regex_cmd_ap.get()) 975de164aaaSGreg Clayton { 976de164aaaSGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 977de164aaaSGreg Clayton { 978de164aaaSGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 979de164aaaSGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 980de164aaaSGreg Clayton } 981de164aaaSGreg Clayton } 982de164aaaSGreg Clayton } 983de164aaaSGreg Clayton 9840e5e5a79SGreg Clayton void 9850e5e5a79SGreg Clayton InputReaderDidCancel() 9860e5e5a79SGreg Clayton { 9870e5e5a79SGreg Clayton m_regex_cmd_ap.reset(); 9880e5e5a79SGreg Clayton } 9890e5e5a79SGreg Clayton 990de164aaaSGreg Clayton static size_t 991de164aaaSGreg Clayton InputReaderCallback (void *baton, 992de164aaaSGreg Clayton InputReader &reader, 993de164aaaSGreg Clayton lldb::InputReaderAction notification, 994de164aaaSGreg Clayton const char *bytes, 9955a988416SJim Ingham size_t bytes_len) 9965a988416SJim Ingham { 9975a988416SJim Ingham CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton; 9985a988416SJim Ingham bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 9995a988416SJim Ingham 10005a988416SJim Ingham switch (notification) 10015a988416SJim Ingham { 10025a988416SJim Ingham case eInputReaderActivate: 10035a988416SJim Ingham if (!batch_mode) 10045a988416SJim Ingham { 10055a988416SJim Ingham StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream (); 10065a988416SJim Ingham out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:"); 10075a988416SJim Ingham out_stream->Flush(); 10085a988416SJim Ingham } 10095a988416SJim Ingham break; 10105a988416SJim Ingham case eInputReaderReactivate: 10115a988416SJim Ingham break; 10125a988416SJim Ingham 10135a988416SJim Ingham case eInputReaderDeactivate: 10145a988416SJim Ingham break; 10155a988416SJim Ingham 10165a988416SJim Ingham case eInputReaderAsynchronousOutputWritten: 10175a988416SJim Ingham break; 10185a988416SJim Ingham 10195a988416SJim Ingham case eInputReaderGotToken: 10205a988416SJim Ingham while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n')) 10215a988416SJim Ingham --bytes_len; 10225a988416SJim Ingham if (bytes_len == 0) 10235a988416SJim Ingham reader.SetIsDone(true); 10245a988416SJim Ingham else if (bytes) 10255a988416SJim Ingham { 10265a988416SJim Ingham llvm::StringRef bytes_strref (bytes, bytes_len); 10275a988416SJim Ingham Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref)); 10285a988416SJim Ingham if (error.Fail()) 10295a988416SJim Ingham { 10305a988416SJim Ingham if (!batch_mode) 10315a988416SJim Ingham { 10325a988416SJim Ingham StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 10335a988416SJim Ingham out_stream->Printf("error: %s\n", error.AsCString()); 10345a988416SJim Ingham out_stream->Flush(); 10355a988416SJim Ingham } 10365a988416SJim Ingham add_regex_cmd->InputReaderDidCancel (); 10375a988416SJim Ingham reader.SetIsDone (true); 10385a988416SJim Ingham } 10395a988416SJim Ingham } 10405a988416SJim Ingham break; 10415a988416SJim Ingham 10425a988416SJim Ingham case eInputReaderInterrupt: 10435a988416SJim Ingham { 10445a988416SJim Ingham reader.SetIsDone (true); 10455a988416SJim Ingham if (!batch_mode) 10465a988416SJim Ingham { 10475a988416SJim Ingham StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 10485a988416SJim Ingham out_stream->PutCString("Regular expression command creations was cancelled.\n"); 10495a988416SJim Ingham out_stream->Flush(); 10505a988416SJim Ingham } 10515a988416SJim Ingham add_regex_cmd->InputReaderDidCancel (); 10525a988416SJim Ingham } 10535a988416SJim Ingham break; 10545a988416SJim Ingham 10555a988416SJim Ingham case eInputReaderEndOfFile: 10565a988416SJim Ingham reader.SetIsDone (true); 10575a988416SJim Ingham break; 10585a988416SJim Ingham 10595a988416SJim Ingham case eInputReaderDone: 10605a988416SJim Ingham add_regex_cmd->AddRegexCommandToInterpreter(); 10615a988416SJim Ingham break; 10625a988416SJim Ingham } 10635a988416SJim Ingham 10645a988416SJim Ingham return bytes_len; 10655a988416SJim Ingham } 10665a988416SJim Ingham 1067de164aaaSGreg Clayton private: 1068de164aaaSGreg Clayton std::auto_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1069de164aaaSGreg Clayton 1070de164aaaSGreg Clayton class CommandOptions : public Options 1071de164aaaSGreg Clayton { 1072de164aaaSGreg Clayton public: 1073de164aaaSGreg Clayton 1074de164aaaSGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1075de164aaaSGreg Clayton Options (interpreter) 1076de164aaaSGreg Clayton { 1077de164aaaSGreg Clayton } 1078de164aaaSGreg Clayton 1079de164aaaSGreg Clayton virtual 1080de164aaaSGreg Clayton ~CommandOptions (){} 1081de164aaaSGreg Clayton 1082de164aaaSGreg Clayton virtual Error 1083de164aaaSGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 1084de164aaaSGreg Clayton { 1085de164aaaSGreg Clayton Error error; 1086de164aaaSGreg Clayton char short_option = (char) m_getopt_table[option_idx].val; 1087de164aaaSGreg Clayton 1088de164aaaSGreg Clayton switch (short_option) 1089de164aaaSGreg Clayton { 1090de164aaaSGreg Clayton case 'h': 1091de164aaaSGreg Clayton m_help.assign (option_arg); 1092de164aaaSGreg Clayton break; 1093de164aaaSGreg Clayton case 's': 1094de164aaaSGreg Clayton m_syntax.assign (option_arg); 1095de164aaaSGreg Clayton break; 1096de164aaaSGreg Clayton 1097de164aaaSGreg Clayton default: 109886edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1099de164aaaSGreg Clayton break; 1100de164aaaSGreg Clayton } 1101de164aaaSGreg Clayton 1102de164aaaSGreg Clayton return error; 1103de164aaaSGreg Clayton } 1104de164aaaSGreg Clayton 1105de164aaaSGreg Clayton void 1106de164aaaSGreg Clayton OptionParsingStarting () 1107de164aaaSGreg Clayton { 1108de164aaaSGreg Clayton m_help.clear(); 1109de164aaaSGreg Clayton m_syntax.clear(); 1110de164aaaSGreg Clayton } 1111de164aaaSGreg Clayton 1112de164aaaSGreg Clayton const OptionDefinition* 1113de164aaaSGreg Clayton GetDefinitions () 1114de164aaaSGreg Clayton { 1115de164aaaSGreg Clayton return g_option_table; 1116de164aaaSGreg Clayton } 1117de164aaaSGreg Clayton 1118de164aaaSGreg Clayton // Options table: Required for subclasses of Options. 1119de164aaaSGreg Clayton 1120de164aaaSGreg Clayton static OptionDefinition g_option_table[]; 1121de164aaaSGreg Clayton 1122de164aaaSGreg Clayton const char * 1123de164aaaSGreg Clayton GetHelp () 1124de164aaaSGreg Clayton { 1125de164aaaSGreg Clayton if (m_help.empty()) 1126de164aaaSGreg Clayton return NULL; 1127de164aaaSGreg Clayton return m_help.c_str(); 1128de164aaaSGreg Clayton } 1129de164aaaSGreg Clayton const char * 1130de164aaaSGreg Clayton GetSyntax () 1131de164aaaSGreg Clayton { 1132de164aaaSGreg Clayton if (m_syntax.empty()) 1133de164aaaSGreg Clayton return NULL; 1134de164aaaSGreg Clayton return m_syntax.c_str(); 1135de164aaaSGreg Clayton } 1136de164aaaSGreg Clayton // Instance variables to hold the values for command options. 1137de164aaaSGreg Clayton protected: 1138de164aaaSGreg Clayton std::string m_help; 1139de164aaaSGreg Clayton std::string m_syntax; 1140de164aaaSGreg Clayton }; 1141de164aaaSGreg Clayton 1142de164aaaSGreg Clayton virtual Options * 1143de164aaaSGreg Clayton GetOptions () 1144de164aaaSGreg Clayton { 1145de164aaaSGreg Clayton return &m_options; 1146de164aaaSGreg Clayton } 1147de164aaaSGreg Clayton 11485a988416SJim Ingham CommandOptions m_options; 1149de164aaaSGreg Clayton }; 1150de164aaaSGreg Clayton 1151de164aaaSGreg Clayton OptionDefinition 1152de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1153de164aaaSGreg Clayton { 1154de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1155de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1156de164aaaSGreg Clayton { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL } 1157de164aaaSGreg Clayton }; 1158de164aaaSGreg Clayton 1159de164aaaSGreg Clayton 11605a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw 1161223383edSEnrico Granata { 1162223383edSEnrico Granata private: 1163223383edSEnrico Granata std::string m_function_name; 11640a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchro; 1165*fac939e9SEnrico Granata bool m_fetched_help_long; 1166223383edSEnrico Granata 1167223383edSEnrico Granata public: 1168223383edSEnrico Granata 1169223383edSEnrico Granata CommandObjectPythonFunction (CommandInterpreter &interpreter, 1170223383edSEnrico Granata std::string name, 11710a305db7SEnrico Granata std::string funct, 11720a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 11735a988416SJim Ingham CommandObjectRaw (interpreter, 1174223383edSEnrico Granata name.c_str(), 1175223383edSEnrico Granata (std::string("Run Python function ") + funct).c_str(), 1176223383edSEnrico Granata NULL), 11770a305db7SEnrico Granata m_function_name(funct), 1178*fac939e9SEnrico Granata m_synchro(synch), 1179*fac939e9SEnrico Granata m_fetched_help_long(false) 1180223383edSEnrico Granata { 1181223383edSEnrico Granata } 1182223383edSEnrico Granata 1183223383edSEnrico Granata virtual 1184223383edSEnrico Granata ~CommandObjectPythonFunction () 1185223383edSEnrico Granata { 1186223383edSEnrico Granata } 1187223383edSEnrico Granata 1188223383edSEnrico Granata virtual bool 11895a988416SJim Ingham IsRemovable () 11905a988416SJim Ingham { 11915a988416SJim Ingham return true; 11925a988416SJim Ingham } 11935a988416SJim Ingham 11945a988416SJim Ingham const std::string& 11955a988416SJim Ingham GetFunctionName () 11965a988416SJim Ingham { 11975a988416SJim Ingham return m_function_name; 11985a988416SJim Ingham } 11995a988416SJim Ingham 12005a988416SJim Ingham ScriptedCommandSynchronicity 12015a988416SJim Ingham GetSynchronicity () 12025a988416SJim Ingham { 12035a988416SJim Ingham return m_synchro; 12045a988416SJim Ingham } 12055a988416SJim Ingham 1206*fac939e9SEnrico Granata virtual const char * 1207*fac939e9SEnrico Granata GetHelpLong () 1208*fac939e9SEnrico Granata { 1209*fac939e9SEnrico Granata if (!m_fetched_help_long) 1210*fac939e9SEnrico Granata { 1211*fac939e9SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1212*fac939e9SEnrico Granata if (scripter) 1213*fac939e9SEnrico Granata { 1214*fac939e9SEnrico Granata std::string docstring; 1215*fac939e9SEnrico Granata m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1216*fac939e9SEnrico Granata if (!docstring.empty()) 1217*fac939e9SEnrico Granata SetHelpLong(docstring); 1218*fac939e9SEnrico Granata } 1219*fac939e9SEnrico Granata } 1220*fac939e9SEnrico Granata return CommandObjectRaw::GetHelpLong(); 1221*fac939e9SEnrico Granata } 1222*fac939e9SEnrico Granata 12235a988416SJim Ingham protected: 12245a988416SJim Ingham virtual bool 12255a988416SJim Ingham DoExecute (const char *raw_command_line, CommandReturnObject &result) 1226223383edSEnrico Granata { 1227223383edSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1228223383edSEnrico Granata 1229223383edSEnrico Granata Error error; 1230223383edSEnrico Granata 123170f11f88SJim Ingham result.SetStatus(eReturnStatusInvalid); 123270f11f88SJim Ingham 1233223383edSEnrico Granata if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1234223383edSEnrico Granata raw_command_line, 12350a305db7SEnrico Granata m_synchro, 1236223383edSEnrico Granata result, 1237223383edSEnrico Granata error) == false) 1238223383edSEnrico Granata { 1239223383edSEnrico Granata result.AppendError(error.AsCString()); 1240223383edSEnrico Granata result.SetStatus(eReturnStatusFailed); 1241223383edSEnrico Granata } 1242223383edSEnrico Granata else 124370f11f88SJim Ingham { 124470f11f88SJim Ingham // Don't change the status if the command already set it... 124570f11f88SJim Ingham if (result.GetStatus() == eReturnStatusInvalid) 124670f11f88SJim Ingham { 124770f11f88SJim Ingham if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1248223383edSEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 124970f11f88SJim Ingham else 125070f11f88SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 125170f11f88SJim Ingham } 125270f11f88SJim Ingham } 1253223383edSEnrico Granata 1254223383edSEnrico Granata return result.Succeeded(); 1255223383edSEnrico Granata } 1256223383edSEnrico Granata 1257223383edSEnrico Granata }; 1258223383edSEnrico Granata 1259a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1260a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport 1261a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1262a9dbf432SEnrico Granata 12635a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed 1264a9dbf432SEnrico Granata { 12655a988416SJim Ingham public: 12665a988416SJim Ingham CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 12675a988416SJim Ingham CommandObjectParsed (interpreter, 12685a988416SJim Ingham "command script import", 12695a988416SJim Ingham "Import a scripting module in LLDB.", 12705a988416SJim Ingham NULL), 12715a988416SJim Ingham m_options(interpreter) 12725a988416SJim Ingham { 12735a988416SJim Ingham CommandArgumentEntry arg1; 12745a988416SJim Ingham CommandArgumentData cmd_arg; 12755a988416SJim Ingham 12765a988416SJim Ingham // Define the first (and only) variant of this arg. 12775a988416SJim Ingham cmd_arg.arg_type = eArgTypeFilename; 12785a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 12795a988416SJim Ingham 12805a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 12815a988416SJim Ingham arg1.push_back (cmd_arg); 12825a988416SJim Ingham 12835a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 12845a988416SJim Ingham m_arguments.push_back (arg1); 12855a988416SJim Ingham } 12865a988416SJim Ingham 12875a988416SJim Ingham ~CommandObjectCommandsScriptImport () 12885a988416SJim Ingham { 12895a988416SJim Ingham } 12905a988416SJim Ingham 12915a988416SJim Ingham int 12925a988416SJim Ingham HandleArgumentCompletion (Args &input, 12935a988416SJim Ingham int &cursor_index, 12945a988416SJim Ingham int &cursor_char_position, 12955a988416SJim Ingham OptionElementVector &opt_element_vector, 12965a988416SJim Ingham int match_start_point, 12975a988416SJim Ingham int max_return_elements, 12985a988416SJim Ingham bool &word_complete, 12995a988416SJim Ingham StringList &matches) 13005a988416SJim Ingham { 13015a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 13025a988416SJim Ingham completion_str.erase (cursor_char_position); 13035a988416SJim Ingham 13045a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 13055a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 13065a988416SJim Ingham completion_str.c_str(), 13075a988416SJim Ingham match_start_point, 13085a988416SJim Ingham max_return_elements, 13095a988416SJim Ingham NULL, 13105a988416SJim Ingham word_complete, 13115a988416SJim Ingham matches); 13125a988416SJim Ingham return matches.GetSize(); 13135a988416SJim Ingham } 13145a988416SJim Ingham 13155a988416SJim Ingham virtual Options * 13165a988416SJim Ingham GetOptions () 13175a988416SJim Ingham { 13185a988416SJim Ingham return &m_options; 13195a988416SJim Ingham } 13205a988416SJim Ingham 13215a988416SJim Ingham protected: 13220a305db7SEnrico Granata 13230a305db7SEnrico Granata class CommandOptions : public Options 13240a305db7SEnrico Granata { 13250a305db7SEnrico Granata public: 13260a305db7SEnrico Granata 13270a305db7SEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 13280a305db7SEnrico Granata Options (interpreter) 13290a305db7SEnrico Granata { 13300a305db7SEnrico Granata } 13310a305db7SEnrico Granata 13320a305db7SEnrico Granata virtual 13330a305db7SEnrico Granata ~CommandOptions (){} 13340a305db7SEnrico Granata 13350a305db7SEnrico Granata virtual Error 13360a305db7SEnrico Granata SetOptionValue (uint32_t option_idx, const char *option_arg) 13370a305db7SEnrico Granata { 13380a305db7SEnrico Granata Error error; 13390a305db7SEnrico Granata char short_option = (char) m_getopt_table[option_idx].val; 13400a305db7SEnrico Granata 13410a305db7SEnrico Granata switch (short_option) 13420a305db7SEnrico Granata { 13430a305db7SEnrico Granata case 'r': 13440a305db7SEnrico Granata m_allow_reload = true; 13450a305db7SEnrico Granata break; 13460a305db7SEnrico Granata default: 13470a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 13480a305db7SEnrico Granata break; 13490a305db7SEnrico Granata } 13500a305db7SEnrico Granata 13510a305db7SEnrico Granata return error; 13520a305db7SEnrico Granata } 13530a305db7SEnrico Granata 13540a305db7SEnrico Granata void 13550a305db7SEnrico Granata OptionParsingStarting () 13560a305db7SEnrico Granata { 13570a305db7SEnrico Granata m_allow_reload = false; 13580a305db7SEnrico Granata } 13590a305db7SEnrico Granata 13600a305db7SEnrico Granata const OptionDefinition* 13610a305db7SEnrico Granata GetDefinitions () 13620a305db7SEnrico Granata { 13630a305db7SEnrico Granata return g_option_table; 13640a305db7SEnrico Granata } 13650a305db7SEnrico Granata 13660a305db7SEnrico Granata // Options table: Required for subclasses of Options. 13670a305db7SEnrico Granata 13680a305db7SEnrico Granata static OptionDefinition g_option_table[]; 13690a305db7SEnrico Granata 13700a305db7SEnrico Granata // Instance variables to hold the values for command options. 13710a305db7SEnrico Granata 13720a305db7SEnrico Granata bool m_allow_reload; 13730a305db7SEnrico Granata }; 13740a305db7SEnrico Granata 1375a9dbf432SEnrico Granata bool 13765a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1377a9dbf432SEnrico Granata { 1378a9dbf432SEnrico Granata 1379a9dbf432SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1380a9dbf432SEnrico Granata { 1381a9dbf432SEnrico Granata result.AppendError ("only scripting language supported for module importing is currently Python"); 1382a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1383a9dbf432SEnrico Granata return false; 1384a9dbf432SEnrico Granata } 1385a9dbf432SEnrico Granata 13865a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1387a9dbf432SEnrico Granata 1388a9dbf432SEnrico Granata if (argc != 1) 1389a9dbf432SEnrico Granata { 1390a9dbf432SEnrico Granata result.AppendError ("'command script import' requires one argument"); 1391a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1392a9dbf432SEnrico Granata return false; 1393a9dbf432SEnrico Granata } 1394a9dbf432SEnrico Granata 13955a988416SJim Ingham std::string path = command.GetArgumentAtIndex(0); 1396a9dbf432SEnrico Granata Error error; 1397a9dbf432SEnrico Granata 1398a9dbf432SEnrico Granata if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 13990a305db7SEnrico Granata m_options.m_allow_reload, 1400a9dbf432SEnrico Granata error)) 1401a9dbf432SEnrico Granata { 1402a9dbf432SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1403a9dbf432SEnrico Granata } 1404a9dbf432SEnrico Granata else 1405a9dbf432SEnrico Granata { 1406a9dbf432SEnrico Granata result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1407a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1408a9dbf432SEnrico Granata } 1409a9dbf432SEnrico Granata 1410a9dbf432SEnrico Granata return result.Succeeded(); 1411a9dbf432SEnrico Granata } 14120a305db7SEnrico Granata 14135a988416SJim Ingham CommandOptions m_options; 1414a9dbf432SEnrico Granata }; 1415223383edSEnrico Granata 14160a305db7SEnrico Granata OptionDefinition 14170a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 14180a305db7SEnrico Granata { 14190a305db7SEnrico Granata { LLDB_OPT_SET_1, false, "allow-reload", 'r', no_argument, NULL, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before (for Python, the __lldb_init_module function will be called again, but the module will not be reloaded from disk)."}, 14200a305db7SEnrico Granata { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 14210a305db7SEnrico Granata }; 14220a305db7SEnrico Granata 14230a305db7SEnrico Granata 1424223383edSEnrico Granata //------------------------------------------------------------------------- 1425223383edSEnrico Granata // CommandObjectCommandsScriptAdd 1426223383edSEnrico Granata //------------------------------------------------------------------------- 1427223383edSEnrico Granata 14285a988416SJim Ingham class CommandObjectCommandsScriptAdd : public CommandObjectParsed 1429223383edSEnrico Granata { 14305a988416SJim Ingham public: 14315a988416SJim Ingham CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 14325a988416SJim Ingham CommandObjectParsed (interpreter, 14335a988416SJim Ingham "command script add", 14345a988416SJim Ingham "Add a scripted function as an LLDB command.", 14355a988416SJim Ingham NULL), 14365a988416SJim Ingham m_options (interpreter) 14375a988416SJim Ingham { 14385a988416SJim Ingham CommandArgumentEntry arg1; 14395a988416SJim Ingham CommandArgumentData cmd_arg; 14405a988416SJim Ingham 14415a988416SJim Ingham // Define the first (and only) variant of this arg. 14425a988416SJim Ingham cmd_arg.arg_type = eArgTypeCommandName; 14435a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 14445a988416SJim Ingham 14455a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 14465a988416SJim Ingham arg1.push_back (cmd_arg); 14475a988416SJim Ingham 14485a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 14495a988416SJim Ingham m_arguments.push_back (arg1); 14505a988416SJim Ingham } 14515a988416SJim Ingham 14525a988416SJim Ingham ~CommandObjectCommandsScriptAdd () 14535a988416SJim Ingham { 14545a988416SJim Ingham } 14555a988416SJim Ingham 14565a988416SJim Ingham virtual Options * 14575a988416SJim Ingham GetOptions () 14585a988416SJim Ingham { 14595a988416SJim Ingham return &m_options; 14605a988416SJim Ingham } 14615a988416SJim Ingham 14625a988416SJim Ingham protected: 1463223383edSEnrico Granata 1464223383edSEnrico Granata class CommandOptions : public Options 1465223383edSEnrico Granata { 1466223383edSEnrico Granata public: 1467223383edSEnrico Granata 1468223383edSEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 1469223383edSEnrico Granata Options (interpreter) 1470223383edSEnrico Granata { 1471223383edSEnrico Granata } 1472223383edSEnrico Granata 1473223383edSEnrico Granata virtual 1474223383edSEnrico Granata ~CommandOptions (){} 1475223383edSEnrico Granata 1476223383edSEnrico Granata virtual Error 1477223383edSEnrico Granata SetOptionValue (uint32_t option_idx, const char *option_arg) 1478223383edSEnrico Granata { 1479223383edSEnrico Granata Error error; 1480223383edSEnrico Granata char short_option = (char) m_getopt_table[option_idx].val; 1481223383edSEnrico Granata 1482223383edSEnrico Granata switch (short_option) 1483223383edSEnrico Granata { 1484223383edSEnrico Granata case 'f': 1485223383edSEnrico Granata m_funct_name = std::string(option_arg); 1486223383edSEnrico Granata break; 14870a305db7SEnrico Granata case 's': 14880a305db7SEnrico Granata m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 14890a305db7SEnrico Granata if (!error.Success()) 14900a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 14910a305db7SEnrico Granata break; 1492223383edSEnrico Granata default: 149386edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1494223383edSEnrico Granata break; 1495223383edSEnrico Granata } 1496223383edSEnrico Granata 1497223383edSEnrico Granata return error; 1498223383edSEnrico Granata } 1499223383edSEnrico Granata 1500223383edSEnrico Granata void 1501223383edSEnrico Granata OptionParsingStarting () 1502223383edSEnrico Granata { 1503223383edSEnrico Granata m_funct_name = ""; 15040a305db7SEnrico Granata m_synchronous = eScriptedCommandSynchronicitySynchronous; 1505223383edSEnrico Granata } 1506223383edSEnrico Granata 1507223383edSEnrico Granata const OptionDefinition* 1508223383edSEnrico Granata GetDefinitions () 1509223383edSEnrico Granata { 1510223383edSEnrico Granata return g_option_table; 1511223383edSEnrico Granata } 1512223383edSEnrico Granata 1513223383edSEnrico Granata // Options table: Required for subclasses of Options. 1514223383edSEnrico Granata 1515223383edSEnrico Granata static OptionDefinition g_option_table[]; 1516223383edSEnrico Granata 1517223383edSEnrico Granata // Instance variables to hold the values for command options. 1518223383edSEnrico Granata 1519223383edSEnrico Granata std::string m_funct_name; 15200a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchronous; 1521223383edSEnrico Granata }; 1522223383edSEnrico Granata 15235a988416SJim Ingham private: 1524223383edSEnrico Granata class PythonAliasReader : public InputReaderEZ 1525223383edSEnrico Granata { 1526223383edSEnrico Granata private: 1527223383edSEnrico Granata CommandInterpreter& m_interpreter; 1528223383edSEnrico Granata std::string m_cmd_name; 15290a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchronous; 1530223383edSEnrico Granata StringList m_user_input; 1531223383edSEnrico Granata DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); 1532223383edSEnrico Granata public: 1533223383edSEnrico Granata PythonAliasReader(Debugger& debugger, 1534223383edSEnrico Granata CommandInterpreter& interpreter, 15350a305db7SEnrico Granata std::string cmd_name, 15360a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 1537223383edSEnrico Granata InputReaderEZ(debugger), 1538223383edSEnrico Granata m_interpreter(interpreter), 1539223383edSEnrico Granata m_cmd_name(cmd_name), 15400a305db7SEnrico Granata m_synchronous(synch), 1541223383edSEnrico Granata m_user_input() 1542223383edSEnrico Granata {} 1543223383edSEnrico Granata 1544223383edSEnrico Granata virtual 1545223383edSEnrico Granata ~PythonAliasReader() 1546223383edSEnrico Granata { 1547223383edSEnrico Granata } 1548223383edSEnrico Granata 1549223383edSEnrico Granata virtual void ActivateHandler(HandlerData& data) 1550223383edSEnrico Granata { 1551223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1552223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1553223383edSEnrico Granata if (!batch_mode) 1554223383edSEnrico Granata { 1555223383edSEnrico Granata out_stream->Printf ("%s\n", g_python_command_instructions); 1556223383edSEnrico Granata if (data.reader.GetPrompt()) 1557223383edSEnrico Granata out_stream->Printf ("%s", data.reader.GetPrompt()); 1558223383edSEnrico Granata out_stream->Flush(); 1559223383edSEnrico Granata } 1560223383edSEnrico Granata } 1561223383edSEnrico Granata 1562223383edSEnrico Granata virtual void ReactivateHandler(HandlerData& data) 1563223383edSEnrico Granata { 1564223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1565223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1566223383edSEnrico Granata if (data.reader.GetPrompt() && !batch_mode) 1567223383edSEnrico Granata { 1568223383edSEnrico Granata out_stream->Printf ("%s", data.reader.GetPrompt()); 1569223383edSEnrico Granata out_stream->Flush(); 1570223383edSEnrico Granata } 1571223383edSEnrico Granata } 1572223383edSEnrico Granata virtual void GotTokenHandler(HandlerData& data) 1573223383edSEnrico Granata { 1574223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1575223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1576223383edSEnrico Granata if (data.bytes && data.bytes_len) 1577223383edSEnrico Granata { 1578223383edSEnrico Granata m_user_input.AppendString(data.bytes, data.bytes_len); 1579223383edSEnrico Granata } 1580223383edSEnrico Granata if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 1581223383edSEnrico Granata { 1582223383edSEnrico Granata out_stream->Printf ("%s", data.reader.GetPrompt()); 1583223383edSEnrico Granata out_stream->Flush(); 1584223383edSEnrico Granata } 1585223383edSEnrico Granata } 1586223383edSEnrico Granata virtual void InterruptHandler(HandlerData& data) 1587223383edSEnrico Granata { 1588223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1589223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1590223383edSEnrico Granata data.reader.SetIsDone (true); 1591223383edSEnrico Granata if (!batch_mode) 1592223383edSEnrico Granata { 15930a305db7SEnrico Granata out_stream->Printf ("Warning: No script attached.\n"); 1594223383edSEnrico Granata out_stream->Flush(); 1595223383edSEnrico Granata } 1596223383edSEnrico Granata } 1597223383edSEnrico Granata virtual void EOFHandler(HandlerData& data) 1598223383edSEnrico Granata { 1599223383edSEnrico Granata data.reader.SetIsDone (true); 1600223383edSEnrico Granata } 1601223383edSEnrico Granata virtual void DoneHandler(HandlerData& data) 1602223383edSEnrico Granata { 1603223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1604223383edSEnrico Granata 1605223383edSEnrico Granata ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1606223383edSEnrico Granata if (!interpreter) 1607223383edSEnrico Granata { 16080a305db7SEnrico Granata out_stream->Printf ("Script interpreter missing: no script attached.\n"); 1609223383edSEnrico Granata out_stream->Flush(); 1610223383edSEnrico Granata return; 1611223383edSEnrico Granata } 1612a73b7df7SEnrico Granata std::string funct_name_str; 1613223383edSEnrico Granata if (!interpreter->GenerateScriptAliasFunction (m_user_input, 1614a73b7df7SEnrico Granata funct_name_str)) 1615223383edSEnrico Granata { 16160a305db7SEnrico Granata out_stream->Printf ("Unable to create function: no script attached.\n"); 1617223383edSEnrico Granata out_stream->Flush(); 1618223383edSEnrico Granata return; 1619223383edSEnrico Granata } 1620a73b7df7SEnrico Granata if (funct_name_str.empty()) 1621223383edSEnrico Granata { 16220a305db7SEnrico Granata out_stream->Printf ("Unable to obtain a function name: no script attached.\n"); 1623223383edSEnrico Granata out_stream->Flush(); 1624223383edSEnrico Granata return; 1625223383edSEnrico Granata } 1626223383edSEnrico Granata // everything should be fine now, let's add this alias 1627223383edSEnrico Granata 1628223383edSEnrico Granata CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, 1629223383edSEnrico Granata m_cmd_name, 1630a73b7df7SEnrico Granata funct_name_str.c_str(), 16310a305db7SEnrico Granata m_synchronous)); 1632223383edSEnrico Granata 16330a305db7SEnrico Granata if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1634223383edSEnrico Granata { 16350a305db7SEnrico Granata out_stream->Printf ("Unable to add selected command: no script attached.\n"); 1636223383edSEnrico Granata out_stream->Flush(); 1637223383edSEnrico Granata return; 1638223383edSEnrico Granata } 1639223383edSEnrico Granata } 1640223383edSEnrico Granata }; 1641223383edSEnrico Granata 16425a988416SJim Ingham protected: 1643223383edSEnrico Granata bool 16445a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1645223383edSEnrico Granata { 164699f0b8f9SEnrico Granata 164799f0b8f9SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 164899f0b8f9SEnrico Granata { 164999f0b8f9SEnrico Granata result.AppendError ("only scripting language supported for scripted commands is currently Python"); 165099f0b8f9SEnrico Granata result.SetStatus (eReturnStatusFailed); 165199f0b8f9SEnrico Granata return false; 165299f0b8f9SEnrico Granata } 165399f0b8f9SEnrico Granata 16545a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1655223383edSEnrico Granata 1656223383edSEnrico Granata if (argc != 1) 1657223383edSEnrico Granata { 1658223383edSEnrico Granata result.AppendError ("'command script add' requires one argument"); 1659223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1660223383edSEnrico Granata return false; 1661223383edSEnrico Granata } 1662223383edSEnrico Granata 16635a988416SJim Ingham std::string cmd_name = command.GetArgumentAtIndex(0); 1664223383edSEnrico Granata 1665223383edSEnrico Granata if (m_options.m_funct_name.empty()) 1666223383edSEnrico Granata { 1667223383edSEnrico Granata InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), 1668223383edSEnrico Granata m_interpreter, 16690a305db7SEnrico Granata cmd_name, 16700a305db7SEnrico Granata m_options.m_synchronous)); 1671223383edSEnrico Granata 1672223383edSEnrico Granata if (reader_sp) 1673223383edSEnrico Granata { 1674223383edSEnrico Granata 1675223383edSEnrico Granata InputReaderEZ::InitializationParameters ipr; 1676223383edSEnrico Granata 1677223383edSEnrico Granata Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); 1678223383edSEnrico Granata if (err.Success()) 1679223383edSEnrico Granata { 1680223383edSEnrico Granata m_interpreter.GetDebugger().PushInputReader (reader_sp); 1681223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1682223383edSEnrico Granata } 1683223383edSEnrico Granata else 1684223383edSEnrico Granata { 1685223383edSEnrico Granata result.AppendError (err.AsCString()); 1686223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1687223383edSEnrico Granata } 1688223383edSEnrico Granata } 1689223383edSEnrico Granata else 1690223383edSEnrico Granata { 1691223383edSEnrico Granata result.AppendError("out of memory"); 1692223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1693223383edSEnrico Granata } 1694223383edSEnrico Granata } 1695223383edSEnrico Granata else 1696223383edSEnrico Granata { 16970a305db7SEnrico Granata CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 16980a305db7SEnrico Granata cmd_name, 16990a305db7SEnrico Granata m_options.m_funct_name, 17000a305db7SEnrico Granata m_options.m_synchronous)); 17010a305db7SEnrico Granata if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true)) 1702223383edSEnrico Granata { 1703223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1704223383edSEnrico Granata } 1705223383edSEnrico Granata else 1706223383edSEnrico Granata { 1707223383edSEnrico Granata result.AppendError("cannot add command"); 1708223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1709223383edSEnrico Granata } 1710223383edSEnrico Granata } 1711223383edSEnrico Granata 1712223383edSEnrico Granata return result.Succeeded(); 1713223383edSEnrico Granata 1714223383edSEnrico Granata } 17155a988416SJim Ingham 17165a988416SJim Ingham CommandOptions m_options; 1717223383edSEnrico Granata }; 1718223383edSEnrico Granata 17190a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] = 17200a305db7SEnrico Granata { 17210a305db7SEnrico Granata { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 17220a305db7SEnrico Granata { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 17230a305db7SEnrico Granata { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 17240a305db7SEnrico Granata { 0, NULL, NULL } 17250a305db7SEnrico Granata }; 17260a305db7SEnrico Granata 1727223383edSEnrico Granata OptionDefinition 1728223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1729223383edSEnrico Granata { 17309128ee2fSEnrico Granata { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 17310a305db7SEnrico Granata { LLDB_OPT_SET_1, false, "synchronicity", 's', required_argument, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system."}, 1732223383edSEnrico Granata { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1733223383edSEnrico Granata }; 1734223383edSEnrico Granata 1735223383edSEnrico Granata //------------------------------------------------------------------------- 1736223383edSEnrico Granata // CommandObjectCommandsScriptList 1737223383edSEnrico Granata //------------------------------------------------------------------------- 1738223383edSEnrico Granata 17395a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed 1740223383edSEnrico Granata { 1741223383edSEnrico Granata private: 1742223383edSEnrico Granata 1743223383edSEnrico Granata public: 1744223383edSEnrico Granata CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 17455a988416SJim Ingham CommandObjectParsed (interpreter, 1746223383edSEnrico Granata "command script list", 1747223383edSEnrico Granata "List defined scripted commands.", 1748223383edSEnrico Granata NULL) 1749223383edSEnrico Granata { 1750223383edSEnrico Granata } 1751223383edSEnrico Granata 1752223383edSEnrico Granata ~CommandObjectCommandsScriptList () 1753223383edSEnrico Granata { 1754223383edSEnrico Granata } 1755223383edSEnrico Granata 1756223383edSEnrico Granata bool 17575a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1758223383edSEnrico Granata { 1759223383edSEnrico Granata 1760223383edSEnrico Granata m_interpreter.GetHelp(result, 1761223383edSEnrico Granata CommandInterpreter::eCommandTypesUserDef); 1762223383edSEnrico Granata 1763223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 1764223383edSEnrico Granata 1765223383edSEnrico Granata return true; 1766223383edSEnrico Granata 1767223383edSEnrico Granata 1768223383edSEnrico Granata } 1769223383edSEnrico Granata }; 1770223383edSEnrico Granata 1771223383edSEnrico Granata //------------------------------------------------------------------------- 1772223383edSEnrico Granata // CommandObjectCommandsScriptClear 1773223383edSEnrico Granata //------------------------------------------------------------------------- 1774223383edSEnrico Granata 17755a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed 1776223383edSEnrico Granata { 1777223383edSEnrico Granata private: 1778223383edSEnrico Granata 1779223383edSEnrico Granata public: 1780223383edSEnrico Granata CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 17815a988416SJim Ingham CommandObjectParsed (interpreter, 1782223383edSEnrico Granata "command script clear", 1783223383edSEnrico Granata "Delete all scripted commands.", 1784223383edSEnrico Granata NULL) 1785223383edSEnrico Granata { 1786223383edSEnrico Granata } 1787223383edSEnrico Granata 1788223383edSEnrico Granata ~CommandObjectCommandsScriptClear () 1789223383edSEnrico Granata { 1790223383edSEnrico Granata } 1791223383edSEnrico Granata 17925a988416SJim Ingham protected: 1793223383edSEnrico Granata bool 17945a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1795223383edSEnrico Granata { 1796223383edSEnrico Granata 1797223383edSEnrico Granata m_interpreter.RemoveAllUser(); 1798223383edSEnrico Granata 1799223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 1800223383edSEnrico Granata 1801223383edSEnrico Granata return true; 1802223383edSEnrico Granata } 1803223383edSEnrico Granata }; 1804223383edSEnrico Granata 1805223383edSEnrico Granata //------------------------------------------------------------------------- 1806223383edSEnrico Granata // CommandObjectCommandsScriptDelete 1807223383edSEnrico Granata //------------------------------------------------------------------------- 1808223383edSEnrico Granata 18095a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed 1810223383edSEnrico Granata { 1811223383edSEnrico Granata public: 1812223383edSEnrico Granata CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 18135a988416SJim Ingham CommandObjectParsed (interpreter, 1814223383edSEnrico Granata "command script delete", 1815223383edSEnrico Granata "Delete a scripted command.", 1816223383edSEnrico Granata NULL) 1817223383edSEnrico Granata { 1818223383edSEnrico Granata CommandArgumentEntry arg1; 1819223383edSEnrico Granata CommandArgumentData cmd_arg; 1820223383edSEnrico Granata 1821223383edSEnrico Granata // Define the first (and only) variant of this arg. 1822223383edSEnrico Granata cmd_arg.arg_type = eArgTypeCommandName; 1823223383edSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlain; 1824223383edSEnrico Granata 1825223383edSEnrico Granata // There is only one variant this argument could be; put it into the argument entry. 1826223383edSEnrico Granata arg1.push_back (cmd_arg); 1827223383edSEnrico Granata 1828223383edSEnrico Granata // Push the data for the first argument into the m_arguments vector. 1829223383edSEnrico Granata m_arguments.push_back (arg1); 1830223383edSEnrico Granata } 1831223383edSEnrico Granata 1832223383edSEnrico Granata ~CommandObjectCommandsScriptDelete () 1833223383edSEnrico Granata { 1834223383edSEnrico Granata } 1835223383edSEnrico Granata 18365a988416SJim Ingham protected: 1837223383edSEnrico Granata bool 18385a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1839223383edSEnrico Granata { 1840223383edSEnrico Granata 18415a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1842223383edSEnrico Granata 1843223383edSEnrico Granata if (argc != 1) 1844223383edSEnrico Granata { 1845223383edSEnrico Granata result.AppendError ("'command script delete' requires one argument"); 1846223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1847223383edSEnrico Granata return false; 1848223383edSEnrico Granata } 1849223383edSEnrico Granata 18505a988416SJim Ingham const char* cmd_name = command.GetArgumentAtIndex(0); 1851223383edSEnrico Granata 1852223383edSEnrico Granata if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1853223383edSEnrico Granata { 1854223383edSEnrico Granata m_interpreter.RemoveUser(cmd_name); 1855223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 1856223383edSEnrico Granata } 1857223383edSEnrico Granata else 1858223383edSEnrico Granata { 1859223383edSEnrico Granata result.AppendErrorWithFormat ("command %s not found", cmd_name); 1860223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1861223383edSEnrico Granata } 1862223383edSEnrico Granata 1863223383edSEnrico Granata return result.Succeeded(); 1864223383edSEnrico Granata 1865223383edSEnrico Granata } 1866223383edSEnrico Granata }; 1867223383edSEnrico Granata 1868223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript 1869223383edSEnrico Granata 1870223383edSEnrico Granata //------------------------------------------------------------------------- 1871223383edSEnrico Granata // CommandObjectMultiwordCommandsScript 1872223383edSEnrico Granata //------------------------------------------------------------------------- 1873223383edSEnrico Granata 1874223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1875223383edSEnrico Granata { 1876223383edSEnrico Granata public: 1877223383edSEnrico Granata CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1878223383edSEnrico Granata CommandObjectMultiword (interpreter, 1879223383edSEnrico Granata "command script", 1880223383edSEnrico Granata "A set of commands for managing or customizing script commands.", 1881223383edSEnrico Granata "command script <subcommand> [<subcommand-options>]") 1882223383edSEnrico Granata { 1883223383edSEnrico Granata LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1884223383edSEnrico Granata LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1885223383edSEnrico Granata LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1886223383edSEnrico Granata LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1887a9dbf432SEnrico Granata LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1888223383edSEnrico Granata } 1889223383edSEnrico Granata 1890223383edSEnrico Granata ~CommandObjectMultiwordCommandsScript () 1891223383edSEnrico Granata { 1892223383edSEnrico Granata } 1893223383edSEnrico Granata 1894223383edSEnrico Granata }; 1895223383edSEnrico Granata 1896223383edSEnrico Granata 1897ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands 1898ebc09c36SJim Ingham 1899ebc09c36SJim Ingham //------------------------------------------------------------------------- 1900ebc09c36SJim Ingham // CommandObjectMultiwordCommands 1901ebc09c36SJim Ingham //------------------------------------------------------------------------- 1902ebc09c36SJim Ingham 1903ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1904a7015092SGreg Clayton CommandObjectMultiword (interpreter, 19050e5e5a79SGreg Clayton "command", 19063f4c09c1SCaroline Tice "A set of commands for managing or customizing the debugger commands.", 19070e5e5a79SGreg Clayton "command <subcommand> [<subcommand-options>]") 1908ebc09c36SJim Ingham { 1909a7015092SGreg Clayton LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 1910a7015092SGreg Clayton LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 1911a7015092SGreg Clayton LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 1912de164aaaSGreg Clayton LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 1913a5a97ebeSJim Ingham LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 1914223383edSEnrico Granata LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 1915ebc09c36SJim Ingham } 1916ebc09c36SJim Ingham 1917ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 1918ebc09c36SJim Ingham { 1919ebc09c36SJim Ingham } 1920ebc09c36SJim Ingham 1921