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 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 12ebc09c36SJim Ingham #include "CommandObjectCommands.h" 13ebc09c36SJim Ingham 14ebc09c36SJim Ingham // C Includes 15ebc09c36SJim Ingham // C++ Includes 16ebc09c36SJim Ingham // Other libraries and framework includes 170e5e5a79SGreg Clayton #include "llvm/ADT/StringRef.h" 180e5e5a79SGreg Clayton 19ebc09c36SJim Ingham // Project includes 20ebc09c36SJim Ingham #include "lldb/Core/Debugger.h" 21de164aaaSGreg Clayton #include "lldb/Core/InputReader.h" 22be93a35aSEnrico Granata #include "lldb/Core/InputReaderEZ.h" 23be93a35aSEnrico Granata #include "lldb/Core/StringList.h" 24de164aaaSGreg Clayton #include "lldb/Interpreter/Args.h" 25ebc09c36SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h" 26de164aaaSGreg Clayton #include "lldb/Interpreter/CommandObjectRegexCommand.h" 27ebc09c36SJim Ingham #include "lldb/Interpreter/CommandReturnObject.h" 28*012d4fcaSEnrico Granata #include "lldb/Interpreter/OptionValueBoolean.h" 29ebc09c36SJim Ingham #include "lldb/Interpreter/Options.h" 3099f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreter.h" 3199f0b8f9SEnrico Granata #include "lldb/Interpreter/ScriptInterpreterPython.h" 32ebc09c36SJim Ingham 33ebc09c36SJim Ingham using namespace lldb; 34ebc09c36SJim Ingham using namespace lldb_private; 35ebc09c36SJim Ingham 36ebc09c36SJim Ingham //------------------------------------------------------------------------- 37ebc09c36SJim Ingham // CommandObjectCommandsSource 38ebc09c36SJim Ingham //------------------------------------------------------------------------- 39ebc09c36SJim Ingham 405a988416SJim Ingham class CommandObjectCommandsHistory : public CommandObjectParsed 41a5a97ebeSJim Ingham { 425a988416SJim Ingham public: 435a988416SJim Ingham CommandObjectCommandsHistory(CommandInterpreter &interpreter) : 445a988416SJim Ingham CommandObjectParsed (interpreter, 455a988416SJim Ingham "command history", 465a988416SJim Ingham "Dump the history of commands in this session.", 475a988416SJim Ingham NULL), 485a988416SJim Ingham m_options (interpreter) 495a988416SJim Ingham { 505a988416SJim Ingham } 515a988416SJim Ingham 525a988416SJim Ingham ~CommandObjectCommandsHistory () {} 535a988416SJim Ingham 545a988416SJim Ingham virtual Options * 555a988416SJim Ingham GetOptions () 565a988416SJim Ingham { 575a988416SJim Ingham return &m_options; 585a988416SJim Ingham } 595a988416SJim Ingham 605a988416SJim Ingham protected: 61a5a97ebeSJim Ingham 62a5a97ebeSJim Ingham class CommandOptions : public Options 63a5a97ebeSJim Ingham { 64a5a97ebeSJim Ingham public: 65a5a97ebeSJim Ingham 66a5a97ebeSJim Ingham CommandOptions (CommandInterpreter &interpreter) : 67a5a97ebeSJim Ingham Options (interpreter) 68a5a97ebeSJim Ingham { 69a5a97ebeSJim Ingham } 70a5a97ebeSJim Ingham 71a5a97ebeSJim Ingham virtual 72a5a97ebeSJim Ingham ~CommandOptions (){} 73a5a97ebeSJim Ingham 74a5a97ebeSJim Ingham virtual Error 75a5a97ebeSJim Ingham SetOptionValue (uint32_t option_idx, const char *option_arg) 76a5a97ebeSJim Ingham { 77a5a97ebeSJim Ingham Error error; 783bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 79a5a97ebeSJim Ingham bool success; 80a5a97ebeSJim Ingham 81a5a97ebeSJim Ingham switch (short_option) 82a5a97ebeSJim Ingham { 83a5a97ebeSJim Ingham case 'c': 84a5a97ebeSJim Ingham m_end_idx = Args::StringToUInt32(option_arg, UINT_MAX, 0, &success); 85a5a97ebeSJim Ingham if (!success) 8686edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for count: %s", option_arg); 87a5a97ebeSJim Ingham if (m_end_idx != 0) 88a5a97ebeSJim Ingham m_end_idx--; 89a5a97ebeSJim Ingham m_start_idx = 0; 90a5a97ebeSJim Ingham break; 91a5a97ebeSJim Ingham case 'e': 92a5a97ebeSJim Ingham m_end_idx = Args::StringToUInt32(option_arg, 0, 0, &success); 93a5a97ebeSJim Ingham if (!success) 9486edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for end index: %s", option_arg); 95a5a97ebeSJim Ingham break; 96a5a97ebeSJim Ingham case 's': 97a5a97ebeSJim Ingham m_start_idx = Args::StringToUInt32(option_arg, 0, 0, &success); 98a5a97ebeSJim Ingham if (!success) 9986edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for start index: %s", option_arg); 100a5a97ebeSJim Ingham break; 101a5a97ebeSJim Ingham default: 10286edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 103a5a97ebeSJim Ingham break; 104a5a97ebeSJim Ingham } 105a5a97ebeSJim Ingham 106a5a97ebeSJim Ingham return error; 107a5a97ebeSJim Ingham } 108a5a97ebeSJim Ingham 109a5a97ebeSJim Ingham void 110a5a97ebeSJim Ingham OptionParsingStarting () 111a5a97ebeSJim Ingham { 112a5a97ebeSJim Ingham m_start_idx = 0; 113a5a97ebeSJim Ingham m_end_idx = UINT_MAX; 114a5a97ebeSJim Ingham } 115a5a97ebeSJim Ingham 116a5a97ebeSJim Ingham const OptionDefinition* 117a5a97ebeSJim Ingham GetDefinitions () 118a5a97ebeSJim Ingham { 119a5a97ebeSJim Ingham return g_option_table; 120a5a97ebeSJim Ingham } 121a5a97ebeSJim Ingham 122a5a97ebeSJim Ingham // Options table: Required for subclasses of Options. 123a5a97ebeSJim Ingham 124a5a97ebeSJim Ingham static OptionDefinition g_option_table[]; 125a5a97ebeSJim Ingham 126a5a97ebeSJim Ingham // Instance variables to hold the values for command options. 127a5a97ebeSJim Ingham 128a5a97ebeSJim Ingham uint32_t m_start_idx; 129a5a97ebeSJim Ingham uint32_t m_end_idx; 130a5a97ebeSJim Ingham }; 131a5a97ebeSJim Ingham 132a5a97ebeSJim Ingham bool 1335a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 134a5a97ebeSJim Ingham { 135a5a97ebeSJim Ingham 136a5a97ebeSJim Ingham m_interpreter.DumpHistory (result.GetOutputStream(), 137a5a97ebeSJim Ingham m_options.m_start_idx, 138a5a97ebeSJim Ingham m_options.m_end_idx); 139a5a97ebeSJim Ingham return result.Succeeded(); 140a5a97ebeSJim Ingham 141a5a97ebeSJim Ingham } 1425a988416SJim Ingham 1435a988416SJim Ingham CommandOptions m_options; 144a5a97ebeSJim Ingham }; 145a5a97ebeSJim Ingham 146a5a97ebeSJim Ingham OptionDefinition 147a5a97ebeSJim Ingham CommandObjectCommandsHistory::CommandOptions::g_option_table[] = 148a5a97ebeSJim Ingham { 149a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "count", 'c', required_argument, NULL, 0, eArgTypeUnsignedInteger, "How many history commands to print."}, 150a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "start-index", 's', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands."}, 151a5a97ebeSJim Ingham { LLDB_OPT_SET_1, false, "end-index", 'e', required_argument, NULL, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands."}, 152a5a97ebeSJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 153a5a97ebeSJim Ingham }; 154a5a97ebeSJim Ingham 155a5a97ebeSJim Ingham 156a5a97ebeSJim Ingham //------------------------------------------------------------------------- 157a5a97ebeSJim Ingham // CommandObjectCommandsSource 158a5a97ebeSJim Ingham //------------------------------------------------------------------------- 159a5a97ebeSJim Ingham 1605a988416SJim Ingham class CommandObjectCommandsSource : public CommandObjectParsed 161ebc09c36SJim Ingham { 1625a988416SJim Ingham public: 1635a988416SJim Ingham CommandObjectCommandsSource(CommandInterpreter &interpreter) : 1645a988416SJim Ingham CommandObjectParsed (interpreter, 1655a988416SJim Ingham "command source", 1665a988416SJim Ingham "Read in debugger commands from the file <filename> and execute them.", 1675a988416SJim Ingham NULL), 1685a988416SJim Ingham m_options (interpreter) 1695a988416SJim Ingham { 1705a988416SJim Ingham CommandArgumentEntry arg; 1715a988416SJim Ingham CommandArgumentData file_arg; 1725a988416SJim Ingham 1735a988416SJim Ingham // Define the first (and only) variant of this arg. 1745a988416SJim Ingham file_arg.arg_type = eArgTypeFilename; 1755a988416SJim Ingham file_arg.arg_repetition = eArgRepeatPlain; 1765a988416SJim Ingham 1775a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 1785a988416SJim Ingham arg.push_back (file_arg); 1795a988416SJim Ingham 1805a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 1815a988416SJim Ingham m_arguments.push_back (arg); 1825a988416SJim Ingham } 1835a988416SJim Ingham 1845a988416SJim Ingham ~CommandObjectCommandsSource () {} 1855a988416SJim Ingham 1865a988416SJim Ingham virtual const char* 1875a988416SJim Ingham GetRepeatCommand (Args ¤t_command_args, uint32_t index) 1885a988416SJim Ingham { 1895a988416SJim Ingham return ""; 1905a988416SJim Ingham } 1915a988416SJim Ingham 192c7bece56SGreg Clayton virtual int 1935a988416SJim Ingham HandleArgumentCompletion (Args &input, 1945a988416SJim Ingham int &cursor_index, 1955a988416SJim Ingham int &cursor_char_position, 1965a988416SJim Ingham OptionElementVector &opt_element_vector, 1975a988416SJim Ingham int match_start_point, 1985a988416SJim Ingham int max_return_elements, 1995a988416SJim Ingham bool &word_complete, 2005a988416SJim Ingham StringList &matches) 2015a988416SJim Ingham { 2025a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2035a988416SJim Ingham completion_str.erase (cursor_char_position); 2045a988416SJim Ingham 2055a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2065a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 2075a988416SJim Ingham completion_str.c_str(), 2085a988416SJim Ingham match_start_point, 2095a988416SJim Ingham max_return_elements, 2105a988416SJim Ingham NULL, 2115a988416SJim Ingham word_complete, 2125a988416SJim Ingham matches); 2135a988416SJim Ingham return matches.GetSize(); 2145a988416SJim Ingham } 2155a988416SJim Ingham 2165a988416SJim Ingham virtual Options * 2175a988416SJim Ingham GetOptions () 2185a988416SJim Ingham { 2195a988416SJim Ingham return &m_options; 2205a988416SJim Ingham } 2215a988416SJim Ingham 2225a988416SJim Ingham protected: 223e16c50a1SJim Ingham 224e16c50a1SJim Ingham class CommandOptions : public Options 225e16c50a1SJim Ingham { 226e16c50a1SJim Ingham public: 227e16c50a1SJim Ingham 228eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 229*012d4fcaSEnrico Granata Options (interpreter), 230*012d4fcaSEnrico Granata m_stop_on_error (true) 231eb0103f2SGreg Clayton { 232eb0103f2SGreg Clayton } 233e16c50a1SJim Ingham 234e16c50a1SJim Ingham virtual 235e16c50a1SJim Ingham ~CommandOptions (){} 236e16c50a1SJim Ingham 237e16c50a1SJim Ingham virtual Error 238f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 239e16c50a1SJim Ingham { 240e16c50a1SJim Ingham Error error; 2413bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 242e16c50a1SJim Ingham bool success; 243e16c50a1SJim Ingham 244e16c50a1SJim Ingham switch (short_option) 245e16c50a1SJim Ingham { 246e16c50a1SJim Ingham case 'e': 247*012d4fcaSEnrico Granata m_stop_on_error.SetCurrentValue(Args::StringToBoolean(option_arg, true, &success)); 248e16c50a1SJim Ingham if (!success) 24986edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for stop-on-error: %s", option_arg); 250e16c50a1SJim Ingham break; 251e16c50a1SJim Ingham case 'c': 252e16c50a1SJim Ingham m_stop_on_continue = Args::StringToBoolean(option_arg, true, &success); 253e16c50a1SJim Ingham if (!success) 25486edbf41SGreg Clayton error.SetErrorStringWithFormat("invalid value for stop-on-continue: %s", option_arg); 255e16c50a1SJim Ingham break; 256e16c50a1SJim Ingham default: 25786edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 258e16c50a1SJim Ingham break; 259e16c50a1SJim Ingham } 260e16c50a1SJim Ingham 261e16c50a1SJim Ingham return error; 262e16c50a1SJim Ingham } 263e16c50a1SJim Ingham 264e16c50a1SJim Ingham void 265f6b8b581SGreg Clayton OptionParsingStarting () 266e16c50a1SJim Ingham { 267*012d4fcaSEnrico Granata m_stop_on_error.Clear(); 268e16c50a1SJim Ingham m_stop_on_continue = true; 269e16c50a1SJim Ingham } 270e16c50a1SJim Ingham 271e0d378b3SGreg Clayton const OptionDefinition* 272e16c50a1SJim Ingham GetDefinitions () 273e16c50a1SJim Ingham { 274e16c50a1SJim Ingham return g_option_table; 275e16c50a1SJim Ingham } 276e16c50a1SJim Ingham 277e16c50a1SJim Ingham // Options table: Required for subclasses of Options. 278e16c50a1SJim Ingham 279e0d378b3SGreg Clayton static OptionDefinition g_option_table[]; 280e16c50a1SJim Ingham 281e16c50a1SJim Ingham // Instance variables to hold the values for command options. 282e16c50a1SJim Ingham 283*012d4fcaSEnrico Granata OptionValueBoolean m_stop_on_error; 284e16c50a1SJim Ingham bool m_stop_on_continue; 285e16c50a1SJim Ingham }; 286e16c50a1SJim Ingham 287ebc09c36SJim Ingham bool 2885a988416SJim Ingham DoExecute(Args& command, CommandReturnObject &result) 289ebc09c36SJim Ingham { 290c7bece56SGreg Clayton const size_t argc = command.GetArgumentCount(); 291ebc09c36SJim Ingham if (argc == 1) 292ebc09c36SJim Ingham { 2935a988416SJim Ingham const char *filename = command.GetArgumentAtIndex(0); 294ebc09c36SJim Ingham 295ebc09c36SJim Ingham result.AppendMessageWithFormat ("Executing commands in '%s'.\n", filename); 296ebc09c36SJim Ingham 2971ee3853fSJohnny Chen FileSpec cmd_file (filename, true); 298e16c50a1SJim Ingham ExecutionContext *exe_ctx = NULL; // Just use the default context. 299e16c50a1SJim Ingham bool echo_commands = true; 300e16c50a1SJim Ingham bool print_results = true; 301*012d4fcaSEnrico Granata bool stop_on_error = m_options.m_stop_on_error.OptionWasSet() ? (bool)m_options.m_stop_on_error : m_interpreter.GetStopCmdSourceOnError(); 302ebc09c36SJim Ingham 303e16c50a1SJim Ingham m_interpreter.HandleCommandsFromFile (cmd_file, 304e16c50a1SJim Ingham exe_ctx, 305e16c50a1SJim Ingham m_options.m_stop_on_continue, 306*012d4fcaSEnrico Granata stop_on_error, 307e16c50a1SJim Ingham echo_commands, 308e16c50a1SJim Ingham print_results, 3095f5ab602SEnrico Granata eLazyBoolCalculate, 310e16c50a1SJim Ingham result); 311ebc09c36SJim Ingham } 312ebc09c36SJim Ingham else 313ebc09c36SJim Ingham { 314ebc09c36SJim Ingham result.AppendErrorWithFormat("'%s' takes exactly one executable filename argument.\n", GetCommandName()); 315ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 316ebc09c36SJim Ingham } 317ebc09c36SJim Ingham return result.Succeeded(); 318ebc09c36SJim Ingham 319ebc09c36SJim Ingham } 3205a988416SJim Ingham CommandOptions m_options; 321ebc09c36SJim Ingham }; 322ebc09c36SJim Ingham 323e0d378b3SGreg Clayton OptionDefinition 324e16c50a1SJim Ingham CommandObjectCommandsSource::CommandOptions::g_option_table[] = 325e16c50a1SJim Ingham { 326e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on error."}, 327e16c50a1SJim Ingham { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', required_argument, NULL, 0, eArgTypeBoolean, "If true, stop executing commands on continue."}, 328e16c50a1SJim Ingham { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 329e16c50a1SJim Ingham }; 330e16c50a1SJim Ingham 331ebc09c36SJim Ingham #pragma mark CommandObjectCommandsAlias 332ebc09c36SJim Ingham //------------------------------------------------------------------------- 333ebc09c36SJim Ingham // CommandObjectCommandsAlias 334ebc09c36SJim Ingham //------------------------------------------------------------------------- 335ebc09c36SJim Ingham 336be93a35aSEnrico Granata static const char *g_python_command_instructions = "Enter your Python command(s). Type 'DONE' to end.\n" 337be93a35aSEnrico Granata "You must define a Python function with this signature:\n" 33840d55710SEnrico Granata "def my_command_impl(debugger, args, result, internal_dict):"; 339be93a35aSEnrico Granata 340be93a35aSEnrico Granata 3415a988416SJim Ingham class CommandObjectCommandsAlias : public CommandObjectRaw 342ebc09c36SJim Ingham { 343be93a35aSEnrico Granata 344be93a35aSEnrico Granata 345ebc09c36SJim Ingham public: 346a7015092SGreg Clayton CommandObjectCommandsAlias (CommandInterpreter &interpreter) : 3475a988416SJim Ingham CommandObjectRaw (interpreter, 3480e5e5a79SGreg Clayton "command alias", 349e3d26315SCaroline Tice "Allow users to define their own debugger command abbreviations.", 350405fe67fSCaroline Tice NULL) 351ebc09c36SJim Ingham { 352ebc09c36SJim Ingham SetHelpLong( 353ebc09c36SJim Ingham "'alias' allows the user to create a short-cut or abbreviation for long \n\ 354ebc09c36SJim Ingham commands, multi-word commands, and commands that take particular options. \n\ 355ebc09c36SJim Ingham Below are some simple examples of how one might use the 'alias' command: \n\ 35669c12ccbSJason Molenda \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ 357ebc09c36SJim Ingham // command. \n\ 35869c12ccbSJason Molenda 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ 359ebc09c36SJim Ingham // command. Since breakpoint commands are two-word \n\ 360ebc09c36SJim Ingham // commands, the user will still need to enter the \n\ 361ebc09c36SJim Ingham // second word after 'bp', e.g. 'bp enable' or \n\ 362ebc09c36SJim Ingham // 'bp delete'. \n\ 36369c12ccbSJason Molenda 'command alias bpl breakpoint list' // Creates the abbreviation 'bpl' for the \n\ 364ebc09c36SJim Ingham // two-word command 'breakpoint list'. \n\ 365ebc09c36SJim Ingham \nAn alias can include some options for the command, with the values either \n\ 366ebc09c36SJim Ingham filled in at the time the alias is created, or specified as positional \n\ 367ebc09c36SJim Ingham arguments, to be filled in when the alias is invoked. The following example \n\ 368ebc09c36SJim Ingham shows how to create aliases with options: \n\ 369ebc09c36SJim Ingham \n\ 37069c12ccbSJason Molenda 'command alias bfl breakpoint set -f %1 -l %2' \n\ 371ebc09c36SJim Ingham \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ 372ebc09c36SJim Ingham options already part of the alias. So if the user wants to set a breakpoint \n\ 373ebc09c36SJim Ingham by file and line without explicitly having to use the -f and -l options, the \n\ 374ebc09c36SJim Ingham user can now use 'bfl' instead. The '%1' and '%2' are positional placeholders \n\ 375ebc09c36SJim Ingham for the actual arguments that will be passed when the alias command is used. \n\ 376ebc09c36SJim Ingham The number in the placeholder refers to the position/order the actual value \n\ 37781ded935SJim Ingham occupies when the alias is used. All the occurrences of '%1' in the alias \n\ 378ebc09c36SJim Ingham will be replaced with the first argument, all the occurrences of '%2' in the \n\ 379ebc09c36SJim Ingham alias will be replaced with the second argument, and so on. This also allows \n\ 380ebc09c36SJim Ingham actual arguments to be used multiple times within an alias (see 'process \n\ 38181ded935SJim Ingham launch' example below). \n\ 38281ded935SJim Ingham Note: the positional arguments must substitute as whole words in the resultant\n\ 38381ded935SJim Ingham command, so you can't at present do something like:\n\ 38481ded935SJim Ingham \n\ 38569c12ccbSJason Molenda command alias bcppfl breakpoint set -f %1.cpp -l %2\n\ 38681ded935SJim Ingham \n\ 38781ded935SJim Ingham to get the file extension \".cpp\" automatically appended. For more complex\n\ 38881ded935SJim Ingham aliasing, use the \"command regex\" command instead.\n\ 38981ded935SJim Ingham \nSo in the 'bfl' case, the actual file value will be \n\ 390ebc09c36SJim Ingham filled in with the first argument following 'bfl' and the actual line number \n\ 391ebc09c36SJim Ingham value will be filled in with the second argument. The user would use this \n\ 392ebc09c36SJim Ingham alias as follows: \n\ 39369c12ccbSJason Molenda \n (lldb) command alias bfl breakpoint set -f %1 -l %2 \n\ 394ebc09c36SJim Ingham <... some time later ...> \n\ 39509799af6SCaroline Tice (lldb) bfl my-file.c 137 \n\ 396ebc09c36SJim Ingham \nThis would be the same as if the user had entered \n\ 397ebc09c36SJim Ingham 'breakpoint set -f my-file.c -l 137'. \n\ 398ebc09c36SJim Ingham \nAnother example: \n\ 39969c12ccbSJason Molenda \n (lldb) command alias pltty process launch -s -o %1 -e %1 \n\ 40009799af6SCaroline Tice (lldb) pltty /dev/tty0 \n\ 401ebc09c36SJim Ingham // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ 402ebc09c36SJim Ingham \nIf the user always wanted to pass the same value to a particular option, the \n\ 403ebc09c36SJim Ingham alias could be defined with that value directly in the alias as a constant, \n\ 404ebc09c36SJim Ingham rather than using a positional placeholder: \n\ 40569c12ccbSJason Molenda \n command alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ 406ebc09c36SJim Ingham // 3 of whatever file is indicated. \n"); 407ebc09c36SJim Ingham 408405fe67fSCaroline Tice CommandArgumentEntry arg1; 409405fe67fSCaroline Tice CommandArgumentEntry arg2; 410405fe67fSCaroline Tice CommandArgumentEntry arg3; 411405fe67fSCaroline Tice CommandArgumentData alias_arg; 412405fe67fSCaroline Tice CommandArgumentData cmd_arg; 413405fe67fSCaroline Tice CommandArgumentData options_arg; 414405fe67fSCaroline Tice 415405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 416405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 417405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 418405fe67fSCaroline Tice 419405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 420405fe67fSCaroline Tice arg1.push_back (alias_arg); 421405fe67fSCaroline Tice 422405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 423405fe67fSCaroline Tice cmd_arg.arg_type = eArgTypeCommandName; 424405fe67fSCaroline Tice cmd_arg.arg_repetition = eArgRepeatPlain; 425405fe67fSCaroline Tice 426405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 427405fe67fSCaroline Tice arg2.push_back (cmd_arg); 428405fe67fSCaroline Tice 429405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 430405fe67fSCaroline Tice options_arg.arg_type = eArgTypeAliasOptions; 431405fe67fSCaroline Tice options_arg.arg_repetition = eArgRepeatOptional; 432405fe67fSCaroline Tice 433405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 434405fe67fSCaroline Tice arg3.push_back (options_arg); 435405fe67fSCaroline Tice 436405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 437405fe67fSCaroline Tice m_arguments.push_back (arg1); 438405fe67fSCaroline Tice m_arguments.push_back (arg2); 439405fe67fSCaroline Tice m_arguments.push_back (arg3); 440ebc09c36SJim Ingham } 441ebc09c36SJim Ingham 442ebc09c36SJim Ingham ~CommandObjectCommandsAlias () 443ebc09c36SJim Ingham { 444ebc09c36SJim Ingham } 445ebc09c36SJim Ingham 4465a988416SJim Ingham protected: 4475a988416SJim Ingham virtual bool 4485a988416SJim Ingham DoExecute (const char *raw_command_line, CommandReturnObject &result) 449844d2303SCaroline Tice { 450844d2303SCaroline Tice Args args (raw_command_line); 451844d2303SCaroline Tice std::string raw_command_string (raw_command_line); 452844d2303SCaroline Tice 453844d2303SCaroline Tice size_t argc = args.GetArgumentCount(); 454844d2303SCaroline Tice 455844d2303SCaroline Tice if (argc < 2) 456844d2303SCaroline Tice { 457844d2303SCaroline Tice result.AppendError ("'alias' requires at least two arguments"); 458844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 459844d2303SCaroline Tice return false; 460844d2303SCaroline Tice } 461844d2303SCaroline Tice 462844d2303SCaroline Tice // Get the alias command. 463844d2303SCaroline Tice 464844d2303SCaroline Tice const std::string alias_command = args.GetArgumentAtIndex (0); 465844d2303SCaroline Tice 466844d2303SCaroline Tice // Strip the new alias name off 'raw_command_string' (leave it on args, which gets passed to 'Execute', which 467844d2303SCaroline Tice // does the stripping itself. 468844d2303SCaroline Tice size_t pos = raw_command_string.find (alias_command); 469844d2303SCaroline Tice if (pos == 0) 470844d2303SCaroline Tice { 471844d2303SCaroline Tice raw_command_string = raw_command_string.substr (alias_command.size()); 472844d2303SCaroline Tice pos = raw_command_string.find_first_not_of (' '); 473844d2303SCaroline Tice if ((pos != std::string::npos) && (pos > 0)) 474844d2303SCaroline Tice raw_command_string = raw_command_string.substr (pos); 475844d2303SCaroline Tice } 476844d2303SCaroline Tice else 477844d2303SCaroline Tice { 478844d2303SCaroline Tice result.AppendError ("Error parsing command string. No alias created."); 479844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 480844d2303SCaroline Tice return false; 481844d2303SCaroline Tice } 482844d2303SCaroline Tice 483844d2303SCaroline Tice 484844d2303SCaroline Tice // Verify that the command is alias-able. 485844d2303SCaroline Tice if (m_interpreter.CommandExists (alias_command.c_str())) 486844d2303SCaroline Tice { 487844d2303SCaroline Tice result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 488844d2303SCaroline Tice alias_command.c_str()); 489844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 490844d2303SCaroline Tice return false; 491844d2303SCaroline Tice } 492844d2303SCaroline Tice 493844d2303SCaroline Tice // Get CommandObject that is being aliased. The command name is read from the front of raw_command_string. 494844d2303SCaroline Tice // raw_command_string is returned with the name of the command object stripped off the front. 495844d2303SCaroline Tice CommandObject *cmd_obj = m_interpreter.GetCommandObjectForCommand (raw_command_string); 496844d2303SCaroline Tice 497844d2303SCaroline Tice if (!cmd_obj) 498844d2303SCaroline Tice { 49986edbf41SGreg Clayton result.AppendErrorWithFormat ("invalid command given to 'alias'. '%s' does not begin with a valid command." 500844d2303SCaroline Tice " No alias created.", raw_command_string.c_str()); 501844d2303SCaroline Tice result.SetStatus (eReturnStatusFailed); 502844d2303SCaroline Tice return false; 503844d2303SCaroline Tice } 504844d2303SCaroline Tice else if (!cmd_obj->WantsRawCommandString ()) 505844d2303SCaroline Tice { 506844d2303SCaroline Tice // Note that args was initialized with the original command, and has not been updated to this point. 507844d2303SCaroline Tice // Therefore can we pass it to the version of Execute that does not need/expect raw input in the alias. 5085a988416SJim Ingham return HandleAliasingNormalCommand (args, result); 509844d2303SCaroline Tice } 510844d2303SCaroline Tice else 511844d2303SCaroline Tice { 5125a988416SJim Ingham return HandleAliasingRawCommand (alias_command, raw_command_string, *cmd_obj, result); 5135a988416SJim Ingham } 5145a988416SJim Ingham return result.Succeeded(); 5155a988416SJim Ingham } 5165a988416SJim Ingham 5175a988416SJim Ingham bool 5185a988416SJim Ingham HandleAliasingRawCommand (const std::string &alias_command, std::string &raw_command_string, CommandObject &cmd_obj, CommandReturnObject &result) 5195a988416SJim Ingham { 520844d2303SCaroline Tice // Verify & handle any options/arguments passed to the alias command 521844d2303SCaroline Tice 522844d2303SCaroline Tice OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 523844d2303SCaroline Tice OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 524844d2303SCaroline Tice 5255a988416SJim Ingham CommandObjectSP cmd_obj_sp = m_interpreter.GetCommandSPExact (cmd_obj.GetCommandName(), false); 526844d2303SCaroline Tice 527ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (cmd_obj_sp, raw_command_string.c_str(), option_arg_vector_sp)) 528844d2303SCaroline Tice { 529844d2303SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 530ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 531844d2303SCaroline Tice return false; 532844d2303SCaroline Tice } 533844d2303SCaroline Tice 534844d2303SCaroline Tice // Create the alias 535844d2303SCaroline Tice if (m_interpreter.AliasExists (alias_command.c_str()) 536844d2303SCaroline Tice || m_interpreter.UserCommandExists (alias_command.c_str())) 537844d2303SCaroline Tice { 538844d2303SCaroline Tice OptionArgVectorSP temp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 539844d2303SCaroline Tice if (temp_option_arg_sp.get()) 540844d2303SCaroline Tice { 541844d2303SCaroline Tice if (option_arg_vector->size() == 0) 542844d2303SCaroline Tice m_interpreter.RemoveAliasOptions (alias_command.c_str()); 543844d2303SCaroline Tice } 544844d2303SCaroline Tice result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 545844d2303SCaroline Tice alias_command.c_str()); 546844d2303SCaroline Tice } 547844d2303SCaroline Tice 548472362e6SCaroline Tice if (cmd_obj_sp) 549472362e6SCaroline Tice { 550844d2303SCaroline Tice m_interpreter.AddAlias (alias_command.c_str(), cmd_obj_sp); 551844d2303SCaroline Tice if (option_arg_vector->size() > 0) 552844d2303SCaroline Tice m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 553844d2303SCaroline Tice result.SetStatus (eReturnStatusSuccessFinishNoResult); 554844d2303SCaroline Tice } 555472362e6SCaroline Tice else 556472362e6SCaroline Tice { 557472362e6SCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 558472362e6SCaroline Tice result.SetStatus (eReturnStatusFailed); 559472362e6SCaroline Tice } 560844d2303SCaroline Tice return result.Succeeded (); 561844d2303SCaroline Tice } 562ebc09c36SJim Ingham 563ebc09c36SJim Ingham bool 5645a988416SJim Ingham HandleAliasingNormalCommand (Args& args, CommandReturnObject &result) 565ebc09c36SJim Ingham { 566867b185dSCaroline Tice size_t argc = args.GetArgumentCount(); 567ebc09c36SJim Ingham 568ebc09c36SJim Ingham if (argc < 2) 569ebc09c36SJim Ingham { 570ebc09c36SJim Ingham result.AppendError ("'alias' requires at least two arguments"); 571ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 572ebc09c36SJim Ingham return false; 573ebc09c36SJim Ingham } 574ebc09c36SJim Ingham 575ebc09c36SJim Ingham const std::string alias_command = args.GetArgumentAtIndex(0); 576ebc09c36SJim Ingham const std::string actual_command = args.GetArgumentAtIndex(1); 577ebc09c36SJim Ingham 578ebc09c36SJim Ingham args.Shift(); // Shift the alias command word off the argument vector. 579ebc09c36SJim Ingham args.Shift(); // Shift the old command word off the argument vector. 580ebc09c36SJim Ingham 581ebc09c36SJim Ingham // Verify that the command is alias'able, and get the appropriate command object. 582ebc09c36SJim Ingham 583a7015092SGreg Clayton if (m_interpreter.CommandExists (alias_command.c_str())) 584ebc09c36SJim Ingham { 585ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be redefined.\n", 586ebc09c36SJim Ingham alias_command.c_str()); 587ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 588ebc09c36SJim Ingham } 589ebc09c36SJim Ingham else 590ebc09c36SJim Ingham { 591a7015092SGreg Clayton CommandObjectSP command_obj_sp(m_interpreter.GetCommandSPExact (actual_command.c_str(), true)); 592ebc09c36SJim Ingham CommandObjectSP subcommand_obj_sp; 593ebc09c36SJim Ingham bool use_subcommand = false; 594ebc09c36SJim Ingham if (command_obj_sp.get()) 595ebc09c36SJim Ingham { 596ebc09c36SJim Ingham CommandObject *cmd_obj = command_obj_sp.get(); 597c982c768SGreg Clayton CommandObject *sub_cmd_obj = NULL; 598ebc09c36SJim Ingham OptionArgVectorSP option_arg_vector_sp = OptionArgVectorSP (new OptionArgVector); 599ebc09c36SJim Ingham OptionArgVector *option_arg_vector = option_arg_vector_sp.get(); 600ebc09c36SJim Ingham 601844d2303SCaroline Tice while (cmd_obj->IsMultiwordObject() && args.GetArgumentCount() > 0) 602ebc09c36SJim Ingham { 603ebc09c36SJim Ingham if (argc >= 3) 604ebc09c36SJim Ingham { 605ebc09c36SJim Ingham const std::string sub_command = args.GetArgumentAtIndex(0); 606ebc09c36SJim Ingham assert (sub_command.length() != 0); 607998255bfSGreg Clayton subcommand_obj_sp = cmd_obj->GetSubcommandSP (sub_command.c_str()); 608ebc09c36SJim Ingham if (subcommand_obj_sp.get()) 609ebc09c36SJim Ingham { 610ebc09c36SJim Ingham sub_cmd_obj = subcommand_obj_sp.get(); 611ebc09c36SJim Ingham use_subcommand = true; 612ebc09c36SJim Ingham args.Shift(); // Shift the sub_command word off the argument vector. 613844d2303SCaroline Tice cmd_obj = sub_cmd_obj; 614ebc09c36SJim Ingham } 615ebc09c36SJim Ingham else 616ebc09c36SJim Ingham { 617f415eeb4SCaroline Tice result.AppendErrorWithFormat("'%s' is not a valid sub-command of '%s'. " 618f415eeb4SCaroline Tice "Unable to create alias.\n", 619f415eeb4SCaroline Tice sub_command.c_str(), actual_command.c_str()); 620ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 621ebc09c36SJim Ingham return false; 622ebc09c36SJim Ingham } 623ebc09c36SJim Ingham } 624ebc09c36SJim Ingham } 625ebc09c36SJim Ingham 626ebc09c36SJim Ingham // Verify & handle any options/arguments passed to the alias command 627ebc09c36SJim Ingham 628ebc09c36SJim Ingham if (args.GetArgumentCount () > 0) 629ebc09c36SJim Ingham { 630ca90c47eSCaroline Tice CommandObjectSP tmp_sp = m_interpreter.GetCommandSPExact (cmd_obj->GetCommandName(), false); 631ebc09c36SJim Ingham if (use_subcommand) 632ca90c47eSCaroline Tice tmp_sp = m_interpreter.GetCommandSPExact (sub_cmd_obj->GetCommandName(), false); 633ca90c47eSCaroline Tice 634ca90c47eSCaroline Tice std::string args_string; 635ca90c47eSCaroline Tice args.GetCommandString (args_string); 636ca90c47eSCaroline Tice 637ca90c47eSCaroline Tice if (!m_interpreter.ProcessAliasOptionsArgs (tmp_sp, args_string.c_str(), option_arg_vector_sp)) 638ebc09c36SJim Ingham { 639ca90c47eSCaroline Tice result.AppendError ("Unable to create requested alias.\n"); 640ca90c47eSCaroline Tice result.SetStatus (eReturnStatusFailed); 641e7941795SCaroline Tice return false; 642867b185dSCaroline Tice } 643867b185dSCaroline Tice } 644867b185dSCaroline Tice 645ebc09c36SJim Ingham // Create the alias. 646ebc09c36SJim Ingham 647a7015092SGreg Clayton if (m_interpreter.AliasExists (alias_command.c_str()) 648a7015092SGreg Clayton || m_interpreter.UserCommandExists (alias_command.c_str())) 649ebc09c36SJim Ingham { 650a7015092SGreg Clayton OptionArgVectorSP tmp_option_arg_sp (m_interpreter.GetAliasOptions (alias_command.c_str())); 651ebc09c36SJim Ingham if (tmp_option_arg_sp.get()) 652ebc09c36SJim Ingham { 653ebc09c36SJim Ingham if (option_arg_vector->size() == 0) 654a7015092SGreg Clayton m_interpreter.RemoveAliasOptions (alias_command.c_str()); 655ebc09c36SJim Ingham } 656ebc09c36SJim Ingham result.AppendWarningWithFormat ("Overwriting existing definition for '%s'.\n", 657ebc09c36SJim Ingham alias_command.c_str()); 658ebc09c36SJim Ingham } 659ebc09c36SJim Ingham 660ebc09c36SJim Ingham if (use_subcommand) 661a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), subcommand_obj_sp); 662ebc09c36SJim Ingham else 663a7015092SGreg Clayton m_interpreter.AddAlias (alias_command.c_str(), command_obj_sp); 664ebc09c36SJim Ingham if (option_arg_vector->size() > 0) 665a7015092SGreg Clayton m_interpreter.AddOrReplaceAliasOptions (alias_command.c_str(), option_arg_vector_sp); 666ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 667ebc09c36SJim Ingham } 668ebc09c36SJim Ingham else 669ebc09c36SJim Ingham { 670ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing command.\n", actual_command.c_str()); 671ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 672e7941795SCaroline Tice return false; 673ebc09c36SJim Ingham } 674ebc09c36SJim Ingham } 675ebc09c36SJim Ingham 676ebc09c36SJim Ingham return result.Succeeded(); 677ebc09c36SJim Ingham } 6785a988416SJim Ingham 679ebc09c36SJim Ingham }; 680ebc09c36SJim Ingham 681ebc09c36SJim Ingham #pragma mark CommandObjectCommandsUnalias 682ebc09c36SJim Ingham //------------------------------------------------------------------------- 683ebc09c36SJim Ingham // CommandObjectCommandsUnalias 684ebc09c36SJim Ingham //------------------------------------------------------------------------- 685ebc09c36SJim Ingham 6865a988416SJim Ingham class CommandObjectCommandsUnalias : public CommandObjectParsed 687ebc09c36SJim Ingham { 688ebc09c36SJim Ingham public: 689a7015092SGreg Clayton CommandObjectCommandsUnalias (CommandInterpreter &interpreter) : 6905a988416SJim Ingham CommandObjectParsed (interpreter, 6910e5e5a79SGreg Clayton "command unalias", 69286ddae50SCaroline Tice "Allow the user to remove/delete a user-defined command abbreviation.", 693405fe67fSCaroline Tice NULL) 694ebc09c36SJim Ingham { 695405fe67fSCaroline Tice CommandArgumentEntry arg; 696405fe67fSCaroline Tice CommandArgumentData alias_arg; 697405fe67fSCaroline Tice 698405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 699405fe67fSCaroline Tice alias_arg.arg_type = eArgTypeAliasName; 700405fe67fSCaroline Tice alias_arg.arg_repetition = eArgRepeatPlain; 701405fe67fSCaroline Tice 702405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 703405fe67fSCaroline Tice arg.push_back (alias_arg); 704405fe67fSCaroline Tice 705405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 706405fe67fSCaroline Tice m_arguments.push_back (arg); 707ebc09c36SJim Ingham } 708ebc09c36SJim Ingham 709ebc09c36SJim Ingham ~CommandObjectCommandsUnalias() 710ebc09c36SJim Ingham { 711ebc09c36SJim Ingham } 712ebc09c36SJim Ingham 7135a988416SJim Ingham protected: 714ebc09c36SJim Ingham bool 7155a988416SJim Ingham DoExecute (Args& args, CommandReturnObject &result) 716ebc09c36SJim Ingham { 717ebc09c36SJim Ingham CommandObject::CommandMap::iterator pos; 718ebc09c36SJim Ingham CommandObject *cmd_obj; 719ebc09c36SJim Ingham 720ebc09c36SJim Ingham if (args.GetArgumentCount() != 0) 721ebc09c36SJim Ingham { 722ebc09c36SJim Ingham const char *command_name = args.GetArgumentAtIndex(0); 723a7015092SGreg Clayton cmd_obj = m_interpreter.GetCommandObject(command_name); 724ebc09c36SJim Ingham if (cmd_obj) 725ebc09c36SJim Ingham { 726a7015092SGreg Clayton if (m_interpreter.CommandExists (command_name)) 727ebc09c36SJim Ingham { 728ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is a permanent debugger command and cannot be removed.\n", 729ebc09c36SJim Ingham command_name); 730ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 731ebc09c36SJim Ingham } 732ebc09c36SJim Ingham else 733ebc09c36SJim Ingham { 734ebc09c36SJim Ingham 735a7015092SGreg Clayton if (m_interpreter.RemoveAlias (command_name) == false) 736ebc09c36SJim Ingham { 737a7015092SGreg Clayton if (m_interpreter.AliasExists (command_name)) 738ebc09c36SJim Ingham result.AppendErrorWithFormat ("Error occurred while attempting to unalias '%s'.\n", 739ebc09c36SJim Ingham command_name); 740ebc09c36SJim Ingham else 741ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not an existing alias.\n", command_name); 742ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 743ebc09c36SJim Ingham } 744ebc09c36SJim Ingham else 745ebc09c36SJim Ingham result.SetStatus (eReturnStatusSuccessFinishNoResult); 746ebc09c36SJim Ingham } 747ebc09c36SJim Ingham } 748ebc09c36SJim Ingham else 749ebc09c36SJim Ingham { 750ebc09c36SJim Ingham result.AppendErrorWithFormat ("'%s' is not a known command.\nTry 'help' to see a " 751ebc09c36SJim Ingham "current list of commands.\n", 752ebc09c36SJim Ingham command_name); 753ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 754ebc09c36SJim Ingham } 755ebc09c36SJim Ingham } 756ebc09c36SJim Ingham else 757ebc09c36SJim Ingham { 758ebc09c36SJim Ingham result.AppendError ("must call 'unalias' with a valid alias"); 759ebc09c36SJim Ingham result.SetStatus (eReturnStatusFailed); 760ebc09c36SJim Ingham } 761ebc09c36SJim Ingham 762ebc09c36SJim Ingham return result.Succeeded(); 763ebc09c36SJim Ingham } 764ebc09c36SJim Ingham }; 765ebc09c36SJim Ingham 766de164aaaSGreg Clayton //------------------------------------------------------------------------- 767de164aaaSGreg Clayton // CommandObjectCommandsAddRegex 768de164aaaSGreg Clayton //------------------------------------------------------------------------- 7695a988416SJim Ingham #pragma mark CommandObjectCommandsAddRegex 770de164aaaSGreg Clayton 7715a988416SJim Ingham class CommandObjectCommandsAddRegex : public CommandObjectParsed 772de164aaaSGreg Clayton { 773de164aaaSGreg Clayton public: 774de164aaaSGreg Clayton CommandObjectCommandsAddRegex (CommandInterpreter &interpreter) : 7755a988416SJim Ingham CommandObjectParsed (interpreter, 7760e5e5a79SGreg Clayton "command regex", 777de164aaaSGreg Clayton "Allow the user to create a regular expression command.", 7780e5e5a79SGreg Clayton "command regex <cmd-name> [s/<regex>/<subst>/ ...]"), 779de164aaaSGreg Clayton m_options (interpreter) 780de164aaaSGreg Clayton { 7810e5e5a79SGreg Clayton SetHelpLong( 7820e5e5a79SGreg Clayton "This command allows the user to create powerful regular expression commands\n" 7830e5e5a79SGreg Clayton "with substitutions. The regular expressions and substitutions are specified\n" 7840e5e5a79SGreg Clayton "using the regular exression substitution format of:\n" 7850e5e5a79SGreg Clayton "\n" 7860e5e5a79SGreg Clayton " s/<regex>/<subst>/\n" 7870e5e5a79SGreg Clayton "\n" 7880e5e5a79SGreg Clayton "<regex> is a regular expression that can use parenthesis to capture regular\n" 7890e5e5a79SGreg Clayton "expression input and substitute the captured matches in the output using %1\n" 7900e5e5a79SGreg Clayton "for the first match, %2 for the second, and so on.\n" 7910e5e5a79SGreg Clayton "\n" 7920e5e5a79SGreg Clayton "The regular expressions can all be specified on the command line if more than\n" 7930e5e5a79SGreg Clayton "one argument is provided. If just the command name is provided on the command\n" 7940e5e5a79SGreg Clayton "line, then the regular expressions and substitutions can be entered on separate\n" 7950e5e5a79SGreg Clayton " lines, followed by an empty line to terminate the command definition.\n" 7960e5e5a79SGreg Clayton "\n" 7970e5e5a79SGreg Clayton "EXAMPLES\n" 7980e5e5a79SGreg Clayton "\n" 799adc43c99SSean Callanan "The following example will define a regular expression command named 'f' that\n" 8000e5e5a79SGreg Clayton "will call 'finish' if there are no arguments, or 'frame select <frame-idx>' if\n" 8010e5e5a79SGreg Clayton "a number follows 'f':\n" 802adc43c99SSean Callanan "\n" 8030e5e5a79SGreg Clayton " (lldb) command regex f s/^$/finish/ 's/([0-9]+)/frame select %1/'\n" 804adc43c99SSean Callanan "\n" 8050e5e5a79SGreg Clayton ); 806de164aaaSGreg Clayton } 807de164aaaSGreg Clayton 808de164aaaSGreg Clayton ~CommandObjectCommandsAddRegex() 809de164aaaSGreg Clayton { 810de164aaaSGreg Clayton } 811de164aaaSGreg Clayton 812de164aaaSGreg Clayton 8135a988416SJim Ingham protected: 814de164aaaSGreg Clayton bool 8155a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 816de164aaaSGreg Clayton { 8175a988416SJim Ingham const size_t argc = command.GetArgumentCount(); 8180e5e5a79SGreg Clayton if (argc == 0) 819de164aaaSGreg Clayton { 82069c12ccbSJason Molenda result.AppendError ("usage: 'command regex <command-name> [s/<regex1>/<subst1>/ s/<regex2>/<subst2>/ ...]'\n"); 8210e5e5a79SGreg Clayton result.SetStatus (eReturnStatusFailed); 8220e5e5a79SGreg Clayton } 8230e5e5a79SGreg Clayton else 8240e5e5a79SGreg Clayton { 8250e5e5a79SGreg Clayton Error error; 8265a988416SJim Ingham const char *name = command.GetArgumentAtIndex(0); 827de164aaaSGreg Clayton m_regex_cmd_ap.reset (new CommandObjectRegexCommand (m_interpreter, 828de164aaaSGreg Clayton name, 829de164aaaSGreg Clayton m_options.GetHelp (), 830de164aaaSGreg Clayton m_options.GetSyntax (), 831de164aaaSGreg Clayton 10)); 8320e5e5a79SGreg Clayton 8330e5e5a79SGreg Clayton if (argc == 1) 8340e5e5a79SGreg Clayton { 8350e5e5a79SGreg Clayton InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 836de164aaaSGreg Clayton if (reader_sp) 837de164aaaSGreg Clayton { 8380e5e5a79SGreg Clayton error =reader_sp->Initialize (CommandObjectCommandsAddRegex::InputReaderCallback, 839de164aaaSGreg Clayton this, // baton 840de164aaaSGreg Clayton eInputReaderGranularityLine, // token size, to pass to callback function 8410e5e5a79SGreg Clayton NULL, // end token 842de164aaaSGreg Clayton "> ", // prompt 8430e5e5a79SGreg Clayton true); // echo input 8440e5e5a79SGreg Clayton if (error.Success()) 845de164aaaSGreg Clayton { 846de164aaaSGreg Clayton m_interpreter.GetDebugger().PushInputReader (reader_sp); 847de164aaaSGreg Clayton result.SetStatus (eReturnStatusSuccessFinishNoResult); 8480e5e5a79SGreg Clayton return true; 849de164aaaSGreg Clayton } 850de164aaaSGreg Clayton } 851de164aaaSGreg Clayton } 852de164aaaSGreg Clayton else 853de164aaaSGreg Clayton { 8540e5e5a79SGreg Clayton for (size_t arg_idx = 1; arg_idx < argc; ++arg_idx) 8550e5e5a79SGreg Clayton { 8565a988416SJim Ingham llvm::StringRef arg_strref (command.GetArgumentAtIndex(arg_idx)); 8570e5e5a79SGreg Clayton error = AppendRegexSubstitution (arg_strref); 8580e5e5a79SGreg Clayton if (error.Fail()) 8590e5e5a79SGreg Clayton break; 8600e5e5a79SGreg Clayton } 8610e5e5a79SGreg Clayton 8620e5e5a79SGreg Clayton if (error.Success()) 8630e5e5a79SGreg Clayton { 8640e5e5a79SGreg Clayton AddRegexCommandToInterpreter(); 8650e5e5a79SGreg Clayton } 8660e5e5a79SGreg Clayton } 8670e5e5a79SGreg Clayton if (error.Fail()) 8680e5e5a79SGreg Clayton { 8690e5e5a79SGreg Clayton result.AppendError (error.AsCString()); 870de164aaaSGreg Clayton result.SetStatus (eReturnStatusFailed); 871de164aaaSGreg Clayton } 8720e5e5a79SGreg Clayton } 8730e5e5a79SGreg Clayton 874de164aaaSGreg Clayton return result.Succeeded(); 875de164aaaSGreg Clayton } 876de164aaaSGreg Clayton 8770e5e5a79SGreg Clayton Error 8780e5e5a79SGreg Clayton AppendRegexSubstitution (const llvm::StringRef ®ex_sed) 879de164aaaSGreg Clayton { 8800e5e5a79SGreg Clayton Error error; 8810e5e5a79SGreg Clayton 8820e5e5a79SGreg Clayton if (m_regex_cmd_ap.get() == NULL) 883de164aaaSGreg Clayton { 8840e5e5a79SGreg Clayton error.SetErrorStringWithFormat("invalid regular expression command object for: '%.*s'", 8850e5e5a79SGreg Clayton (int)regex_sed.size(), 8860e5e5a79SGreg Clayton regex_sed.data()); 8870e5e5a79SGreg Clayton return error; 888de164aaaSGreg Clayton } 8890e5e5a79SGreg Clayton 8900e5e5a79SGreg Clayton size_t regex_sed_size = regex_sed.size(); 8910e5e5a79SGreg Clayton 8920e5e5a79SGreg Clayton if (regex_sed_size <= 1) 8930e5e5a79SGreg Clayton { 8940e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string is too short: '%.*s'", 8950e5e5a79SGreg Clayton (int)regex_sed.size(), 8960e5e5a79SGreg Clayton regex_sed.data()); 8970e5e5a79SGreg Clayton return error; 8980e5e5a79SGreg Clayton } 8990e5e5a79SGreg Clayton 9000e5e5a79SGreg Clayton if (regex_sed[0] != 's') 9010e5e5a79SGreg Clayton { 9020e5e5a79SGreg Clayton error.SetErrorStringWithFormat("regular expression substitution string doesn't start with 's': '%.*s'", 9030e5e5a79SGreg Clayton (int)regex_sed.size(), 9040e5e5a79SGreg Clayton regex_sed.data()); 9050e5e5a79SGreg Clayton return error; 9060e5e5a79SGreg Clayton } 9070e5e5a79SGreg Clayton const size_t first_separator_char_pos = 1; 9080e5e5a79SGreg Clayton // use the char that follows 's' as the regex separator character 9090e5e5a79SGreg Clayton // so we can have "s/<regex>/<subst>/" or "s|<regex>|<subst>|" 9100e5e5a79SGreg Clayton const char separator_char = regex_sed[first_separator_char_pos]; 9110e5e5a79SGreg Clayton const size_t second_separator_char_pos = regex_sed.find (separator_char, first_separator_char_pos + 1); 9120e5e5a79SGreg Clayton 9130e5e5a79SGreg Clayton if (second_separator_char_pos == std::string::npos) 9140e5e5a79SGreg Clayton { 9150e5e5a79SGreg Clayton error.SetErrorStringWithFormat("missing second '%c' separator char after '%.*s'", 9160e5e5a79SGreg Clayton separator_char, 9170e5e5a79SGreg Clayton (int)(regex_sed.size() - first_separator_char_pos - 1), 9180e5e5a79SGreg Clayton regex_sed.data() + (first_separator_char_pos + 1)); 9190e5e5a79SGreg Clayton return error; 9200e5e5a79SGreg Clayton } 9210e5e5a79SGreg Clayton 9220e5e5a79SGreg Clayton const size_t third_separator_char_pos = regex_sed.find (separator_char, second_separator_char_pos + 1); 9230e5e5a79SGreg Clayton 9240e5e5a79SGreg Clayton if (third_separator_char_pos == std::string::npos) 9250e5e5a79SGreg Clayton { 9260e5e5a79SGreg Clayton error.SetErrorStringWithFormat("missing third '%c' separator char after '%.*s'", 9270e5e5a79SGreg Clayton separator_char, 9280e5e5a79SGreg Clayton (int)(regex_sed.size() - second_separator_char_pos - 1), 9290e5e5a79SGreg Clayton regex_sed.data() + (second_separator_char_pos + 1)); 9300e5e5a79SGreg Clayton return error; 9310e5e5a79SGreg Clayton } 9320e5e5a79SGreg Clayton 9330e5e5a79SGreg Clayton if (third_separator_char_pos != regex_sed_size - 1) 9340e5e5a79SGreg Clayton { 9350e5e5a79SGreg Clayton // Make sure that everything that follows the last regex 9360e5e5a79SGreg Clayton // separator char 9370e5e5a79SGreg Clayton if (regex_sed.find_first_not_of("\t\n\v\f\r ", third_separator_char_pos + 1) != std::string::npos) 9380e5e5a79SGreg Clayton { 9390e5e5a79SGreg Clayton error.SetErrorStringWithFormat("extra data found after the '%.*s' regular expression substitution string: '%.*s'", 9400e5e5a79SGreg Clayton (int)third_separator_char_pos + 1, 9410e5e5a79SGreg Clayton regex_sed.data(), 9420e5e5a79SGreg Clayton (int)(regex_sed.size() - third_separator_char_pos - 1), 9430e5e5a79SGreg Clayton regex_sed.data() + (third_separator_char_pos + 1)); 9440e5e5a79SGreg Clayton return error; 9450e5e5a79SGreg Clayton } 9460e5e5a79SGreg Clayton 9470e5e5a79SGreg Clayton } 9480e5e5a79SGreg Clayton else if (first_separator_char_pos + 1 == second_separator_char_pos) 9490e5e5a79SGreg Clayton { 9500e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<regex> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 9510e5e5a79SGreg Clayton separator_char, 9520e5e5a79SGreg Clayton separator_char, 9530e5e5a79SGreg Clayton separator_char, 9540e5e5a79SGreg Clayton (int)regex_sed.size(), 9550e5e5a79SGreg Clayton regex_sed.data()); 9560e5e5a79SGreg Clayton return error; 9570e5e5a79SGreg Clayton } 9580e5e5a79SGreg Clayton else if (second_separator_char_pos + 1 == third_separator_char_pos) 9590e5e5a79SGreg Clayton { 9600e5e5a79SGreg Clayton error.SetErrorStringWithFormat("<subst> can't be empty in 's%c<regex>%c<subst>%c' string: '%.*s'", 9610e5e5a79SGreg Clayton separator_char, 9620e5e5a79SGreg Clayton separator_char, 9630e5e5a79SGreg Clayton separator_char, 9640e5e5a79SGreg Clayton (int)regex_sed.size(), 9650e5e5a79SGreg Clayton regex_sed.data()); 9660e5e5a79SGreg Clayton return error; 9670e5e5a79SGreg Clayton } 9680e5e5a79SGreg Clayton std::string regex(regex_sed.substr(first_separator_char_pos + 1, second_separator_char_pos - first_separator_char_pos - 1)); 9690e5e5a79SGreg Clayton std::string subst(regex_sed.substr(second_separator_char_pos + 1, third_separator_char_pos - second_separator_char_pos - 1)); 9700e5e5a79SGreg Clayton m_regex_cmd_ap->AddRegexCommand (regex.c_str(), 9710e5e5a79SGreg Clayton subst.c_str()); 9720e5e5a79SGreg Clayton return error; 973de164aaaSGreg Clayton } 974de164aaaSGreg Clayton 975de164aaaSGreg Clayton void 9760e5e5a79SGreg Clayton AddRegexCommandToInterpreter() 977de164aaaSGreg Clayton { 978de164aaaSGreg Clayton if (m_regex_cmd_ap.get()) 979de164aaaSGreg Clayton { 980de164aaaSGreg Clayton if (m_regex_cmd_ap->HasRegexEntries()) 981de164aaaSGreg Clayton { 982de164aaaSGreg Clayton CommandObjectSP cmd_sp (m_regex_cmd_ap.release()); 983de164aaaSGreg Clayton m_interpreter.AddCommand(cmd_sp->GetCommandName(), cmd_sp, true); 984de164aaaSGreg Clayton } 985de164aaaSGreg Clayton } 986de164aaaSGreg Clayton } 987de164aaaSGreg Clayton 9880e5e5a79SGreg Clayton void 9890e5e5a79SGreg Clayton InputReaderDidCancel() 9900e5e5a79SGreg Clayton { 9910e5e5a79SGreg Clayton m_regex_cmd_ap.reset(); 9920e5e5a79SGreg Clayton } 9930e5e5a79SGreg Clayton 994de164aaaSGreg Clayton static size_t 995de164aaaSGreg Clayton InputReaderCallback (void *baton, 996de164aaaSGreg Clayton InputReader &reader, 997de164aaaSGreg Clayton lldb::InputReaderAction notification, 998de164aaaSGreg Clayton const char *bytes, 9995a988416SJim Ingham size_t bytes_len) 10005a988416SJim Ingham { 10015a988416SJim Ingham CommandObjectCommandsAddRegex *add_regex_cmd = (CommandObjectCommandsAddRegex *) baton; 10025a988416SJim Ingham bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 10035a988416SJim Ingham 10045a988416SJim Ingham switch (notification) 10055a988416SJim Ingham { 10065a988416SJim Ingham case eInputReaderActivate: 10075a988416SJim Ingham if (!batch_mode) 10085a988416SJim Ingham { 10095a988416SJim Ingham StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream (); 10105a988416SJim Ingham out_stream->Printf("%s\n", "Enter regular expressions in the form 's/<regex>/<subst>/' and terminate with an empty line:"); 10115a988416SJim Ingham out_stream->Flush(); 10125a988416SJim Ingham } 10135a988416SJim Ingham break; 10145a988416SJim Ingham case eInputReaderReactivate: 10155a988416SJim Ingham break; 10165a988416SJim Ingham 10175a988416SJim Ingham case eInputReaderDeactivate: 10185a988416SJim Ingham break; 10195a988416SJim Ingham 10205a988416SJim Ingham case eInputReaderAsynchronousOutputWritten: 10215a988416SJim Ingham break; 10225a988416SJim Ingham 10235a988416SJim Ingham case eInputReaderGotToken: 10245a988416SJim Ingham while (bytes_len > 0 && (bytes[bytes_len-1] == '\r' || bytes[bytes_len-1] == '\n')) 10255a988416SJim Ingham --bytes_len; 10265a988416SJim Ingham if (bytes_len == 0) 10275a988416SJim Ingham reader.SetIsDone(true); 10285a988416SJim Ingham else if (bytes) 10295a988416SJim Ingham { 10305a988416SJim Ingham llvm::StringRef bytes_strref (bytes, bytes_len); 10315a988416SJim Ingham Error error (add_regex_cmd->AppendRegexSubstitution (bytes_strref)); 10325a988416SJim Ingham if (error.Fail()) 10335a988416SJim Ingham { 10345a988416SJim Ingham if (!batch_mode) 10355a988416SJim Ingham { 10365a988416SJim Ingham StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 10375a988416SJim Ingham out_stream->Printf("error: %s\n", error.AsCString()); 10385a988416SJim Ingham out_stream->Flush(); 10395a988416SJim Ingham } 10405a988416SJim Ingham add_regex_cmd->InputReaderDidCancel (); 10415a988416SJim Ingham reader.SetIsDone (true); 10425a988416SJim Ingham } 10435a988416SJim Ingham } 10445a988416SJim Ingham break; 10455a988416SJim Ingham 10465a988416SJim Ingham case eInputReaderInterrupt: 10475a988416SJim Ingham { 10485a988416SJim Ingham reader.SetIsDone (true); 10495a988416SJim Ingham if (!batch_mode) 10505a988416SJim Ingham { 10515a988416SJim Ingham StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 10525a988416SJim Ingham out_stream->PutCString("Regular expression command creations was cancelled.\n"); 10535a988416SJim Ingham out_stream->Flush(); 10545a988416SJim Ingham } 10555a988416SJim Ingham add_regex_cmd->InputReaderDidCancel (); 10565a988416SJim Ingham } 10575a988416SJim Ingham break; 10585a988416SJim Ingham 10595a988416SJim Ingham case eInputReaderEndOfFile: 10605a988416SJim Ingham reader.SetIsDone (true); 10615a988416SJim Ingham break; 10625a988416SJim Ingham 10635a988416SJim Ingham case eInputReaderDone: 10645a988416SJim Ingham add_regex_cmd->AddRegexCommandToInterpreter(); 10655a988416SJim Ingham break; 10665a988416SJim Ingham } 10675a988416SJim Ingham 10685a988416SJim Ingham return bytes_len; 10695a988416SJim Ingham } 10705a988416SJim Ingham 1071de164aaaSGreg Clayton private: 10727b0992d9SGreg Clayton std::unique_ptr<CommandObjectRegexCommand> m_regex_cmd_ap; 1073de164aaaSGreg Clayton 1074de164aaaSGreg Clayton class CommandOptions : public Options 1075de164aaaSGreg Clayton { 1076de164aaaSGreg Clayton public: 1077de164aaaSGreg Clayton 1078de164aaaSGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 1079de164aaaSGreg Clayton Options (interpreter) 1080de164aaaSGreg Clayton { 1081de164aaaSGreg Clayton } 1082de164aaaSGreg Clayton 1083de164aaaSGreg Clayton virtual 1084de164aaaSGreg Clayton ~CommandOptions (){} 1085de164aaaSGreg Clayton 1086de164aaaSGreg Clayton virtual Error 1087de164aaaSGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 1088de164aaaSGreg Clayton { 1089de164aaaSGreg Clayton Error error; 10903bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1091de164aaaSGreg Clayton 1092de164aaaSGreg Clayton switch (short_option) 1093de164aaaSGreg Clayton { 1094de164aaaSGreg Clayton case 'h': 1095de164aaaSGreg Clayton m_help.assign (option_arg); 1096de164aaaSGreg Clayton break; 1097de164aaaSGreg Clayton case 's': 1098de164aaaSGreg Clayton m_syntax.assign (option_arg); 1099de164aaaSGreg Clayton break; 1100de164aaaSGreg Clayton 1101de164aaaSGreg Clayton default: 110286edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1103de164aaaSGreg Clayton break; 1104de164aaaSGreg Clayton } 1105de164aaaSGreg Clayton 1106de164aaaSGreg Clayton return error; 1107de164aaaSGreg Clayton } 1108de164aaaSGreg Clayton 1109de164aaaSGreg Clayton void 1110de164aaaSGreg Clayton OptionParsingStarting () 1111de164aaaSGreg Clayton { 1112de164aaaSGreg Clayton m_help.clear(); 1113de164aaaSGreg Clayton m_syntax.clear(); 1114de164aaaSGreg Clayton } 1115de164aaaSGreg Clayton 1116de164aaaSGreg Clayton const OptionDefinition* 1117de164aaaSGreg Clayton GetDefinitions () 1118de164aaaSGreg Clayton { 1119de164aaaSGreg Clayton return g_option_table; 1120de164aaaSGreg Clayton } 1121de164aaaSGreg Clayton 1122de164aaaSGreg Clayton // Options table: Required for subclasses of Options. 1123de164aaaSGreg Clayton 1124de164aaaSGreg Clayton static OptionDefinition g_option_table[]; 1125de164aaaSGreg Clayton 1126de164aaaSGreg Clayton const char * 1127de164aaaSGreg Clayton GetHelp () 1128de164aaaSGreg Clayton { 1129de164aaaSGreg Clayton if (m_help.empty()) 1130de164aaaSGreg Clayton return NULL; 1131de164aaaSGreg Clayton return m_help.c_str(); 1132de164aaaSGreg Clayton } 1133de164aaaSGreg Clayton const char * 1134de164aaaSGreg Clayton GetSyntax () 1135de164aaaSGreg Clayton { 1136de164aaaSGreg Clayton if (m_syntax.empty()) 1137de164aaaSGreg Clayton return NULL; 1138de164aaaSGreg Clayton return m_syntax.c_str(); 1139de164aaaSGreg Clayton } 1140de164aaaSGreg Clayton // Instance variables to hold the values for command options. 1141de164aaaSGreg Clayton protected: 1142de164aaaSGreg Clayton std::string m_help; 1143de164aaaSGreg Clayton std::string m_syntax; 1144de164aaaSGreg Clayton }; 1145de164aaaSGreg Clayton 1146de164aaaSGreg Clayton virtual Options * 1147de164aaaSGreg Clayton GetOptions () 1148de164aaaSGreg Clayton { 1149de164aaaSGreg Clayton return &m_options; 1150de164aaaSGreg Clayton } 1151de164aaaSGreg Clayton 11525a988416SJim Ingham CommandOptions m_options; 1153de164aaaSGreg Clayton }; 1154de164aaaSGreg Clayton 1155de164aaaSGreg Clayton OptionDefinition 1156de164aaaSGreg Clayton CommandObjectCommandsAddRegex::CommandOptions::g_option_table[] = 1157de164aaaSGreg Clayton { 1158de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "help" , 'h', required_argument, NULL, 0, eArgTypeNone, "The help text to display for this command."}, 1159de164aaaSGreg Clayton { LLDB_OPT_SET_1, false, "syntax", 's', required_argument, NULL, 0, eArgTypeNone, "A syntax string showing the typical usage syntax."}, 1160de164aaaSGreg Clayton { 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone, NULL } 1161de164aaaSGreg Clayton }; 1162de164aaaSGreg Clayton 1163de164aaaSGreg Clayton 11645a988416SJim Ingham class CommandObjectPythonFunction : public CommandObjectRaw 1165223383edSEnrico Granata { 1166223383edSEnrico Granata private: 1167223383edSEnrico Granata std::string m_function_name; 11680a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchro; 1169fac939e9SEnrico Granata bool m_fetched_help_long; 1170223383edSEnrico Granata 1171223383edSEnrico Granata public: 1172223383edSEnrico Granata 1173223383edSEnrico Granata CommandObjectPythonFunction (CommandInterpreter &interpreter, 1174223383edSEnrico Granata std::string name, 11750a305db7SEnrico Granata std::string funct, 11760a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 11775a988416SJim Ingham CommandObjectRaw (interpreter, 1178223383edSEnrico Granata name.c_str(), 1179223383edSEnrico Granata (std::string("Run Python function ") + funct).c_str(), 1180223383edSEnrico Granata NULL), 11810a305db7SEnrico Granata m_function_name(funct), 1182fac939e9SEnrico Granata m_synchro(synch), 1183fac939e9SEnrico Granata m_fetched_help_long(false) 1184223383edSEnrico Granata { 1185223383edSEnrico Granata } 1186223383edSEnrico Granata 1187223383edSEnrico Granata virtual 1188223383edSEnrico Granata ~CommandObjectPythonFunction () 1189223383edSEnrico Granata { 1190223383edSEnrico Granata } 1191223383edSEnrico Granata 1192223383edSEnrico Granata virtual bool 11933a18e319SGreg Clayton IsRemovable () const 11945a988416SJim Ingham { 11955a988416SJim Ingham return true; 11965a988416SJim Ingham } 11975a988416SJim Ingham 11985a988416SJim Ingham const std::string& 11995a988416SJim Ingham GetFunctionName () 12005a988416SJim Ingham { 12015a988416SJim Ingham return m_function_name; 12025a988416SJim Ingham } 12035a988416SJim Ingham 12045a988416SJim Ingham ScriptedCommandSynchronicity 12055a988416SJim Ingham GetSynchronicity () 12065a988416SJim Ingham { 12075a988416SJim Ingham return m_synchro; 12085a988416SJim Ingham } 12095a988416SJim Ingham 1210fac939e9SEnrico Granata virtual const char * 1211fac939e9SEnrico Granata GetHelpLong () 1212fac939e9SEnrico Granata { 1213fac939e9SEnrico Granata if (!m_fetched_help_long) 1214fac939e9SEnrico Granata { 1215fac939e9SEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1216fac939e9SEnrico Granata if (scripter) 1217fac939e9SEnrico Granata { 1218fac939e9SEnrico Granata std::string docstring; 1219fac939e9SEnrico Granata m_fetched_help_long = scripter->GetDocumentationForItem(m_function_name.c_str(),docstring); 1220fac939e9SEnrico Granata if (!docstring.empty()) 1221fac939e9SEnrico Granata SetHelpLong(docstring); 1222fac939e9SEnrico Granata } 1223fac939e9SEnrico Granata } 1224fac939e9SEnrico Granata return CommandObjectRaw::GetHelpLong(); 1225fac939e9SEnrico Granata } 1226fac939e9SEnrico Granata 12275a988416SJim Ingham protected: 12285a988416SJim Ingham virtual bool 12295a988416SJim Ingham DoExecute (const char *raw_command_line, CommandReturnObject &result) 1230223383edSEnrico Granata { 1231223383edSEnrico Granata ScriptInterpreter* scripter = m_interpreter.GetScriptInterpreter(); 1232223383edSEnrico Granata 1233223383edSEnrico Granata Error error; 1234223383edSEnrico Granata 123570f11f88SJim Ingham result.SetStatus(eReturnStatusInvalid); 123670f11f88SJim Ingham 1237223383edSEnrico Granata if (!scripter || scripter->RunScriptBasedCommand(m_function_name.c_str(), 1238223383edSEnrico Granata raw_command_line, 12390a305db7SEnrico Granata m_synchro, 1240223383edSEnrico Granata result, 1241223383edSEnrico Granata error) == false) 1242223383edSEnrico Granata { 1243223383edSEnrico Granata result.AppendError(error.AsCString()); 1244223383edSEnrico Granata result.SetStatus(eReturnStatusFailed); 1245223383edSEnrico Granata } 1246223383edSEnrico Granata else 124770f11f88SJim Ingham { 124870f11f88SJim Ingham // Don't change the status if the command already set it... 124970f11f88SJim Ingham if (result.GetStatus() == eReturnStatusInvalid) 125070f11f88SJim Ingham { 125170f11f88SJim Ingham if (result.GetOutputData() == NULL || result.GetOutputData()[0] == '\0') 1252223383edSEnrico Granata result.SetStatus(eReturnStatusSuccessFinishNoResult); 125370f11f88SJim Ingham else 125470f11f88SJim Ingham result.SetStatus(eReturnStatusSuccessFinishResult); 125570f11f88SJim Ingham } 125670f11f88SJim Ingham } 1257223383edSEnrico Granata 1258223383edSEnrico Granata return result.Succeeded(); 1259223383edSEnrico Granata } 1260223383edSEnrico Granata 1261223383edSEnrico Granata }; 1262223383edSEnrico Granata 1263a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1264a9dbf432SEnrico Granata // CommandObjectCommandsScriptImport 1265a9dbf432SEnrico Granata //------------------------------------------------------------------------- 1266a9dbf432SEnrico Granata 12675a988416SJim Ingham class CommandObjectCommandsScriptImport : public CommandObjectParsed 1268a9dbf432SEnrico Granata { 12695a988416SJim Ingham public: 12705a988416SJim Ingham CommandObjectCommandsScriptImport (CommandInterpreter &interpreter) : 12715a988416SJim Ingham CommandObjectParsed (interpreter, 12725a988416SJim Ingham "command script import", 12735a988416SJim Ingham "Import a scripting module in LLDB.", 12745a988416SJim Ingham NULL), 12755a988416SJim Ingham m_options(interpreter) 12765a988416SJim Ingham { 12775a988416SJim Ingham CommandArgumentEntry arg1; 12785a988416SJim Ingham CommandArgumentData cmd_arg; 12795a988416SJim Ingham 12805a988416SJim Ingham // Define the first (and only) variant of this arg. 12815a988416SJim Ingham cmd_arg.arg_type = eArgTypeFilename; 12825a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 12835a988416SJim Ingham 12845a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 12855a988416SJim Ingham arg1.push_back (cmd_arg); 12865a988416SJim Ingham 12875a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 12885a988416SJim Ingham m_arguments.push_back (arg1); 12895a988416SJim Ingham } 12905a988416SJim Ingham 12915a988416SJim Ingham ~CommandObjectCommandsScriptImport () 12925a988416SJim Ingham { 12935a988416SJim Ingham } 12945a988416SJim Ingham 1295c7bece56SGreg Clayton virtual int 12965a988416SJim Ingham HandleArgumentCompletion (Args &input, 12975a988416SJim Ingham int &cursor_index, 12985a988416SJim Ingham int &cursor_char_position, 12995a988416SJim Ingham OptionElementVector &opt_element_vector, 13005a988416SJim Ingham int match_start_point, 13015a988416SJim Ingham int max_return_elements, 13025a988416SJim Ingham bool &word_complete, 13035a988416SJim Ingham StringList &matches) 13045a988416SJim Ingham { 13055a988416SJim Ingham std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 13065a988416SJim Ingham completion_str.erase (cursor_char_position); 13075a988416SJim Ingham 13085a988416SJim Ingham CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 13095a988416SJim Ingham CommandCompletions::eDiskFileCompletion, 13105a988416SJim Ingham completion_str.c_str(), 13115a988416SJim Ingham match_start_point, 13125a988416SJim Ingham max_return_elements, 13135a988416SJim Ingham NULL, 13145a988416SJim Ingham word_complete, 13155a988416SJim Ingham matches); 13165a988416SJim Ingham return matches.GetSize(); 13175a988416SJim Ingham } 13185a988416SJim Ingham 13195a988416SJim Ingham virtual Options * 13205a988416SJim Ingham GetOptions () 13215a988416SJim Ingham { 13225a988416SJim Ingham return &m_options; 13235a988416SJim Ingham } 13245a988416SJim Ingham 13255a988416SJim Ingham protected: 13260a305db7SEnrico Granata 13270a305db7SEnrico Granata class CommandOptions : public Options 13280a305db7SEnrico Granata { 13290a305db7SEnrico Granata public: 13300a305db7SEnrico Granata 13310a305db7SEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 13320a305db7SEnrico Granata Options (interpreter) 13330a305db7SEnrico Granata { 13340a305db7SEnrico Granata } 13350a305db7SEnrico Granata 13360a305db7SEnrico Granata virtual 13370a305db7SEnrico Granata ~CommandOptions (){} 13380a305db7SEnrico Granata 13390a305db7SEnrico Granata virtual Error 13400a305db7SEnrico Granata SetOptionValue (uint32_t option_idx, const char *option_arg) 13410a305db7SEnrico Granata { 13420a305db7SEnrico Granata Error error; 13433bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 13440a305db7SEnrico Granata 13450a305db7SEnrico Granata switch (short_option) 13460a305db7SEnrico Granata { 13470a305db7SEnrico Granata case 'r': 13480a305db7SEnrico Granata m_allow_reload = true; 13490a305db7SEnrico Granata break; 13500a305db7SEnrico Granata default: 13510a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 13520a305db7SEnrico Granata break; 13530a305db7SEnrico Granata } 13540a305db7SEnrico Granata 13550a305db7SEnrico Granata return error; 13560a305db7SEnrico Granata } 13570a305db7SEnrico Granata 13580a305db7SEnrico Granata void 13590a305db7SEnrico Granata OptionParsingStarting () 13600a305db7SEnrico Granata { 1361e0c70f1bSEnrico Granata m_allow_reload = true; 13620a305db7SEnrico Granata } 13630a305db7SEnrico Granata 13640a305db7SEnrico Granata const OptionDefinition* 13650a305db7SEnrico Granata GetDefinitions () 13660a305db7SEnrico Granata { 13670a305db7SEnrico Granata return g_option_table; 13680a305db7SEnrico Granata } 13690a305db7SEnrico Granata 13700a305db7SEnrico Granata // Options table: Required for subclasses of Options. 13710a305db7SEnrico Granata 13720a305db7SEnrico Granata static OptionDefinition g_option_table[]; 13730a305db7SEnrico Granata 13740a305db7SEnrico Granata // Instance variables to hold the values for command options. 13750a305db7SEnrico Granata 13760a305db7SEnrico Granata bool m_allow_reload; 13770a305db7SEnrico Granata }; 13780a305db7SEnrico Granata 1379a9dbf432SEnrico Granata bool 13805a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1381a9dbf432SEnrico Granata { 1382a9dbf432SEnrico Granata 1383a9dbf432SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 1384a9dbf432SEnrico Granata { 1385a9dbf432SEnrico Granata result.AppendError ("only scripting language supported for module importing is currently Python"); 1386a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1387a9dbf432SEnrico Granata return false; 1388a9dbf432SEnrico Granata } 1389a9dbf432SEnrico Granata 13905a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1391a9dbf432SEnrico Granata 1392a9dbf432SEnrico Granata if (argc != 1) 1393a9dbf432SEnrico Granata { 1394a9dbf432SEnrico Granata result.AppendError ("'command script import' requires one argument"); 1395a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1396a9dbf432SEnrico Granata return false; 1397a9dbf432SEnrico Granata } 1398a9dbf432SEnrico Granata 13995a988416SJim Ingham std::string path = command.GetArgumentAtIndex(0); 1400a9dbf432SEnrico Granata Error error; 1401a9dbf432SEnrico Granata 1402c9d645d3SGreg Clayton const bool init_session = true; 1403078551c7SEnrico Granata // FIXME: this is necessary because CommandObject::CheckRequirements() assumes that 1404078551c7SEnrico Granata // commands won't ever be recursively invoked, but it's actually possible to craft 1405078551c7SEnrico Granata // a Python script that does other "command script imports" in __lldb_init_module 1406078551c7SEnrico Granata // the real fix is to have recursive commands possible with a CommandInvocation object 1407078551c7SEnrico Granata // separate from the CommandObject itself, so that recursive command invocations 1408078551c7SEnrico Granata // won't stomp on each other (wrt to execution contents, options, and more) 1409078551c7SEnrico Granata m_exe_ctx.Clear(); 1410a9dbf432SEnrico Granata if (m_interpreter.GetScriptInterpreter()->LoadScriptingModule(path.c_str(), 14110a305db7SEnrico Granata m_options.m_allow_reload, 1412c9d645d3SGreg Clayton init_session, 1413a9dbf432SEnrico Granata error)) 1414a9dbf432SEnrico Granata { 1415a9dbf432SEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1416a9dbf432SEnrico Granata } 1417a9dbf432SEnrico Granata else 1418a9dbf432SEnrico Granata { 1419a9dbf432SEnrico Granata result.AppendErrorWithFormat("module importing failed: %s", error.AsCString()); 1420a9dbf432SEnrico Granata result.SetStatus (eReturnStatusFailed); 1421a9dbf432SEnrico Granata } 1422a9dbf432SEnrico Granata 1423a9dbf432SEnrico Granata return result.Succeeded(); 1424a9dbf432SEnrico Granata } 14250a305db7SEnrico Granata 14265a988416SJim Ingham CommandOptions m_options; 1427a9dbf432SEnrico Granata }; 1428223383edSEnrico Granata 14290a305db7SEnrico Granata OptionDefinition 14300a305db7SEnrico Granata CommandObjectCommandsScriptImport::CommandOptions::g_option_table[] = 14310a305db7SEnrico Granata { 1432e0c70f1bSEnrico 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. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not."}, 14330a305db7SEnrico Granata { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 14340a305db7SEnrico Granata }; 14350a305db7SEnrico Granata 14360a305db7SEnrico Granata 1437223383edSEnrico Granata //------------------------------------------------------------------------- 1438223383edSEnrico Granata // CommandObjectCommandsScriptAdd 1439223383edSEnrico Granata //------------------------------------------------------------------------- 1440223383edSEnrico Granata 14415a988416SJim Ingham class CommandObjectCommandsScriptAdd : public CommandObjectParsed 1442223383edSEnrico Granata { 14435a988416SJim Ingham public: 14445a988416SJim Ingham CommandObjectCommandsScriptAdd(CommandInterpreter &interpreter) : 14455a988416SJim Ingham CommandObjectParsed (interpreter, 14465a988416SJim Ingham "command script add", 14475a988416SJim Ingham "Add a scripted function as an LLDB command.", 14485a988416SJim Ingham NULL), 14495a988416SJim Ingham m_options (interpreter) 14505a988416SJim Ingham { 14515a988416SJim Ingham CommandArgumentEntry arg1; 14525a988416SJim Ingham CommandArgumentData cmd_arg; 14535a988416SJim Ingham 14545a988416SJim Ingham // Define the first (and only) variant of this arg. 14555a988416SJim Ingham cmd_arg.arg_type = eArgTypeCommandName; 14565a988416SJim Ingham cmd_arg.arg_repetition = eArgRepeatPlain; 14575a988416SJim Ingham 14585a988416SJim Ingham // There is only one variant this argument could be; put it into the argument entry. 14595a988416SJim Ingham arg1.push_back (cmd_arg); 14605a988416SJim Ingham 14615a988416SJim Ingham // Push the data for the first argument into the m_arguments vector. 14625a988416SJim Ingham m_arguments.push_back (arg1); 14635a988416SJim Ingham } 14645a988416SJim Ingham 14655a988416SJim Ingham ~CommandObjectCommandsScriptAdd () 14665a988416SJim Ingham { 14675a988416SJim Ingham } 14685a988416SJim Ingham 14695a988416SJim Ingham virtual Options * 14705a988416SJim Ingham GetOptions () 14715a988416SJim Ingham { 14725a988416SJim Ingham return &m_options; 14735a988416SJim Ingham } 14745a988416SJim Ingham 14755a988416SJim Ingham protected: 1476223383edSEnrico Granata 1477223383edSEnrico Granata class CommandOptions : public Options 1478223383edSEnrico Granata { 1479223383edSEnrico Granata public: 1480223383edSEnrico Granata 1481223383edSEnrico Granata CommandOptions (CommandInterpreter &interpreter) : 1482223383edSEnrico Granata Options (interpreter) 1483223383edSEnrico Granata { 1484223383edSEnrico Granata } 1485223383edSEnrico Granata 1486223383edSEnrico Granata virtual 1487223383edSEnrico Granata ~CommandOptions (){} 1488223383edSEnrico Granata 1489223383edSEnrico Granata virtual Error 1490223383edSEnrico Granata SetOptionValue (uint32_t option_idx, const char *option_arg) 1491223383edSEnrico Granata { 1492223383edSEnrico Granata Error error; 14933bcdfc0eSGreg Clayton const int short_option = m_getopt_table[option_idx].val; 1494223383edSEnrico Granata 1495223383edSEnrico Granata switch (short_option) 1496223383edSEnrico Granata { 1497223383edSEnrico Granata case 'f': 1498223383edSEnrico Granata m_funct_name = std::string(option_arg); 1499223383edSEnrico Granata break; 15000a305db7SEnrico Granata case 's': 15010a305db7SEnrico Granata m_synchronous = (ScriptedCommandSynchronicity) Args::StringToOptionEnum(option_arg, g_option_table[option_idx].enum_values, 0, error); 15020a305db7SEnrico Granata if (!error.Success()) 15030a305db7SEnrico Granata error.SetErrorStringWithFormat ("unrecognized value for synchronicity '%s'", option_arg); 15040a305db7SEnrico Granata break; 1505223383edSEnrico Granata default: 150686edbf41SGreg Clayton error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); 1507223383edSEnrico Granata break; 1508223383edSEnrico Granata } 1509223383edSEnrico Granata 1510223383edSEnrico Granata return error; 1511223383edSEnrico Granata } 1512223383edSEnrico Granata 1513223383edSEnrico Granata void 1514223383edSEnrico Granata OptionParsingStarting () 1515223383edSEnrico Granata { 1516223383edSEnrico Granata m_funct_name = ""; 15170a305db7SEnrico Granata m_synchronous = eScriptedCommandSynchronicitySynchronous; 1518223383edSEnrico Granata } 1519223383edSEnrico Granata 1520223383edSEnrico Granata const OptionDefinition* 1521223383edSEnrico Granata GetDefinitions () 1522223383edSEnrico Granata { 1523223383edSEnrico Granata return g_option_table; 1524223383edSEnrico Granata } 1525223383edSEnrico Granata 1526223383edSEnrico Granata // Options table: Required for subclasses of Options. 1527223383edSEnrico Granata 1528223383edSEnrico Granata static OptionDefinition g_option_table[]; 1529223383edSEnrico Granata 1530223383edSEnrico Granata // Instance variables to hold the values for command options. 1531223383edSEnrico Granata 1532223383edSEnrico Granata std::string m_funct_name; 15330a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchronous; 1534223383edSEnrico Granata }; 1535223383edSEnrico Granata 15365a988416SJim Ingham private: 1537223383edSEnrico Granata class PythonAliasReader : public InputReaderEZ 1538223383edSEnrico Granata { 1539223383edSEnrico Granata private: 1540223383edSEnrico Granata CommandInterpreter& m_interpreter; 1541223383edSEnrico Granata std::string m_cmd_name; 15420a305db7SEnrico Granata ScriptedCommandSynchronicity m_synchronous; 1543223383edSEnrico Granata StringList m_user_input; 1544223383edSEnrico Granata DISALLOW_COPY_AND_ASSIGN (PythonAliasReader); 1545223383edSEnrico Granata public: 1546223383edSEnrico Granata PythonAliasReader(Debugger& debugger, 1547223383edSEnrico Granata CommandInterpreter& interpreter, 15480a305db7SEnrico Granata std::string cmd_name, 15490a305db7SEnrico Granata ScriptedCommandSynchronicity synch) : 1550223383edSEnrico Granata InputReaderEZ(debugger), 1551223383edSEnrico Granata m_interpreter(interpreter), 1552223383edSEnrico Granata m_cmd_name(cmd_name), 15530a305db7SEnrico Granata m_synchronous(synch), 1554223383edSEnrico Granata m_user_input() 1555223383edSEnrico Granata {} 1556223383edSEnrico Granata 1557223383edSEnrico Granata virtual 1558223383edSEnrico Granata ~PythonAliasReader() 1559223383edSEnrico Granata { 1560223383edSEnrico Granata } 1561223383edSEnrico Granata 1562223383edSEnrico Granata virtual void ActivateHandler(HandlerData& data) 1563223383edSEnrico Granata { 1564223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1565223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1566223383edSEnrico Granata if (!batch_mode) 1567223383edSEnrico Granata { 1568223383edSEnrico Granata out_stream->Printf ("%s\n", g_python_command_instructions); 1569223383edSEnrico Granata if (data.reader.GetPrompt()) 1570223383edSEnrico Granata out_stream->Printf ("%s", data.reader.GetPrompt()); 1571223383edSEnrico Granata out_stream->Flush(); 1572223383edSEnrico Granata } 1573223383edSEnrico Granata } 1574223383edSEnrico Granata 1575223383edSEnrico Granata virtual void ReactivateHandler(HandlerData& data) 1576223383edSEnrico Granata { 1577223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1578223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1579223383edSEnrico Granata if (data.reader.GetPrompt() && !batch_mode) 1580223383edSEnrico Granata { 1581223383edSEnrico Granata out_stream->Printf ("%s", data.reader.GetPrompt()); 1582223383edSEnrico Granata out_stream->Flush(); 1583223383edSEnrico Granata } 1584223383edSEnrico Granata } 1585223383edSEnrico Granata virtual void GotTokenHandler(HandlerData& data) 1586223383edSEnrico Granata { 1587223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1588223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1589223383edSEnrico Granata if (data.bytes && data.bytes_len) 1590223383edSEnrico Granata { 1591223383edSEnrico Granata m_user_input.AppendString(data.bytes, data.bytes_len); 1592223383edSEnrico Granata } 1593223383edSEnrico Granata if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode) 1594223383edSEnrico Granata { 1595223383edSEnrico Granata out_stream->Printf ("%s", data.reader.GetPrompt()); 1596223383edSEnrico Granata out_stream->Flush(); 1597223383edSEnrico Granata } 1598223383edSEnrico Granata } 1599223383edSEnrico Granata virtual void InterruptHandler(HandlerData& data) 1600223383edSEnrico Granata { 1601223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1602223383edSEnrico Granata bool batch_mode = data.GetBatchMode(); 1603223383edSEnrico Granata data.reader.SetIsDone (true); 1604223383edSEnrico Granata if (!batch_mode) 1605223383edSEnrico Granata { 16060a305db7SEnrico Granata out_stream->Printf ("Warning: No script attached.\n"); 1607223383edSEnrico Granata out_stream->Flush(); 1608223383edSEnrico Granata } 1609223383edSEnrico Granata } 1610223383edSEnrico Granata virtual void EOFHandler(HandlerData& data) 1611223383edSEnrico Granata { 1612223383edSEnrico Granata data.reader.SetIsDone (true); 1613223383edSEnrico Granata } 1614223383edSEnrico Granata virtual void DoneHandler(HandlerData& data) 1615223383edSEnrico Granata { 1616223383edSEnrico Granata StreamSP out_stream = data.GetOutStream(); 1617223383edSEnrico Granata 1618223383edSEnrico Granata ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter(); 1619223383edSEnrico Granata if (!interpreter) 1620223383edSEnrico Granata { 16210a305db7SEnrico Granata out_stream->Printf ("Script interpreter missing: no script attached.\n"); 1622223383edSEnrico Granata out_stream->Flush(); 1623223383edSEnrico Granata return; 1624223383edSEnrico Granata } 1625a73b7df7SEnrico Granata std::string funct_name_str; 1626223383edSEnrico Granata if (!interpreter->GenerateScriptAliasFunction (m_user_input, 1627a73b7df7SEnrico Granata funct_name_str)) 1628223383edSEnrico Granata { 16290a305db7SEnrico Granata out_stream->Printf ("Unable to create function: no script attached.\n"); 1630223383edSEnrico Granata out_stream->Flush(); 1631223383edSEnrico Granata return; 1632223383edSEnrico Granata } 1633a73b7df7SEnrico Granata if (funct_name_str.empty()) 1634223383edSEnrico Granata { 16350a305db7SEnrico Granata out_stream->Printf ("Unable to obtain a function name: no script attached.\n"); 1636223383edSEnrico Granata out_stream->Flush(); 1637223383edSEnrico Granata return; 1638223383edSEnrico Granata } 1639223383edSEnrico Granata // everything should be fine now, let's add this alias 1640223383edSEnrico Granata 1641223383edSEnrico Granata CommandObjectSP command_obj_sp(new CommandObjectPythonFunction(m_interpreter, 1642223383edSEnrico Granata m_cmd_name, 1643a73b7df7SEnrico Granata funct_name_str.c_str(), 16440a305db7SEnrico Granata m_synchronous)); 1645223383edSEnrico Granata 16460a305db7SEnrico Granata if (!m_interpreter.AddUserCommand(m_cmd_name, command_obj_sp, true)) 1647223383edSEnrico Granata { 16480a305db7SEnrico Granata out_stream->Printf ("Unable to add selected command: no script attached.\n"); 1649223383edSEnrico Granata out_stream->Flush(); 1650223383edSEnrico Granata return; 1651223383edSEnrico Granata } 1652223383edSEnrico Granata } 1653223383edSEnrico Granata }; 1654223383edSEnrico Granata 16555a988416SJim Ingham protected: 1656223383edSEnrico Granata bool 16575a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1658223383edSEnrico Granata { 165999f0b8f9SEnrico Granata 166099f0b8f9SEnrico Granata if (m_interpreter.GetDebugger().GetScriptLanguage() != lldb::eScriptLanguagePython) 166199f0b8f9SEnrico Granata { 166299f0b8f9SEnrico Granata result.AppendError ("only scripting language supported for scripted commands is currently Python"); 166399f0b8f9SEnrico Granata result.SetStatus (eReturnStatusFailed); 166499f0b8f9SEnrico Granata return false; 166599f0b8f9SEnrico Granata } 166699f0b8f9SEnrico Granata 16675a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1668223383edSEnrico Granata 1669223383edSEnrico Granata if (argc != 1) 1670223383edSEnrico Granata { 1671223383edSEnrico Granata result.AppendError ("'command script add' requires one argument"); 1672223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1673223383edSEnrico Granata return false; 1674223383edSEnrico Granata } 1675223383edSEnrico Granata 16765a988416SJim Ingham std::string cmd_name = command.GetArgumentAtIndex(0); 1677223383edSEnrico Granata 1678223383edSEnrico Granata if (m_options.m_funct_name.empty()) 1679223383edSEnrico Granata { 1680223383edSEnrico Granata InputReaderSP reader_sp (new PythonAliasReader (m_interpreter.GetDebugger(), 1681223383edSEnrico Granata m_interpreter, 16820a305db7SEnrico Granata cmd_name, 16830a305db7SEnrico Granata m_options.m_synchronous)); 1684223383edSEnrico Granata 1685223383edSEnrico Granata if (reader_sp) 1686223383edSEnrico Granata { 1687223383edSEnrico Granata 1688223383edSEnrico Granata InputReaderEZ::InitializationParameters ipr; 1689223383edSEnrico Granata 1690223383edSEnrico Granata Error err (reader_sp->Initialize (ipr.SetBaton(NULL).SetPrompt(" "))); 1691223383edSEnrico Granata if (err.Success()) 1692223383edSEnrico Granata { 1693223383edSEnrico Granata m_interpreter.GetDebugger().PushInputReader (reader_sp); 1694223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1695223383edSEnrico Granata } 1696223383edSEnrico Granata else 1697223383edSEnrico Granata { 1698223383edSEnrico Granata result.AppendError (err.AsCString()); 1699223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1700223383edSEnrico Granata } 1701223383edSEnrico Granata } 1702223383edSEnrico Granata else 1703223383edSEnrico Granata { 1704223383edSEnrico Granata result.AppendError("out of memory"); 1705223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1706223383edSEnrico Granata } 1707223383edSEnrico Granata } 1708223383edSEnrico Granata else 1709223383edSEnrico Granata { 17100a305db7SEnrico Granata CommandObjectSP new_cmd(new CommandObjectPythonFunction(m_interpreter, 17110a305db7SEnrico Granata cmd_name, 17120a305db7SEnrico Granata m_options.m_funct_name, 17130a305db7SEnrico Granata m_options.m_synchronous)); 17140a305db7SEnrico Granata if (m_interpreter.AddUserCommand(cmd_name, new_cmd, true)) 1715223383edSEnrico Granata { 1716223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishNoResult); 1717223383edSEnrico Granata } 1718223383edSEnrico Granata else 1719223383edSEnrico Granata { 1720223383edSEnrico Granata result.AppendError("cannot add command"); 1721223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1722223383edSEnrico Granata } 1723223383edSEnrico Granata } 1724223383edSEnrico Granata 1725223383edSEnrico Granata return result.Succeeded(); 1726223383edSEnrico Granata 1727223383edSEnrico Granata } 17285a988416SJim Ingham 17295a988416SJim Ingham CommandOptions m_options; 1730223383edSEnrico Granata }; 1731223383edSEnrico Granata 17320a305db7SEnrico Granata static OptionEnumValueElement g_script_synchro_type[] = 17330a305db7SEnrico Granata { 17340a305db7SEnrico Granata { eScriptedCommandSynchronicitySynchronous, "synchronous", "Run synchronous"}, 17350a305db7SEnrico Granata { eScriptedCommandSynchronicityAsynchronous, "asynchronous", "Run asynchronous"}, 17360a305db7SEnrico Granata { eScriptedCommandSynchronicityCurrentValue, "current", "Do not alter current setting"}, 17370a305db7SEnrico Granata { 0, NULL, NULL } 17380a305db7SEnrico Granata }; 17390a305db7SEnrico Granata 1740223383edSEnrico Granata OptionDefinition 1741223383edSEnrico Granata CommandObjectCommandsScriptAdd::CommandOptions::g_option_table[] = 1742223383edSEnrico Granata { 17439128ee2fSEnrico Granata { LLDB_OPT_SET_1, false, "function", 'f', required_argument, NULL, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name."}, 17440a305db7SEnrico 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."}, 1745223383edSEnrico Granata { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1746223383edSEnrico Granata }; 1747223383edSEnrico Granata 1748223383edSEnrico Granata //------------------------------------------------------------------------- 1749223383edSEnrico Granata // CommandObjectCommandsScriptList 1750223383edSEnrico Granata //------------------------------------------------------------------------- 1751223383edSEnrico Granata 17525a988416SJim Ingham class CommandObjectCommandsScriptList : public CommandObjectParsed 1753223383edSEnrico Granata { 1754223383edSEnrico Granata private: 1755223383edSEnrico Granata 1756223383edSEnrico Granata public: 1757223383edSEnrico Granata CommandObjectCommandsScriptList(CommandInterpreter &interpreter) : 17585a988416SJim Ingham CommandObjectParsed (interpreter, 1759223383edSEnrico Granata "command script list", 1760223383edSEnrico Granata "List defined scripted commands.", 1761223383edSEnrico Granata NULL) 1762223383edSEnrico Granata { 1763223383edSEnrico Granata } 1764223383edSEnrico Granata 1765223383edSEnrico Granata ~CommandObjectCommandsScriptList () 1766223383edSEnrico Granata { 1767223383edSEnrico Granata } 1768223383edSEnrico Granata 1769223383edSEnrico Granata bool 17705a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1771223383edSEnrico Granata { 1772223383edSEnrico Granata 1773223383edSEnrico Granata m_interpreter.GetHelp(result, 1774223383edSEnrico Granata CommandInterpreter::eCommandTypesUserDef); 1775223383edSEnrico Granata 1776223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 1777223383edSEnrico Granata 1778223383edSEnrico Granata return true; 1779223383edSEnrico Granata 1780223383edSEnrico Granata 1781223383edSEnrico Granata } 1782223383edSEnrico Granata }; 1783223383edSEnrico Granata 1784223383edSEnrico Granata //------------------------------------------------------------------------- 1785223383edSEnrico Granata // CommandObjectCommandsScriptClear 1786223383edSEnrico Granata //------------------------------------------------------------------------- 1787223383edSEnrico Granata 17885a988416SJim Ingham class CommandObjectCommandsScriptClear : public CommandObjectParsed 1789223383edSEnrico Granata { 1790223383edSEnrico Granata private: 1791223383edSEnrico Granata 1792223383edSEnrico Granata public: 1793223383edSEnrico Granata CommandObjectCommandsScriptClear(CommandInterpreter &interpreter) : 17945a988416SJim Ingham CommandObjectParsed (interpreter, 1795223383edSEnrico Granata "command script clear", 1796223383edSEnrico Granata "Delete all scripted commands.", 1797223383edSEnrico Granata NULL) 1798223383edSEnrico Granata { 1799223383edSEnrico Granata } 1800223383edSEnrico Granata 1801223383edSEnrico Granata ~CommandObjectCommandsScriptClear () 1802223383edSEnrico Granata { 1803223383edSEnrico Granata } 1804223383edSEnrico Granata 18055a988416SJim Ingham protected: 1806223383edSEnrico Granata bool 18075a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1808223383edSEnrico Granata { 1809223383edSEnrico Granata 1810223383edSEnrico Granata m_interpreter.RemoveAllUser(); 1811223383edSEnrico Granata 1812223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 1813223383edSEnrico Granata 1814223383edSEnrico Granata return true; 1815223383edSEnrico Granata } 1816223383edSEnrico Granata }; 1817223383edSEnrico Granata 1818223383edSEnrico Granata //------------------------------------------------------------------------- 1819223383edSEnrico Granata // CommandObjectCommandsScriptDelete 1820223383edSEnrico Granata //------------------------------------------------------------------------- 1821223383edSEnrico Granata 18225a988416SJim Ingham class CommandObjectCommandsScriptDelete : public CommandObjectParsed 1823223383edSEnrico Granata { 1824223383edSEnrico Granata public: 1825223383edSEnrico Granata CommandObjectCommandsScriptDelete(CommandInterpreter &interpreter) : 18265a988416SJim Ingham CommandObjectParsed (interpreter, 1827223383edSEnrico Granata "command script delete", 1828223383edSEnrico Granata "Delete a scripted command.", 1829223383edSEnrico Granata NULL) 1830223383edSEnrico Granata { 1831223383edSEnrico Granata CommandArgumentEntry arg1; 1832223383edSEnrico Granata CommandArgumentData cmd_arg; 1833223383edSEnrico Granata 1834223383edSEnrico Granata // Define the first (and only) variant of this arg. 1835223383edSEnrico Granata cmd_arg.arg_type = eArgTypeCommandName; 1836223383edSEnrico Granata cmd_arg.arg_repetition = eArgRepeatPlain; 1837223383edSEnrico Granata 1838223383edSEnrico Granata // There is only one variant this argument could be; put it into the argument entry. 1839223383edSEnrico Granata arg1.push_back (cmd_arg); 1840223383edSEnrico Granata 1841223383edSEnrico Granata // Push the data for the first argument into the m_arguments vector. 1842223383edSEnrico Granata m_arguments.push_back (arg1); 1843223383edSEnrico Granata } 1844223383edSEnrico Granata 1845223383edSEnrico Granata ~CommandObjectCommandsScriptDelete () 1846223383edSEnrico Granata { 1847223383edSEnrico Granata } 1848223383edSEnrico Granata 18495a988416SJim Ingham protected: 1850223383edSEnrico Granata bool 18515a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 1852223383edSEnrico Granata { 1853223383edSEnrico Granata 18545a988416SJim Ingham size_t argc = command.GetArgumentCount(); 1855223383edSEnrico Granata 1856223383edSEnrico Granata if (argc != 1) 1857223383edSEnrico Granata { 1858223383edSEnrico Granata result.AppendError ("'command script delete' requires one argument"); 1859223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1860223383edSEnrico Granata return false; 1861223383edSEnrico Granata } 1862223383edSEnrico Granata 18635a988416SJim Ingham const char* cmd_name = command.GetArgumentAtIndex(0); 1864223383edSEnrico Granata 1865223383edSEnrico Granata if (cmd_name && *cmd_name && m_interpreter.HasUserCommands() && m_interpreter.UserCommandExists(cmd_name)) 1866223383edSEnrico Granata { 1867223383edSEnrico Granata m_interpreter.RemoveUser(cmd_name); 1868223383edSEnrico Granata result.SetStatus (eReturnStatusSuccessFinishResult); 1869223383edSEnrico Granata } 1870223383edSEnrico Granata else 1871223383edSEnrico Granata { 1872223383edSEnrico Granata result.AppendErrorWithFormat ("command %s not found", cmd_name); 1873223383edSEnrico Granata result.SetStatus (eReturnStatusFailed); 1874223383edSEnrico Granata } 1875223383edSEnrico Granata 1876223383edSEnrico Granata return result.Succeeded(); 1877223383edSEnrico Granata 1878223383edSEnrico Granata } 1879223383edSEnrico Granata }; 1880223383edSEnrico Granata 1881223383edSEnrico Granata #pragma mark CommandObjectMultiwordCommandsScript 1882223383edSEnrico Granata 1883223383edSEnrico Granata //------------------------------------------------------------------------- 1884223383edSEnrico Granata // CommandObjectMultiwordCommandsScript 1885223383edSEnrico Granata //------------------------------------------------------------------------- 1886223383edSEnrico Granata 1887223383edSEnrico Granata class CommandObjectMultiwordCommandsScript : public CommandObjectMultiword 1888223383edSEnrico Granata { 1889223383edSEnrico Granata public: 1890223383edSEnrico Granata CommandObjectMultiwordCommandsScript (CommandInterpreter &interpreter) : 1891223383edSEnrico Granata CommandObjectMultiword (interpreter, 1892223383edSEnrico Granata "command script", 1893223383edSEnrico Granata "A set of commands for managing or customizing script commands.", 1894223383edSEnrico Granata "command script <subcommand> [<subcommand-options>]") 1895223383edSEnrico Granata { 1896223383edSEnrico Granata LoadSubCommand ("add", CommandObjectSP (new CommandObjectCommandsScriptAdd (interpreter))); 1897223383edSEnrico Granata LoadSubCommand ("delete", CommandObjectSP (new CommandObjectCommandsScriptDelete (interpreter))); 1898223383edSEnrico Granata LoadSubCommand ("clear", CommandObjectSP (new CommandObjectCommandsScriptClear (interpreter))); 1899223383edSEnrico Granata LoadSubCommand ("list", CommandObjectSP (new CommandObjectCommandsScriptList (interpreter))); 1900a9dbf432SEnrico Granata LoadSubCommand ("import", CommandObjectSP (new CommandObjectCommandsScriptImport (interpreter))); 1901223383edSEnrico Granata } 1902223383edSEnrico Granata 1903223383edSEnrico Granata ~CommandObjectMultiwordCommandsScript () 1904223383edSEnrico Granata { 1905223383edSEnrico Granata } 1906223383edSEnrico Granata 1907223383edSEnrico Granata }; 1908223383edSEnrico Granata 1909223383edSEnrico Granata 1910ebc09c36SJim Ingham #pragma mark CommandObjectMultiwordCommands 1911ebc09c36SJim Ingham 1912ebc09c36SJim Ingham //------------------------------------------------------------------------- 1913ebc09c36SJim Ingham // CommandObjectMultiwordCommands 1914ebc09c36SJim Ingham //------------------------------------------------------------------------- 1915ebc09c36SJim Ingham 1916ebc09c36SJim Ingham CommandObjectMultiwordCommands::CommandObjectMultiwordCommands (CommandInterpreter &interpreter) : 1917a7015092SGreg Clayton CommandObjectMultiword (interpreter, 19180e5e5a79SGreg Clayton "command", 19193f4c09c1SCaroline Tice "A set of commands for managing or customizing the debugger commands.", 19200e5e5a79SGreg Clayton "command <subcommand> [<subcommand-options>]") 1921ebc09c36SJim Ingham { 1922a7015092SGreg Clayton LoadSubCommand ("source", CommandObjectSP (new CommandObjectCommandsSource (interpreter))); 1923a7015092SGreg Clayton LoadSubCommand ("alias", CommandObjectSP (new CommandObjectCommandsAlias (interpreter))); 1924a7015092SGreg Clayton LoadSubCommand ("unalias", CommandObjectSP (new CommandObjectCommandsUnalias (interpreter))); 1925de164aaaSGreg Clayton LoadSubCommand ("regex", CommandObjectSP (new CommandObjectCommandsAddRegex (interpreter))); 1926a5a97ebeSJim Ingham LoadSubCommand ("history", CommandObjectSP (new CommandObjectCommandsHistory (interpreter))); 1927223383edSEnrico Granata LoadSubCommand ("script", CommandObjectSP (new CommandObjectMultiwordCommandsScript (interpreter))); 1928ebc09c36SJim Ingham } 1929ebc09c36SJim Ingham 1930ebc09c36SJim Ingham CommandObjectMultiwordCommands::~CommandObjectMultiwordCommands () 1931ebc09c36SJim Ingham { 1932ebc09c36SJim Ingham } 1933ebc09c36SJim Ingham 1934