$ command in gdb now works (#10956)

This commit is contained in:
Arne Döring
2019-04-15 08:25:21 +02:00
committed by Andreas Rumpf
parent a517a9985b
commit 107905919e

View File

@@ -125,27 +125,36 @@ class NimTypePrinter:
class DollarPrintFunction (gdb.Function):
"Nim's equivalent of $ operator as a gdb function, available in expressions `print $dollar(myvalue)"
_gdb_dollar_functions = gdb.execute("info functions dollar__", True, True)
dollar_functions = re.findall('NimStringDesc \*(dollar__[A-z0-9_]+?)\(([^,)]*)\);', _gdb_dollar_functions)
dollar_functions = re.findall(
'NimStringDesc \*(dollar__[A-z0-9_]+?)\(([^,)]*)\);',
gdb.execute("info functions dollar__", True, True)
)
def __init__ (self):
super (DollarPrintFunction, self).__init__("dollar")
@staticmethod
def invoke_static(arg):
for func, arg_typ in DollarPrintFunction.dollar_functions:
if arg.type.code == gdb.TYPE_CODE_PTR and arg.type.target().name == "NimStringDesc":
return arg
if arg.type.name == arg_typ:
argTypeName = str(arg.type)
for func, arg_typ in DollarPrintFunction.dollar_functions:
# this way of overload resolution cannot deal with type aliases,
# therefore it won't find all overloads.
if arg_typ == argTypeName:
func_value = gdb.lookup_global_symbol(func, gdb.SYMBOL_FUNCTIONS_DOMAIN).value()
return func_value(arg)
if arg.type.name + " *" == arg_typ:
elif arg_typ == argTypeName + " *":
func_value = gdb.lookup_global_symbol(func, gdb.SYMBOL_FUNCTIONS_DOMAIN).value()
return func_value(arg.address)
typeName = arg.type.name
printErrorOnce(typeName, "No suitable Nim $ operator found for type: " + typeName + ".\n")
printErrorOnce(argTypeName, "No suitable Nim $ operator found for type: " + argTypeName + "\n")
return None
def invoke(self, arg):
return self.invoke_static(arg)
@@ -157,14 +166,32 @@ DollarPrintFunction()
################################################################################
class DollarPrintCmd (gdb.Command):
"""Dollar print command for Nim, `$ expr` will invoke Nim's $ operator"""
"""Dollar print command for Nim, `$ expr` will invoke Nim's $ operator and print the result."""
def __init__ (self):
super (DollarPrintCmd, self).__init__ ("$", gdb.COMMAND_DATA, gdb.COMPLETE_EXPRESSION)
def invoke (self, arg, from_tty):
def invoke(self, arg, from_tty):
param = gdb.parse_and_eval(arg)
gdb.write(str(DollarPrintFunction.invoke_static(param)) + "\n", gdb.STDOUT)
strValue = DollarPrintFunction.invoke_static(param)
if strValue:
gdb.write(
NimStringPrinter(strValue).to_string() + "\n",
gdb.STDOUT
)
# could not find a suitable dollar overload. This here is the
# fallback to get sensible output of basic types anyway.
elif param.type.code == gdb.TYPE_CODE_ARRAY and param.type.target().name == "char":
gdb.write(param.string("utf-8", "ignore") + "\n", gdb.STDOUT)
elif param.type.code == gdb.TYPE_CODE_INT:
gdb.write(str(int(param)) + "\n", gdb.STDOUT)
elif param.type.name == "NIM_BOOL":
if int(param) != 0:
gdb.write("true\n", gdb.STDOUT)
else:
gdb.write("false\n", gdb.STDOUT)
DollarPrintCmd()