merge from gcc
[deliverable/binutils-gdb.git] / gdb / completer.c
index 7005a5dc0343423fd05abbc72dbf4201974b71a6..62f0b694fa31102e5cc6238fa22d8cddffb6a2ed 100644 (file)
@@ -1,5 +1,5 @@
 /* Line completion stuff for GDB, the GNU debugger.
-   Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -338,6 +338,97 @@ location_completer (char *text, char *word)
   return list;
 }
 
+/* Helper for expression_completer which recursively counts the number
+   of named fields in a structure or union type.  */
+static int
+count_struct_fields (struct type *type)
+{
+  int i, result = 0;
+
+  CHECK_TYPEDEF (type);
+  for (i = 0; i < TYPE_NFIELDS (type); ++i)
+    {
+      if (i < TYPE_N_BASECLASSES (type))
+       result += count_struct_fields (TYPE_BASECLASS (type, i));
+      else if (TYPE_FIELD_NAME (type, i))
+       ++result;
+    }
+  return result;
+}
+
+/* Helper for expression_completer which recursively adds field names
+   from TYPE, a struct or union type, to the array OUTPUT.  This
+   function assumes that OUTPUT is correctly-sized.  */
+static void
+add_struct_fields (struct type *type, int *nextp, char **output,
+                  char *fieldname, int namelen)
+{
+  int i;
+
+  CHECK_TYPEDEF (type);
+  for (i = 0; i < TYPE_NFIELDS (type); ++i)
+    {
+      if (i < TYPE_N_BASECLASSES (type))
+       add_struct_fields (TYPE_BASECLASS (type, i), nextp, output,
+                          fieldname, namelen);
+      else if (TYPE_FIELD_NAME (type, i)
+              && ! strncmp (TYPE_FIELD_NAME (type, i), fieldname, namelen))
+       {
+         output[*nextp] = xstrdup (TYPE_FIELD_NAME (type, i));
+         ++*nextp;
+       }
+    }
+}
+
+/* Complete on expressions.  Often this means completing on symbol
+   names, but some language parsers also have support for completing
+   field names.  */
+char **
+expression_completer (char *text, char *word)
+{
+  struct type *type;
+  char *fieldname, *p;
+
+  /* Perform a tentative parse of the expression, to see whether a
+     field completion is required.  */
+  fieldname = NULL;
+  type = parse_field_expression (text, &fieldname);
+  if (fieldname && type)
+    {
+      for (;;)
+       {
+         CHECK_TYPEDEF (type);
+         if (TYPE_CODE (type) != TYPE_CODE_PTR
+             && TYPE_CODE (type) != TYPE_CODE_REF)
+           break;
+         type = TYPE_TARGET_TYPE (type);
+       }
+
+      if (TYPE_CODE (type) == TYPE_CODE_UNION
+         || TYPE_CODE (type) == TYPE_CODE_STRUCT)
+       {
+         int alloc = count_struct_fields (type);
+         int flen = strlen (fieldname);
+         int out = 0;
+         char **result = (char **) xmalloc ((alloc + 1) * sizeof (char *));
+
+         add_struct_fields (type, &out, result, fieldname, flen);
+         result[out] = NULL;
+         return result;
+       }
+    }
+
+  /* Commands which complete on locations want to see the entire
+     argument.  */
+  for (p = word;
+       p > text && p[-1] != ' ' && p[-1] != '\t';
+       p--)
+    ;
+
+  /* Not ideal but it is what we used to do before... */
+  return location_completer (p, word);
+}
+
 /* Complete on command names.  Used by "help".  */
 char **
 command_completer (char *text, char *word)
This page took 0.024786 seconds and 4 git commands to generate.