Introduce class completion_tracker & rewrite completion<->readline interaction
[deliverable/binutils-gdb.git] / gdb / python / py-cmd.c
index 3aaf7f943541fc584ba718c7a7ae0ac9737543b6..b9f60377bd60218547968f30ae737b6d8322d11e 100644 (file)
 /* Struct representing built-in completion types.  */
 struct cmdpy_completer
 {
-  /* Python symbol name.
-     This isn't a const char * for Python 2.4's sake.
-     PyModule_AddIntConstant only takes a char *, sigh.  */
-  char *name;
+  /* Python symbol name.  */
+  const char *name;
   /* Completion function.  */
   completer_ftype *completer;
 };
@@ -46,7 +44,7 @@ static const struct cmdpy_completer completers[] =
   { "COMPLETE_FILENAME", filename_completer },
   { "COMPLETE_LOCATION", location_completer },
   { "COMPLETE_COMMAND", command_completer },
-  { "COMPLETE_SYMBOL", make_symbol_completion_list_fn },
+  { "COMPLETE_SYMBOL", symbol_completer },
   { "COMPLETE_EXPRESSION", expression_completer },
 };
 
@@ -111,8 +109,10 @@ cmdpy_destroyer (struct cmd_list_element *self, void *context)
 /* Called by gdb to invoke the command.  */
 
 static void
-cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
+cmdpy_function (struct cmd_list_element *command,
+               char *args_entry, int from_tty)
 {
+  const char *args = args_entry;
   cmdpy_object *obj = (cmdpy_object *) get_cmd_context (command);
 
   gdbpy_enter enter_py (get_current_arch (), current_language);
@@ -242,10 +242,21 @@ cmdpy_completer_helper (struct cmd_list_element *command,
                                         NULL));
   if (textobj == NULL)
     error (_("Could not convert argument to Python string."));
-  gdbpy_ref<> wordobj (PyUnicode_Decode (word, strlen (word), host_charset (),
-                                        NULL));
-  if (wordobj == NULL)
-    error (_("Could not convert argument to Python string."));
+
+  gdbpy_ref<> wordobj;
+  if (word == NULL)
+    {
+      /* "brkchars" phase.  */
+      wordobj.reset (Py_None);
+      Py_INCREF (Py_None);
+    }
+  else
+    {
+      wordobj.reset (PyUnicode_Decode (word, strlen (word), host_charset (),
+                                      NULL));
+      if (wordobj == NULL)
+       error (_("Could not convert argument to Python string."));
+    }
 
   gdbpy_ref<> resultobj (PyObject_CallMethodObjArgs ((PyObject *) obj,
                                                     complete_cst,
@@ -267,6 +278,7 @@ cmdpy_completer_helper (struct cmd_list_element *command,
 
 static void
 cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
+                                completion_tracker &tracker,
                                 const char *text, const char *word)
 {
   gdbpy_enter enter_py (get_current_arch (), current_language);
@@ -293,23 +305,25 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
        }
       else if (value >= 0 && value < (long) N_COMPLETERS)
        {
+         completer_handle_brkchars_ftype *brkchars_fn;
+
          /* This is the core of this function.  Depending on which
             completer type the Python function returns, we have to
             adjust the break characters accordingly.  */
-         set_gdb_completion_word_break_characters
-           (completers[value].completer);
+         brkchars_fn = (completer_handle_brkchars_func_for_completer
+                        (completers[value].completer));
+         brkchars_fn (command, tracker, text, word);
        }
     }
 }
 
 /* Called by gdb for command completion.  */
 
-static VEC (char_ptr) *
+static void
 cmdpy_completer (struct cmd_list_element *command,
+                completion_tracker &tracker,
                 const char *text, const char *word)
 {
-  VEC (char_ptr) *result = NULL;
-
   gdbpy_enter enter_py (get_current_arch (), current_language);
 
   /* Calling our helper to obtain the PyObject of the Python
@@ -317,12 +331,10 @@ cmdpy_completer (struct cmd_list_element *command,
   gdbpy_ref<> resultobj (cmdpy_completer_helper (command, text, word));
 
   /* If the result object of calling the Python function is NULL, it
-     means that there was an error.  In this case, just give up and
-     return NULL.  */
+     means that there was an error.  In this case, just give up.  */
   if (resultobj == NULL)
-    return NULL;
+    return;
 
-  result = NULL;
   if (PyInt_Check (resultobj.get ()))
     {
       /* User code may also return one of the completion constants,
@@ -335,15 +347,16 @@ cmdpy_completer (struct cmd_list_element *command,
          PyErr_Clear ();
        }
       else if (value >= 0 && value < (long) N_COMPLETERS)
-       result = completers[value].completer (command, text, word);
+       completers[value].completer (command, tracker, text, word);
     }
   else
     {
       gdbpy_ref<> iter (PyObject_GetIter (resultobj.get ()));
 
       if (iter == NULL)
-       return NULL;
+       return;
 
+      bool got_matches = false;
       while (true)
        {
          gdbpy_ref<> elt (PyIter_Next (iter.get ()));
@@ -363,16 +376,15 @@ cmdpy_completer (struct cmd_list_element *command,
              PyErr_Clear ();
              continue;
            }
-         VEC_safe_push (char_ptr, result, item.release ());
+         tracker.add_completion (std::move (item));
+         got_matches = true;
        }
 
       /* If we got some results, ignore problems.  Otherwise, report
         the problem.  */
-      if (result != NULL && PyErr_Occurred ())
+      if (got_matches && PyErr_Occurred ())
        PyErr_Clear ();
     }
-
-  return result;
 }
 
 /* Helper for cmdpy_init which locates the command list to use and
@@ -490,8 +502,8 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
   char *docstring = NULL;
   struct cmd_list_element **cmd_list;
   char *cmd_name, *pfx_name;
-  static char *keywords[] = { "name", "command_class", "completer_class",
-                             "prefix", NULL };
+  static const char *keywords[] = { "name", "command_class", "completer_class",
+                                   "prefix", NULL };
   PyObject *is_prefix = NULL;
   int cmp;
 
@@ -504,9 +516,9 @@ cmdpy_init (PyObject *self, PyObject *args, PyObject *kw)
       return -1;
     }
 
-  if (! PyArg_ParseTupleAndKeywords (args, kw, "si|iO",
-                                    keywords, &name, &cmdtype,
-                         &completetype, &is_prefix))
+  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "si|iO",
+                                       keywords, &name, &cmdtype,
+                                       &completetype, &is_prefix))
     return -1;
 
   if (cmdtype != no_class && cmdtype != class_run
This page took 0.027218 seconds and 4 git commands to generate.