summaryrefslogtreecommitdiffstats
path: root/lldb/source/Interpreter/OptionGroupFormat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Interpreter/OptionGroupFormat.cpp')
-rw-r--r--lldb/source/Interpreter/OptionGroupFormat.cpp166
1 files changed, 158 insertions, 8 deletions
diff --git a/lldb/source/Interpreter/OptionGroupFormat.cpp b/lldb/source/Interpreter/OptionGroupFormat.cpp
index ad4f371d836..7dc81540ebd 100644
--- a/lldb/source/Interpreter/OptionGroupFormat.cpp
+++ b/lldb/source/Interpreter/OptionGroupFormat.cpp
@@ -23,7 +23,9 @@ OptionGroupFormat::OptionGroupFormat (lldb::Format default_format,
uint64_t default_count) :
m_format (default_format, default_format),
m_byte_size (default_byte_size, default_byte_size),
- m_count (default_count, default_count)
+ m_count (default_count, default_count),
+ m_prev_gdb_format('x'),
+ m_prev_gdb_size('w')
{
}
@@ -34,9 +36,12 @@ OptionGroupFormat::~OptionGroupFormat ()
static OptionDefinition
g_option_table[] =
{
-{ LLDB_OPT_SET_1, false, "format",'f', required_argument, NULL, 0, eArgTypeFormat , "Specify a format to be used for display."},
-{ LLDB_OPT_SET_2, false, "size" ,'s', required_argument, NULL, 0, eArgTypeByteSize, "The size in bytes to use when displaying with the selected format."},
-{ LLDB_OPT_SET_3, false, "count" ,'c', required_argument, NULL, 0, eArgTypeCount , "The number of total items to display."},
+{ LLDB_OPT_SET_1, false, "format" ,'f', required_argument, NULL, 0, eArgTypeFormat , "Specify a format to be used for display."},
+{ LLDB_OPT_SET_1|
+ LLDB_OPT_SET_2|
+ LLDB_OPT_SET_3, false, "gdb-format",'G', required_argument, NULL, 0, eArgTypeGDBFormat, "Specify a format using a GDB format specifier string."},
+{ LLDB_OPT_SET_2, false, "size" ,'s', required_argument, NULL, 0, eArgTypeByteSize , "The size in bytes to use when displaying with the selected format."},
+{ LLDB_OPT_SET_3, false, "count" ,'c', required_argument, NULL, 0, eArgTypeCount , "The number of total items to display."},
};
uint32_t
@@ -45,11 +50,11 @@ OptionGroupFormat::GetNumDefinitions ()
if (m_byte_size.GetDefaultValue() < UINT64_MAX)
{
if (m_count.GetDefaultValue() < UINT64_MAX)
- return 3;
+ return 4;
else
- return 2;
+ return 3;
}
- return 1;
+ return 2;
}
const OptionDefinition *
@@ -98,14 +103,159 @@ OptionGroupFormat::SetOptionValue (CommandInterpreter &interpreter,
}
break;
+ case 'G':
+ {
+ char *end = NULL;
+ const char *gdb_format_cstr = option_arg;
+ uint64_t count = 0;
+ if (::isdigit (gdb_format_cstr[0]))
+ {
+ count = strtoull (gdb_format_cstr, &end, 0);
+
+ if (option_arg != end)
+ gdb_format_cstr = end; // We have a valid count, advance the string position
+ else
+ count = 0;
+ }
+
+ Format format = SetFormatUsingGDBFormatLetter (gdb_format_cstr[0]);
+ if (format != eFormatInvalid)
+ ++gdb_format_cstr;
+
+ uint32_t byte_size = SetByteSizeUsingGDBSizeLetter (gdb_format_cstr[0]);
+ if (byte_size == 0)
+ ++gdb_format_cstr;
+
+ // We the first character of the "gdb_format_cstr" is not the
+ // NULL terminator, we didn't consume the entire string and
+ // something is wrong. Also, if none of the format, size or count
+ // was specified correctly, then abort.
+ if (gdb_format_cstr[0] || (format == eFormatInvalid && byte_size == 0 && count == 0))
+ {
+ // Nothing got set correctly
+ error.SetErrorStringWithFormat ("invalid gdb format string '%s'", option_arg);
+ return error;
+ }
+
+ // At least one of the format, size or count was set correctly.
+ // Anything that wasn't set correctly should be set to the
+ // previous default
+ if (format == eFormatInvalid)
+ format = SetFormatUsingGDBFormatLetter (m_prev_gdb_format);
+
+ const bool byte_size_enabled = m_byte_size.GetDefaultValue() < UINT64_MAX;
+ const bool count_enabled = m_count.GetDefaultValue() < UINT64_MAX;
+ if (byte_size_enabled)
+ {
+ // Byte size is enabled
+ if (byte_size == 0)
+ byte_size = SetByteSizeUsingGDBSizeLetter (m_prev_gdb_size);
+ }
+ else
+ {
+ // Byte size is disabled, make sure it wasn't specified
+ if (byte_size > 0)
+ {
+ error.SetErrorString ("this command doesn't support specifying a byte size");
+ return error;
+ }
+ }
+
+ if (count_enabled)
+ {
+ // Count is enabled and was not set, set it to the default
+ if (count == 0)
+ count = m_count.GetDefaultValue();
+ }
+ else
+ {
+ // Count is disabled, make sure it wasn't specified
+ if (count > 0)
+ {
+ error.SetErrorString ("this command doesn't support specifying a count");
+ return error;
+ }
+ }
+
+ m_format.SetCurrentValue (format);
+ m_format.SetOptionWasSet ();
+ if (byte_size_enabled)
+ {
+ m_byte_size.SetCurrentValue (byte_size);
+ m_byte_size.SetOptionWasSet ();
+ }
+ if (count_enabled)
+ {
+ m_count.SetCurrentValue(count);
+ m_count.SetOptionWasSet ();
+ }
+ }
+ break;
+
default:
- error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
}
return error;
}
+Format
+OptionGroupFormat::SetFormatUsingGDBFormatLetter (char format_letter)
+{
+ Format format = eFormatInvalid;
+ switch (format_letter)
+ {
+ case 'o': format = eFormatOctal; break;
+ case 'x': format = eFormatHex; break;
+ case 'd': format = eFormatDecimal; break;
+ case 'u': format = eFormatUnsigned; break;
+ case 't': format = eFormatBinary; break;
+ case 'f': format = eFormatFloat; break;
+ case 'a': format = eFormatHex; break; // TODO: add a new format: eFormatAddress
+ case 'i': format = eFormatHex; break; // TODO: add a new format: eFormatInstruction
+ case 'c': format = eFormatChar; break;
+ case 's': format = eFormatCString; break;
+ case 'T': format = eFormatOSType; break;
+ case 'A': format = eFormatHex; break; // TODO: add a new format: eFormatHexFloat
+ default: break;
+ }
+ if (format != eFormatInvalid)
+ m_prev_gdb_format = format_letter;
+ return format;
+}
+
+uint32_t
+OptionGroupFormat::SetByteSizeUsingGDBSizeLetter (char size_letter)
+{
+ uint32_t byte_size = 0;
+ switch (size_letter)
+ {
+ case 'b': // byte
+ byte_size = 1;
+ break;
+
+ case 'h': // halfword
+ byte_size = 2;
+ break;
+
+ case 'w': // word
+ byte_size = 4;
+ break;
+
+ case 'g': // giant
+ byte_size = 8;
+ break;
+
+ default:
+ break;
+ }
+ if (byte_size)
+ m_prev_gdb_size = size_letter;
+ return byte_size;
+}
+
+
void
OptionGroupFormat::OptionParsingStarting (CommandInterpreter &interpreter)
{
OpenPOWER on IntegriCloud