diff options
Diffstat (limited to 'source/Interpreter')
-rw-r--r-- | source/Interpreter/Args.cpp | 96 | ||||
-rw-r--r-- | source/Interpreter/CommandHistory.cpp | 8 | ||||
-rw-r--r-- | source/Interpreter/CommandInterpreter.cpp | 166 | ||||
-rw-r--r-- | source/Interpreter/CommandObjectRegexCommand.cpp | 2 | ||||
-rw-r--r-- | source/Interpreter/OptionGroupPlatform.cpp | 35 | ||||
-rw-r--r-- | source/Interpreter/OptionGroupValueObjectDisplay.cpp | 7 | ||||
-rw-r--r-- | source/Interpreter/OptionValue.cpp | 45 | ||||
-rw-r--r-- | source/Interpreter/OptionValueArray.cpp | 9 | ||||
-rw-r--r-- | source/Interpreter/OptionValueFileSpecLIst.cpp | 7 | ||||
-rw-r--r-- | source/Interpreter/OptionValueFormatEntity.cpp | 124 | ||||
-rw-r--r-- | source/Interpreter/OptionValuePathMappings.cpp | 7 | ||||
-rw-r--r-- | source/Interpreter/OptionValueProperties.cpp | 12 | ||||
-rw-r--r-- | source/Interpreter/OptionValueRegex.cpp | 4 | ||||
-rw-r--r-- | source/Interpreter/OptionValueSInt64.cpp | 4 | ||||
-rw-r--r-- | source/Interpreter/OptionValueUInt64.cpp | 4 | ||||
-rw-r--r-- | source/Interpreter/Property.cpp | 41 | ||||
-rw-r--r-- | source/Interpreter/ScriptInterpreterPython.cpp | 59 |
17 files changed, 395 insertions, 235 deletions
diff --git a/source/Interpreter/Args.cpp b/source/Interpreter/Args.cpp index 9393380..4f0219f 100644 --- a/source/Interpreter/Args.cpp +++ b/source/Interpreter/Args.cpp @@ -19,14 +19,13 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" #include "lldb/DataFormatters/FormatManager.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Options.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Process.h" -//#include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" -//#include "lldb/Target/Thread.h" using namespace lldb; using namespace lldb_private; @@ -166,7 +165,7 @@ Args::SetCommandString (const char *command) if (command && command[0]) { static const char *k_space_separators = " \t"; - static const char *k_space_separators_with_slash_and_quotes = " \t \\'\""; + static const char *k_escapable_characters = " \t\\'\""; const char *arg_end = nullptr; const char *arg_pos; for (arg_pos = command; @@ -202,7 +201,7 @@ Args::SetCommandString (const char *command) do { - arg_end = ::strcspn (arg_pos, k_space_separators_with_slash_and_quotes) + arg_pos; + arg_end = ::strcspn (arg_pos, k_escapable_characters) + arg_pos; switch (arg_end[0]) { @@ -216,7 +215,6 @@ Args::SetCommandString (const char *command) arg.append (arg_piece_start); arg_complete = true; break; - case '\\': // Backslash character switch (arg_end[1]) @@ -228,22 +226,21 @@ Args::SetCommandString (const char *command) break; default: - if (quote_char == '\0') + // Only consider this two-character sequence an escape sequence if we're unquoted and + // the character after the backslash is a whitelisted escapable character. Otherwise + // leave the character sequence untouched. + if (quote_char == '\0' && (nullptr != strchr(k_escapable_characters, arg_end[1]))) { arg.append (arg_piece_start, arg_end - arg_piece_start); - if (arg_end[1] != '\0') - { - arg.append (arg_end + 1, 1); - arg_pos = arg_end + 2; - arg_piece_start = arg_pos; - } + arg.append (arg_end + 1, 1); + arg_pos = arg_end + 2; + arg_piece_start = arg_pos; } else arg_pos = arg_end + 2; break; } break; - case '"': case '\'': case '`': @@ -722,77 +719,6 @@ Args::Clear () m_args_quote_char.clear(); } -int32_t -Args::StringToSInt32 (const char *s, int32_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = nullptr; - const long sval = ::strtol (s, &end, base); - if (*end == '\0') - { - if (success_ptr) - *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN)); - return (int32_t)sval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -uint32_t -Args::StringToUInt32 (const char *s, uint32_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = nullptr; - const unsigned long uval = ::strtoul (s, &end, base); - if (*end == '\0') - { - if (success_ptr) - *success_ptr = (uval <= UINT32_MAX); - return (uint32_t)uval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - - -int64_t -Args::StringToSInt64 (const char *s, int64_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = nullptr; - int64_t uval = ::strtoll (s, &end, base); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - -uint64_t -Args::StringToUInt64 (const char *s, uint64_t fail_value, int base, bool *success_ptr) -{ - if (s && s[0]) - { - char *end = nullptr; - uint64_t uval = ::strtoull (s, &end, base); - if (*end == '\0') - { - if (success_ptr) *success_ptr = true; - return uval; // All characters were used, return the result - } - } - if (success_ptr) *success_ptr = false; - return fail_value; -} - lldb::addr_t Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::addr_t fail_value, Error *error_ptr) { @@ -878,7 +804,7 @@ Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::add if (regex_match.GetMatchAtIndex(s, 3, str)) { - offset = Args::StringToUInt64(str.c_str(), 0, 0, &success); + offset = StringConvert::ToUInt64(str.c_str(), 0, 0, &success); if (success) { diff --git a/source/Interpreter/CommandHistory.cpp b/source/Interpreter/CommandHistory.cpp index 26996a6..bbe64b4 100644 --- a/source/Interpreter/CommandHistory.cpp +++ b/source/Interpreter/CommandHistory.cpp @@ -7,8 +7,10 @@ // //===----------------------------------------------------------------------===// +#include <inttypes.h> + #include "lldb/Interpreter/CommandHistory.h" -#include "lldb/Interpreter/Args.h" +#include "lldb/Host/StringConvert.h" using namespace lldb; using namespace lldb_private; @@ -47,7 +49,7 @@ CommandHistory::FindString (const char* input_str) const if (input_str[1] == '-') { bool success; - size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success); + size_t idx = StringConvert::ToUInt32 (input_str+2, 0, 0, &success); if (!success) return nullptr; if (idx > m_history.size()) @@ -66,7 +68,7 @@ CommandHistory::FindString (const char* input_str) const else { bool success; - uint32_t idx = Args::StringToUInt32 (input_str+1, 0, 0, &success); + uint32_t idx = StringConvert::ToUInt32 (input_str+1, 0, 0, &success); if (!success) return nullptr; if (idx >= m_history.size()) diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp index 176a1fc..6318b80a 100644 --- a/source/Interpreter/CommandInterpreter.cpp +++ b/source/Interpreter/CommandInterpreter.cpp @@ -1170,17 +1170,25 @@ void CommandInterpreter::GetHelp (CommandReturnObject &result, uint32_t cmd_types) { + const char * help_prologue = GetDebugger().GetIOHandlerHelpPrologue(); + if (help_prologue != NULL) + { + OutputFormattedHelpText(result.GetOutputStream(), NULL, help_prologue); + } + CommandObject::CommandMap::const_iterator pos; size_t max_len = FindLongestCommandWord (m_command_dict); if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin ) { - - result.AppendMessage("The following is a list of built-in, permanent debugger commands:"); + result.AppendMessage("Debugger commands:"); result.AppendMessage(""); for (pos = m_command_dict.begin(); pos != m_command_dict.end(); ++pos) { + if (!(cmd_types & eCommandTypesHidden) && (pos->first.compare(0, 1, "_") == 0)) + continue; + OutputFormattedHelpText (result.GetOutputStream(), pos->first.c_str(), "--", pos->second->GetHelp(), max_len); } @@ -1190,8 +1198,9 @@ CommandInterpreter::GetHelp (CommandReturnObject &result, if (!m_alias_dict.empty() && ( (cmd_types & eCommandTypesAliases) == eCommandTypesAliases )) { - result.AppendMessage("The following is a list of your current command abbreviations " - "(see 'help command alias' for more info):"); + result.AppendMessageWithFormat("Current command abbreviations " + "(type '%shelp command alias' for more info):\n", + GetCommandPrefix()); result.AppendMessage(""); max_len = FindLongestCommandWord (m_alias_dict); @@ -1212,7 +1221,7 @@ CommandInterpreter::GetHelp (CommandReturnObject &result, if (!m_user_dict.empty() && ( (cmd_types & eCommandTypesUserDef) == eCommandTypesUserDef )) { - result.AppendMessage ("The following is a list of your current user-defined commands:"); + result.AppendMessage ("Current user-defined commands:"); result.AppendMessage(""); max_len = FindLongestCommandWord (m_user_dict); for (pos = m_user_dict.begin(); pos != m_user_dict.end(); ++pos) @@ -1223,7 +1232,8 @@ CommandInterpreter::GetHelp (CommandReturnObject &result, result.AppendMessage(""); } - result.AppendMessage("For more information on any particular command, try 'help <command-name>'."); + result.AppendMessageWithFormat("For more information on any command, type '%shelp <command-name>'.\n", + GetCommandPrefix()); } CommandObject * @@ -2496,6 +2506,13 @@ CommandInterpreter::SourceInitFile (bool in_cwd, CommandReturnObject &result) } } +const char * +CommandInterpreter::GetCommandPrefix() +{ + const char * prefix = GetDebugger().GetIOHandlerCommandPrefix(); + return prefix == NULL ? "" : prefix; +} + PlatformSP CommandInterpreter::GetPlatform (bool prefer_target_platform) { @@ -2887,84 +2904,74 @@ CommandInterpreter::SetSynchronous (bool value) void CommandInterpreter::OutputFormattedHelpText (Stream &strm, - const char *word_text, - const char *separator, - const char *help_text, - size_t max_word_len) + const char *prefix, + const char *help_text) { const uint32_t max_columns = m_debugger.GetTerminalWidth(); - - int indent_size = max_word_len + strlen (separator) + 2; - - strm.IndentMore (indent_size); - - StreamString text_strm; - text_strm.Printf ("%-*s %s %s", (int)max_word_len, word_text, separator, help_text); - - size_t len = text_strm.GetSize(); - const char *text = text_strm.GetData(); - if (text[len - 1] == '\n') - { - text_strm.EOL(); - len = text_strm.GetSize(); - } - - if (len < max_columns) - { - // Output it as a single line. - strm.Printf ("%s", text); - } - else - { - // We need to break it up into multiple lines. - bool first_line = true; - int text_width; - size_t start = 0; - size_t end = start; - const size_t final_end = strlen (text); - - while (end < final_end) - { - if (first_line) - text_width = max_columns - 1; - else - text_width = max_columns - indent_size - 1; - - // Don't start the 'text' on a space, since we're already outputting the indentation. - if (!first_line) + if (prefix == NULL) + prefix = ""; + + size_t prefix_width = strlen(prefix); + size_t line_width_max = max_columns - prefix_width; + const char *help_text_end = help_text + strlen(help_text); + const char *line_start = help_text; + if (line_width_max < 16) + line_width_max = help_text_end - help_text + prefix_width; + + strm.IndentMore (prefix_width); + while (line_start < help_text_end) + { + // Break each line at the first newline or last space/tab before + // the maximum number of characters that fit on a line. Lines with no + // natural break are left unbroken to wrap. + const char *line_end = help_text_end; + const char *line_scan = line_start; + const char *line_scan_end = help_text_end; + while (line_scan < line_scan_end) + { + char next = *line_scan; + if (next == '\t' || next == ' ') { - while ((start < final_end) && (text[start] == ' ')) - start++; + line_end = line_scan; + line_scan_end = line_start + line_width_max; } - - end = start + text_width; - if (end > final_end) - end = final_end; - else + else if (next == '\n' || next == '\0') { - // If we're not at the end of the text, make sure we break the line on white space. - while (end > start - && text[end] != ' ' && text[end] != '\t' && text[end] != '\n') - end--; - assert (end > 0); + line_end = line_scan; + break; } - - const size_t sub_len = end - start; - if (start != 0) - strm.EOL(); - if (!first_line) - strm.Indent(); - else - first_line = false; - assert (start <= final_end); - assert (start + sub_len <= final_end); - if (sub_len > 0) - strm.Write (text + start, sub_len); - start = end + 1; + ++line_scan; } + + // Prefix the first line, indent subsequent lines to line up + if (line_start == help_text) + strm.Write (prefix, prefix_width); + else + strm.Indent(); + strm.Write (line_start, line_end - line_start); + strm.EOL(); + + // When a line breaks at whitespace consume it before continuing + line_start = line_end; + char next = *line_start; + if (next == '\n') + ++line_start; + else while (next == ' ' || next == '\t') + next = *(++line_start); } - strm.EOL(); - strm.IndentLess(indent_size); + strm.IndentLess (prefix_width); +} + +void +CommandInterpreter::OutputFormattedHelpText (Stream &strm, + const char *word_text, + const char *separator, + const char *help_text, + size_t max_word_len) +{ + StreamString prefix_stream; + prefix_stream.Printf (" %-*s %s ", (int)max_word_len, word_text, separator); + OutputFormattedHelpText (strm, prefix_stream.GetData(), help_text); } void @@ -3222,6 +3229,13 @@ CommandInterpreter::IOHandlerInterrupt (IOHandler &io_handler) return true; // Don't do any updating when we are running } } + + ScriptInterpreter *script_interpreter = GetScriptInterpreter (false); + if (script_interpreter) + { + if (script_interpreter->Interrupt()) + return true; + } return false; } diff --git a/source/Interpreter/CommandObjectRegexCommand.cpp b/source/Interpreter/CommandObjectRegexCommand.cpp index efc7c33..bde7f58 100644 --- a/source/Interpreter/CommandObjectRegexCommand.cpp +++ b/source/Interpreter/CommandObjectRegexCommand.cpp @@ -111,7 +111,7 @@ CommandObjectRegexCommand::AddRegexCommand (const char *re_cstr, const char *com { m_entries.resize(m_entries.size() + 1); // Only add the regular expression if it compiles - if (m_entries.back().regex.Compile (re_cstr, REG_EXTENDED)) + if (m_entries.back().regex.Compile (re_cstr)) { m_entries.back().command.assign (command_cstr); return true; diff --git a/source/Interpreter/OptionGroupPlatform.cpp b/source/Interpreter/OptionGroupPlatform.cpp index 7e5e124..6bb3655 100644 --- a/source/Interpreter/OptionGroupPlatform.cpp +++ b/source/Interpreter/OptionGroupPlatform.cpp @@ -147,3 +147,38 @@ OptionGroupPlatform::SetOptionValue (CommandInterpreter &interpreter, } return error; } + +bool +OptionGroupPlatform::PlatformMatches(const lldb::PlatformSP &platform_sp) const +{ + if (platform_sp) + { + if (!m_platform_name.empty()) + { + if (platform_sp->GetName() != ConstString(m_platform_name.c_str())) + return false; + } + + if (m_sdk_build && m_sdk_build != platform_sp->GetSDKBuild()) + return false; + + if (m_sdk_sysroot && m_sdk_sysroot != platform_sp->GetSDKRootDirectory()) + return false; + + if (m_os_version_major != UINT32_MAX) + { + uint32_t major, minor, update; + if (platform_sp->GetOSVersion (major, minor, update)) + { + if (m_os_version_major != major) + return false; + if (m_os_version_minor != minor) + return false; + if (m_os_version_update != update) + return false; + } + } + return true; + } + return false; +} diff --git a/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/source/Interpreter/OptionGroupValueObjectDisplay.cpp index b6c63fa..72d7ff5 100644 --- a/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -16,6 +16,7 @@ // Other libraries and framework includes // Project includes #include "lldb/DataFormatters/ValueObjectPrinter.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Target/Target.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Utility/Utils.h" @@ -89,13 +90,13 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter, case 'A': ignore_cap = true; break; case 'D': - max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success); + max_depth = StringConvert::ToUInt32 (option_arg, UINT32_MAX, 0, &success); if (!success) error.SetErrorStringWithFormat("invalid max depth '%s'", option_arg); break; case 'P': - ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success); + ptr_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success); if (!success) error.SetErrorStringWithFormat("invalid pointer depth '%s'", option_arg); break; @@ -103,7 +104,7 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter, case 'Y': if (option_arg) { - no_summary_depth = Args::StringToUInt32 (option_arg, 0, 0, &success); + no_summary_depth = StringConvert::ToUInt32 (option_arg, 0, 0, &success); if (!success) error.SetErrorStringWithFormat("invalid pointer depth '%s'", option_arg); } diff --git a/source/Interpreter/OptionValue.cpp b/source/Interpreter/OptionValue.cpp index a08a612..1e4ea23 100644 --- a/source/Interpreter/OptionValue.cpp +++ b/source/Interpreter/OptionValue.cpp @@ -222,6 +222,22 @@ OptionValue::GetAsFormat () const return nullptr; } +OptionValueFormatEntity * +OptionValue::GetAsFormatEntity () +{ + if (GetType () == OptionValue::eTypeFormatEntity) + return static_cast<OptionValueFormatEntity *>(this); + return nullptr; +} + +const OptionValueFormatEntity * +OptionValue::GetAsFormatEntity () const +{ + if (GetType () == OptionValue::eTypeFormatEntity) + return static_cast<const OptionValueFormatEntity *>(this); + return nullptr; +} + OptionValuePathMappings * OptionValue::GetAsPathMappings () { @@ -452,6 +468,15 @@ OptionValue::SetFormatValue (lldb::Format new_value) return false; } +const FormatEntity::Entry * +OptionValue::GetFormatEntity () const +{ + const OptionValueFormatEntity *option_value = GetAsFormatEntity(); + if (option_value) + return &option_value->GetCurrentValue(); + return nullptr; +} + const RegularExpression * OptionValue::GetRegexValue () const { @@ -563,6 +588,7 @@ OptionValue::GetBuiltinTypeAsCString (Type t) case eTypeFileSpec: return "file"; case eTypeFileSpecList: return "file-list"; case eTypeFormat: return "format"; + case eTypeFormatEntity: return "format-string"; case eTypePathMap: return "path-map"; case eTypeProperties: return "properties"; case eTypeRegex: return "regex"; @@ -583,15 +609,16 @@ OptionValue::CreateValueFromCStringForTypeMask (const char *value_cstr, uint32_t lldb::OptionValueSP value_sp; switch (type_mask) { - case 1u << eTypeArch: value_sp.reset(new OptionValueArch()); break; - case 1u << eTypeBoolean: value_sp.reset(new OptionValueBoolean(false)); break; - case 1u << eTypeChar: value_sp.reset(new OptionValueChar('\0')); break; - case 1u << eTypeFileSpec: value_sp.reset(new OptionValueFileSpec()); break; - case 1u << eTypeFormat: value_sp.reset(new OptionValueFormat(eFormatInvalid)); break; - case 1u << eTypeSInt64: value_sp.reset(new OptionValueSInt64()); break; - case 1u << eTypeString: value_sp.reset(new OptionValueString()); break; - case 1u << eTypeUInt64: value_sp.reset(new OptionValueUInt64()); break; - case 1u << eTypeUUID: value_sp.reset(new OptionValueUUID()); break; + case 1u << eTypeArch: value_sp.reset(new OptionValueArch()); break; + case 1u << eTypeBoolean: value_sp.reset(new OptionValueBoolean(false)); break; + case 1u << eTypeChar: value_sp.reset(new OptionValueChar('\0')); break; + case 1u << eTypeFileSpec: value_sp.reset(new OptionValueFileSpec()); break; + case 1u << eTypeFormat: value_sp.reset(new OptionValueFormat(eFormatInvalid)); break; + case 1u << eTypeFormatEntity: value_sp.reset(new OptionValueFormatEntity(NULL)); break; + case 1u << eTypeSInt64: value_sp.reset(new OptionValueSInt64()); break; + case 1u << eTypeString: value_sp.reset(new OptionValueString()); break; + case 1u << eTypeUInt64: value_sp.reset(new OptionValueUInt64()); break; + case 1u << eTypeUUID: value_sp.reset(new OptionValueUUID()); break; } if (value_sp) diff --git a/source/Interpreter/OptionValueArray.cpp b/source/Interpreter/OptionValueArray.cpp index c0d48c1..86d49c9 100644 --- a/source/Interpreter/OptionValueArray.cpp +++ b/source/Interpreter/OptionValueArray.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Stream.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Args.h" using namespace lldb; @@ -97,7 +98,7 @@ OptionValueArray::GetSubValue (const ExecutionContext *exe_ctx, sub_value = end_bracket + 1; std::string index_str (name+1, end_bracket); const size_t array_count = m_values.size(); - int32_t idx = Args::StringToSInt32(index_str.c_str(), INT32_MAX, 0, nullptr); + int32_t idx = StringConvert::ToSInt32(index_str.c_str(), INT32_MAX, 0, nullptr); if (idx != INT32_MAX) { ; @@ -177,7 +178,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op) case eVarSetOperationInsertAfter: if (argc > 1) { - uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); const uint32_t count = GetSize(); if (idx > count) { @@ -225,7 +226,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op) for (i=0; i<argc; ++i) { const size_t idx = - Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); if (idx >= size) { all_indexes_valid = false; @@ -274,7 +275,7 @@ OptionValueArray::SetArgs (const Args &args, VarSetOperationType op) case eVarSetOperationReplace: if (argc > 1) { - uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); const uint32_t count = GetSize(); if (idx > count) { diff --git a/source/Interpreter/OptionValueFileSpecLIst.cpp b/source/Interpreter/OptionValueFileSpecLIst.cpp index 7150ad4..0e696ca 100644 --- a/source/Interpreter/OptionValueFileSpecLIst.cpp +++ b/source/Interpreter/OptionValueFileSpecLIst.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Stream.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Args.h" using namespace lldb; @@ -57,7 +58,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation case eVarSetOperationReplace: if (argc > 1) { - uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); const uint32_t count = m_current_value.GetSize(); if (idx > count) { @@ -108,7 +109,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation case eVarSetOperationInsertAfter: if (argc > 1) { - uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); const uint32_t count = m_current_value.GetSize(); if (idx > count) { @@ -140,7 +141,7 @@ OptionValueFileSpecList::SetValueFromCString (const char *value, VarSetOperation size_t i; for (i=0; all_indexes_valid && i<argc; ++i) { - const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); if (idx == INT32_MAX) all_indexes_valid = false; else diff --git a/source/Interpreter/OptionValueFormatEntity.cpp b/source/Interpreter/OptionValueFormatEntity.cpp new file mode 100644 index 0000000..fb8c682 --- /dev/null +++ b/source/Interpreter/OptionValueFormatEntity.cpp @@ -0,0 +1,124 @@ +//===-- OptionValueFormatEntity.cpp -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +#include "lldb/Interpreter/OptionValueFormatEntity.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Module.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StringList.h" +#include "lldb/Interpreter/CommandInterpreter.h" +using namespace lldb; +using namespace lldb_private; + + +OptionValueFormatEntity::OptionValueFormatEntity (const char *default_format) : + OptionValue(), + m_current_format (), + m_default_format (), + m_current_entry (), + m_default_entry () +{ + if (default_format && default_format[0]) + { + llvm::StringRef default_format_str(default_format); + Error error = FormatEntity::Parse(default_format_str, m_default_entry); + if (error.Success()) + { + m_default_format = default_format; + m_current_format = default_format; + m_current_entry = m_default_entry; + } + } +} + +bool +OptionValueFormatEntity::Clear () +{ + m_current_entry = m_default_entry; + m_current_format = m_default_format; + m_value_was_set = false; + return true; +} + + +void +OptionValueFormatEntity::DumpValue (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) +{ + if (dump_mask & eDumpOptionType) + strm.Printf ("(%s)", GetTypeAsCString ()); + if (dump_mask & eDumpOptionValue) + { + if (dump_mask & eDumpOptionType) + strm.PutCString (" = \""); + strm << m_current_format.c_str() << '"'; + } +} + +Error +OptionValueFormatEntity::SetValueFromCString (const char *value_cstr, + VarSetOperationType op) +{ + Error error; + switch (op) + { + case eVarSetOperationClear: + Clear(); + NotifyValueChanged(); + break; + + case eVarSetOperationReplace: + case eVarSetOperationAssign: + { + FormatEntity::Entry entry; + llvm::StringRef value_str(value_cstr); + error = FormatEntity::Parse(value_str, entry); + if (error.Success()) + { + m_current_entry = std::move(entry); + m_current_format = value_cstr; + m_value_was_set = true; + NotifyValueChanged(); + } + } + break; + + case eVarSetOperationInsertBefore: + case eVarSetOperationInsertAfter: + case eVarSetOperationRemove: + case eVarSetOperationAppend: + case eVarSetOperationInvalid: + error = OptionValue::SetValueFromCString (value_cstr, op); + break; + } + return error; +} + +lldb::OptionValueSP +OptionValueFormatEntity::DeepCopy () const +{ + return OptionValueSP(new OptionValueFormatEntity(*this)); +} + +size_t +OptionValueFormatEntity::AutoComplete (CommandInterpreter &interpreter, + const char *s, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) +{ + return FormatEntity::AutoComplete (s, match_start_point, max_return_elements, word_complete, matches); +} + diff --git a/source/Interpreter/OptionValuePathMappings.cpp b/source/Interpreter/OptionValuePathMappings.cpp index 56f2ecf..b1e714e 100644 --- a/source/Interpreter/OptionValuePathMappings.cpp +++ b/source/Interpreter/OptionValuePathMappings.cpp @@ -14,6 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Stream.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/Args.h" using namespace lldb; @@ -50,7 +51,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation // Must be at least one index + 1 pair of paths, and the pair count must be even if (argc >= 3 && (((argc - 1) & 1) == 0)) { - uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); const uint32_t count = m_path_mappings.GetSize(); if (idx > count) { @@ -108,7 +109,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation // Must be at least one index + 1 pair of paths, and the pair count must be even if (argc >= 3 && (((argc - 1) & 1) == 0)) { - uint32_t idx = Args::StringToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); + uint32_t idx = StringConvert::ToUInt32(args.GetArgumentAtIndex(0), UINT32_MAX); const uint32_t count = m_path_mappings.GetSize(); if (idx > count) { @@ -141,7 +142,7 @@ OptionValuePathMappings::SetValueFromCString (const char *value, VarSetOperation size_t i; for (i=0; all_indexes_valid && i<argc; ++i) { - const int idx = Args::StringToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); + const int idx = StringConvert::ToSInt32(args.GetArgumentAtIndex(i), INT32_MAX); if (idx == INT32_MAX) all_indexes_valid = false; else diff --git a/source/Interpreter/OptionValueProperties.cpp b/source/Interpreter/OptionValueProperties.cpp index 6ec2aa5..cf7abaa 100644 --- a/source/Interpreter/OptionValueProperties.cpp +++ b/source/Interpreter/OptionValueProperties.cpp @@ -421,6 +421,18 @@ OptionValueProperties::SetPropertyAtIndexAsEnumeration (const ExecutionContext * return false; } +const FormatEntity::Entry * +OptionValueProperties::GetPropertyAtIndexAsFormatEntity (const ExecutionContext *exe_ctx, uint32_t idx) +{ + const Property *property = GetPropertyAtIndex (exe_ctx, true, idx); + if (property) + { + OptionValue *value = property->GetValue().get(); + if (value) + return value->GetFormatEntity(); + } + return nullptr; +} OptionValueFileSpec * OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const diff --git a/source/Interpreter/OptionValueRegex.cpp b/source/Interpreter/OptionValueRegex.cpp index f51cf02..fab462f 100644 --- a/source/Interpreter/OptionValueRegex.cpp +++ b/source/Interpreter/OptionValueRegex.cpp @@ -62,7 +62,7 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr, case eVarSetOperationReplace: case eVarSetOperationAssign: - if (m_regex.Compile (value_cstr, m_regex.GetCompileFlags())) + if (m_regex.Compile (value_cstr)) { m_value_was_set = true; NotifyValueChanged(); @@ -84,5 +84,5 @@ OptionValueRegex::SetValueFromCString (const char *value_cstr, lldb::OptionValueSP OptionValueRegex::DeepCopy () const { - return OptionValueSP(new OptionValueRegex(m_regex.GetText(), m_regex.GetCompileFlags())); + return OptionValueSP(new OptionValueRegex(m_regex.GetText())); } diff --git a/source/Interpreter/OptionValueSInt64.cpp b/source/Interpreter/OptionValueSInt64.cpp index 1827cc1..c691729 100644 --- a/source/Interpreter/OptionValueSInt64.cpp +++ b/source/Interpreter/OptionValueSInt64.cpp @@ -14,7 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Stream.h" -#include "lldb/Interpreter/Args.h" +#include "lldb/Host/StringConvert.h" using namespace lldb; using namespace lldb_private; @@ -51,7 +51,7 @@ OptionValueSInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT case eVarSetOperationAssign: { bool success = false; - int64_t value = Args::StringToSInt64 (value_cstr, 0, 0, &success); + int64_t value = StringConvert::ToSInt64 (value_cstr, 0, 0, &success); if (success) { if (value >= m_min_value && value <= m_max_value) diff --git a/source/Interpreter/OptionValueUInt64.cpp b/source/Interpreter/OptionValueUInt64.cpp index 3e12c03..48de433 100644 --- a/source/Interpreter/OptionValueUInt64.cpp +++ b/source/Interpreter/OptionValueUInt64.cpp @@ -14,7 +14,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Stream.h" -#include "lldb/Interpreter/Args.h" +#include "lldb/Host/StringConvert.h" using namespace lldb; using namespace lldb_private; @@ -58,7 +58,7 @@ OptionValueUInt64::SetValueFromCString (const char *value_cstr, VarSetOperationT case eVarSetOperationAssign: { bool success = false; - uint64_t value = Args::StringToUInt64 (value_cstr, 0, 0, &success); + uint64_t value = StringConvert::ToUInt64 (value_cstr, 0, 0, &success); if (success) { m_value_was_set = true; diff --git a/source/Interpreter/Property.cpp b/source/Interpreter/Property.cpp index 7f7219f..5679ef8 100644 --- a/source/Interpreter/Property.cpp +++ b/source/Interpreter/Property.cpp @@ -16,7 +16,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/UserSettingsController.h" -#include "lldb/Interpreter/Args.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/OptionValues.h" @@ -109,16 +109,21 @@ Property::Property (const PropertyDefinition &definition) : // "definition.default_cstr_value" is NULL, otherwise interpret // "definition.default_cstr_value" as a string value that represents the default // value. - { - Format new_format = eFormatInvalid; - if (definition.default_cstr_value) - Args::StringToFormat (definition.default_cstr_value, new_format, nullptr); - else - new_format = (Format)definition.default_uint_value; - m_value_sp.reset (new OptionValueFormat(new_format)); - } + { + Format new_format = eFormatInvalid; + if (definition.default_cstr_value) + Args::StringToFormat (definition.default_cstr_value, new_format, nullptr); + else + new_format = (Format)definition.default_uint_value; + m_value_sp.reset (new OptionValueFormat(new_format)); + } break; + case OptionValue::eTypeFormatEntity: + // "definition.default_cstr_value" as a string value that represents the default + m_value_sp.reset (new OptionValueFormatEntity(definition.default_cstr_value)); + break; + case OptionValue::eTypePathMap: // "definition.default_uint_value" tells us if notifications should occur for // path mappings @@ -129,7 +134,7 @@ Property::Property (const PropertyDefinition &definition) : // "definition.default_uint_value" is used to the regular expression flags // "definition.default_cstr_value" the default regular expression value // value. - m_value_sp.reset (new OptionValueRegex(definition.default_cstr_value, definition.default_uint_value)); + m_value_sp.reset (new OptionValueRegex(definition.default_cstr_value)); break; case OptionValue::eTypeSInt64: @@ -137,7 +142,7 @@ Property::Property (const PropertyDefinition &definition) : // "definition.default_cstr_value" is NULL, otherwise interpret // "definition.default_cstr_value" as a string value that represents the default // value. - m_value_sp.reset (new OptionValueSInt64(definition.default_cstr_value ? Args::StringToSInt64 (definition.default_cstr_value) : definition.default_uint_value)); + m_value_sp.reset (new OptionValueSInt64(definition.default_cstr_value ? StringConvert::ToSInt64 (definition.default_cstr_value) : definition.default_uint_value)); break; case OptionValue::eTypeUInt64: @@ -145,18 +150,18 @@ Property::Property (const PropertyDefinition &definition) : // "definition.default_cstr_value" is NULL, otherwise interpret // "definition.default_cstr_value" as a string value that represents the default // value. - m_value_sp.reset (new OptionValueUInt64(definition.default_cstr_value ? Args::StringToUInt64 (definition.default_cstr_value) : definition.default_uint_value)); + m_value_sp.reset (new OptionValueUInt64(definition.default_cstr_value ? StringConvert::ToUInt64 (definition.default_cstr_value) : definition.default_uint_value)); break; case OptionValue::eTypeUUID: // "definition.default_uint_value" is not used for a OptionValue::eTypeUUID // "definition.default_cstr_value" can contain a default UUID value - { - UUID uuid; - if (definition.default_cstr_value) - uuid.SetFromCString (definition.default_cstr_value); - m_value_sp.reset (new OptionValueUUID(uuid)); - } + { + UUID uuid; + if (definition.default_cstr_value) + uuid.SetFromCString (definition.default_cstr_value); + m_value_sp.reset (new OptionValueUUID(uuid)); + } break; case OptionValue::eTypeString: diff --git a/source/Interpreter/ScriptInterpreterPython.cpp b/source/Interpreter/ScriptInterpreterPython.cpp index ab15107..8155cbb 100644 --- a/source/Interpreter/ScriptInterpreterPython.cpp +++ b/source/Interpreter/ScriptInterpreterPython.cpp @@ -103,13 +103,14 @@ ScriptInterpreterPython::Locker::DoAcquireLock() m_GILState = PyGILState_Ensure(); if (log) log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : ""); - + // we need to save the thread state when we first start the command // because we might decide to interrupt it while some action is taking // place outside of Python (e.g. printing to screen, waiting for the network, ...) // in that case, _PyThreadState_Current will be NULL - and we would be unable // to set the asynchronous exception - not a desirable situation m_python_interpreter->SetThreadState (_PyThreadState_Current); + m_python_interpreter->IncrementLockCount(); return true; } @@ -128,6 +129,7 @@ ScriptInterpreterPython::Locker::DoFreeLock() if (log) log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : ""); PyGILState_Release(m_GILState); + m_python_interpreter->DecrementLockCount(); return true; } @@ -166,6 +168,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete m_session_is_active (false), m_pty_slave_is_open (false), m_valid_session (true), + m_lock_count (0), m_command_thread_state (nullptr) { @@ -535,7 +538,7 @@ ScriptInterpreterPython::GetSysModuleDictionary () static std::string GenerateUniqueName (const char* base_name_wanted, uint32_t& functions_counter, - void* name_token = nullptr) + const void* name_token = nullptr) { StreamString sstr; @@ -817,24 +820,7 @@ public: virtual bool Interrupt () { - Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT)); - - PyThreadState* state = _PyThreadState_Current; - if (!state) - state = m_python->GetThreadState(); - if (state) - { - long tid = state->thread_id; - _PyThreadState_Current = state; - int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); - if (log) - log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p", - tid, num_threads, static_cast<void *>(state)); - } - else if (log) - log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL"); - - return false; + return m_python->Interrupt(); } virtual void @@ -870,6 +856,31 @@ ScriptInterpreterPython::ExecuteInterpreterLoop () } bool +ScriptInterpreterPython::Interrupt() +{ + Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT)); + + if (IsExecutingPython()) + { + PyThreadState* state = _PyThreadState_Current; + if (!state) + state = GetThreadState(); + if (state) + { + long tid = state->thread_id; + _PyThreadState_Current = state; + int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt); + if (log) + log->Printf("ScriptInterpreterPython::Interrupt() sending PyExc_KeyboardInterrupt (tid = %li, num_threads = %i)...", tid, num_threads); + return true; + } + } + if (log) + log->Printf("ScriptInterpreterPython::Interrupt() python code not running, can't interrupt"); + return false; + +} +bool ScriptInterpreterPython::ExecuteOneLineWithReturn (const char *in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, @@ -1243,7 +1254,7 @@ ScriptInterpreterPython::GenerateFunction(const char *signature, const StringLis } bool -ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, void* name_token) +ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, std::string& output, const void* name_token) { static uint32_t num_created_functions = 0; user_input.RemoveBlankLines (); @@ -1292,7 +1303,7 @@ ScriptInterpreterPython::GenerateScriptAliasFunction (StringList &user_input, st bool -ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, void* name_token) +ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, std::string &output, const void* name_token) { static uint32_t num_created_classes = 0; user_input.RemoveBlankLines (); @@ -1795,7 +1806,7 @@ ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name } bool -ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, void* name_token) +ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std::string& output, const void* name_token) { StringList input; input.SplitIntoLines(oneliner, strlen(oneliner)); @@ -1803,7 +1814,7 @@ ScriptInterpreterPython::GenerateTypeScriptFunction (const char* oneliner, std:: } bool -ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, void* name_token) +ScriptInterpreterPython::GenerateTypeSynthClass (const char* oneliner, std::string& output, const void* name_token) { StringList input; input.SplitIntoLines(oneliner, strlen(oneliner)); |