Clean up "completer_handle_brkchars" callback handling

This patch cleans up "completer_handle_brkchars" callback handling:

- Renames the function typedef to better match its intent:
  completer_ftype_void ->  completer_handle_brkchars_ftype

- Factors out common code in complete_line_internal handling the
  "handle_brkchars" callback to a separate function.

- Centralizes all the "completer method" to "handle_brkchars method"
  mapping in a single function.

gdb/ChangeLog:
2017-07-17  Pedro Alves  <palves@redhat.com>

	* cli/cli-decode.c (set_cmd_completer_handle_brkchars): Adjust to
	renames.
	* cli/cli-decode.h (struct cmd_list_element) <completer>: Move
	comments to completer_ftype's declaration.
	<completer_handle_brkchars>: Change type to
	completer_handle_brkchars_ftype.
	* command.h (completer_ftype): Add describing comment and give
	names to parameters.
	(completer_ftype_void): Rename to ...
	(completer_handle_brkchars_ftype) ... this.  Add describing comment.
	(set_cmd_completer_handle_brkchars): Adjust.
	* completer.c (filename_completer_handle_brkchars): New function.
	(complete_line_internal_normal_command): New function, factored
	out from ...
	(complete_line_internal): ... here.
	(command_completer_handle_brkchars)
	(default_completer_handle_brkchars)
	(completer_handle_brkchars_func_for_completer): New functions.
	* completer.h (set_gdb_completion_word_break_characters): Delete
	declaration.
	(completer_handle_brkchars_func_for_completer): New declaration.
	* python/py-cmd.c (cmdpy_completer_handle_brkchars): Adjust to use
	completer_handle_brkchars_func_for_completer.
This commit is contained in:
Pedro Alves 2017-07-17 12:05:03 +01:00
parent 78b13106ed
commit 6e1dbf8cda
7 changed files with 154 additions and 69 deletions

View file

@ -1,3 +1,29 @@
2017-07-17 Pedro Alves <palves@redhat.com>
* cli/cli-decode.c (set_cmd_completer_handle_brkchars): Adjust to
renames.
* cli/cli-decode.h (struct cmd_list_element) <completer>: Move
comments to completer_ftype's declaration.
<completer_handle_brkchars>: Change type to
completer_handle_brkchars_ftype.
* command.h (completer_ftype): Add describing comment and give
names to parameters.
(completer_ftype_void): Rename to ...
(completer_handle_brkchars_ftype) ... this. Add describing comment.
(set_cmd_completer_handle_brkchars): Adjust.
* completer.c (filename_completer_handle_brkchars): New function.
(complete_line_internal_normal_command): New function, factored
out from ...
(complete_line_internal): ... here.
(command_completer_handle_brkchars)
(default_completer_handle_brkchars)
(completer_handle_brkchars_func_for_completer): New functions.
* completer.h (set_gdb_completion_word_break_characters): Delete
declaration.
(completer_handle_brkchars_func_for_completer): New declaration.
* python/py-cmd.c (cmdpy_completer_handle_brkchars): Adjust to use
completer_handle_brkchars_func_for_completer.
2017-07-17 Pedro Alves <palves@redhat.com> 2017-07-17 Pedro Alves <palves@redhat.com>
* completer.c (symbol_completer): New function, based on * completer.c (symbol_completer): New function, based on

View file

@ -166,9 +166,9 @@ set_cmd_completer (struct cmd_list_element *cmd, completer_ftype *completer)
void void
set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd, set_cmd_completer_handle_brkchars (struct cmd_list_element *cmd,
completer_ftype_void *completer_handle_brkchars) completer_handle_brkchars_ftype *func)
{ {
cmd->completer_handle_brkchars = completer_handle_brkchars; cmd->completer_handle_brkchars = func;
} }
/* Add element named NAME. /* Add element named NAME.

View file

@ -160,19 +160,7 @@ struct cmd_list_element
/* The prefix command of this command. */ /* The prefix command of this command. */
struct cmd_list_element *prefix; struct cmd_list_element *prefix;
/* Completion routine for this command. TEXT is the text beyond /* Completion routine for this command. */
what was matched for the command itself (leading whitespace is
skipped). It stops where we are supposed to stop completing
(rl_point) and is '\0' terminated.
Return value is a malloc'd vector of pointers to possible
completions terminated with NULL. If there are no completions,
returning a pointer to a NULL would work but returning NULL
itself is also valid. WORD points in the same buffer as TEXT,
and completions should be returned relative to this position.
For example, suppose TEXT is "foo" and we want to complete to
"foobar". If WORD is "oo", return "oobar"; if WORD is
"baz/foo", return "baz/foobar". */
completer_ftype *completer; completer_ftype *completer;
/* Handle the word break characters for this completer. Usually /* Handle the word break characters for this completer. Usually
@ -181,8 +169,7 @@ struct cmd_list_element
a class) the word break chars may need to be redefined a class) the word break chars may need to be redefined
depending on the completer type (e.g., for filename depending on the completer type (e.g., for filename
completers). */ completers). */
completer_handle_brkchars_ftype *completer_handle_brkchars;
completer_ftype_void *completer_handle_brkchars;
/* Destruction routine for this command. If non-NULL, this is /* Destruction routine for this command. If non-NULL, this is
called when this command instance is destroyed. This may be called when this command instance is destroyed. This may be

View file

@ -174,18 +174,28 @@ typedef void cmd_sfunc_ftype (char *args, int from_tty,
extern void set_cmd_sfunc (struct cmd_list_element *cmd, extern void set_cmd_sfunc (struct cmd_list_element *cmd,
cmd_sfunc_ftype *sfunc); cmd_sfunc_ftype *sfunc);
typedef VEC (char_ptr) *completer_ftype (struct cmd_list_element *, /* A completion routine. Return a list of possible completions.
const char *, const char *);
typedef void completer_ftype_void (struct cmd_list_element *, TEXT is the text beyond what was matched for the command itself
const char *, const char *); (leading whitespace is skipped). It stops where we are supposed to
stop completing (rl_point) and is '\0' terminated. WORD points in
the same buffer as TEXT, and completions should be returned
relative to this position. For example, suppose TEXT is "foo" and
we want to complete to "foobar". If WORD is "oo", return "oobar";
if WORD is "baz/foo", return "baz/foobar". */
typedef VEC (char_ptr) *completer_ftype (struct cmd_list_element *,
const char *text, const char *word);
/* Same, but for set_cmd_completer_handle_brkchars. */
typedef void completer_handle_brkchars_ftype (struct cmd_list_element *,
const char *text, const char *word);
extern void set_cmd_completer (struct cmd_list_element *, completer_ftype *); extern void set_cmd_completer (struct cmd_list_element *, completer_ftype *);
/* Set the completer_handle_brkchars callback. */ /* Set the completer_handle_brkchars callback. */
extern void set_cmd_completer_handle_brkchars (struct cmd_list_element *, extern void set_cmd_completer_handle_brkchars (struct cmd_list_element *,
completer_ftype_void *); completer_handle_brkchars_ftype *);
/* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs /* HACK: cagney/2002-02-23: Code, mostly in tracepoints.c, grubs
around in cmd objects to test the value of the commands sfunc(). */ around in cmd objects to test the value of the commands sfunc(). */

View file

@ -132,6 +132,7 @@ noop_completer (struct cmd_list_element *ignore,
} }
/* Complete on filenames. */ /* Complete on filenames. */
VEC (char_ptr) * VEC (char_ptr) *
filename_completer (struct cmd_list_element *ignore, filename_completer (struct cmd_list_element *ignore,
const char *text, const char *word) const char *text, const char *word)
@ -192,6 +193,17 @@ filename_completer (struct cmd_list_element *ignore,
return return_val; return return_val;
} }
/* The corresponding completer_handle_brkchars
implementation. */
static void
filename_completer_handle_brkchars (struct cmd_list_element *ignore,
const char *text, const char *word)
{
set_rl_completer_word_break_characters
(gdb_completer_file_name_break_characters);
}
/* Complete on linespecs, which might be of two possible forms: /* Complete on linespecs, which might be of two possible forms:
file:line file:line
@ -703,6 +715,51 @@ typedef enum
} }
complete_line_internal_reason; complete_line_internal_reason;
/* Helper for complete_line_internal to simplify it. */
static VEC (char_ptr) *
complete_line_internal_normal_command (const char *command, const char *word,
const char *cmd_args,
complete_line_internal_reason reason,
struct cmd_list_element *c)
{
const char *p = cmd_args;
if (c->completer == filename_completer)
{
/* Many commands which want to complete on file names accept
several file names, as in "run foo bar >>baz". So we don't
want to complete the entire text after the command, just the
last word. To this end, we need to find the beginning of the
file name by starting at `word' and going backwards. */
for (p = word;
p > command
&& strchr (gdb_completer_file_name_break_characters,
p[-1]) == NULL;
p--)
;
}
if (reason == handle_brkchars)
{
completer_handle_brkchars_ftype *brkchars_fn;
if (c->completer_handle_brkchars != NULL)
brkchars_fn = c->completer_handle_brkchars;
else
{
brkchars_fn
= (completer_handle_brkchars_func_for_completer
(c->completer));
}
brkchars_fn (c, p, word);
}
if (reason != handle_brkchars && c->completer != NULL)
return (*c->completer) (c, p, word);
return NULL;
}
/* Internal function used to handle completions. /* Internal function used to handle completions.
@ -872,29 +929,9 @@ complete_line_internal (const char *text,
{ {
/* It is a normal command; what comes after it is /* It is a normal command; what comes after it is
completed by the command's completer function. */ completed by the command's completer function. */
if (c->completer == filename_completer) list = complete_line_internal_normal_command (tmp_command,
{ word, p,
/* Many commands which want to complete on reason, c);
file names accept several file names, as
in "run foo bar >>baz". So we don't want
to complete the entire text after the
command, just the last word. To this
end, we need to find the beginning of the
file name by starting at `word' and going
backwards. */
for (p = word;
p > tmp_command
&& strchr (gdb_completer_file_name_break_characters, p[-1]) == NULL;
p--)
;
set_rl_completer_word_break_characters
(gdb_completer_file_name_break_characters);
}
if (reason == handle_brkchars
&& c->completer_handle_brkchars != NULL)
(*c->completer_handle_brkchars) (c, p, word);
if (reason != handle_brkchars && c->completer != NULL)
list = (*c->completer) (c, p, word);
} }
} }
else else
@ -945,24 +982,9 @@ complete_line_internal (const char *text,
else else
{ {
/* It is a normal command. */ /* It is a normal command. */
if (c->completer == filename_completer) list = complete_line_internal_normal_command (tmp_command,
{ word, p,
/* See the commentary above about the specifics reason, c);
of file-name completion. */
for (p = word;
p > tmp_command
&& strchr (gdb_completer_file_name_break_characters,
p[-1]) == NULL;
p--)
;
set_rl_completer_word_break_characters
(gdb_completer_file_name_break_characters);
}
if (reason == handle_brkchars
&& c->completer_handle_brkchars != NULL)
(*c->completer_handle_brkchars) (c, p, word);
if (reason != handle_brkchars && c->completer != NULL)
list = (*c->completer) (c, p, word);
} }
} }
} }
@ -1116,6 +1138,7 @@ complete_line (const char *text, const char *line_buffer, int point)
} }
/* Complete on command names. Used by "help". */ /* Complete on command names. Used by "help". */
VEC (char_ptr) * VEC (char_ptr) *
command_completer (struct cmd_list_element *ignore, command_completer (struct cmd_list_element *ignore,
const char *text, const char *word) const char *text, const char *word)
@ -1124,6 +1147,16 @@ command_completer (struct cmd_list_element *ignore,
strlen (text), handle_help); strlen (text), handle_help);
} }
/* The corresponding completer_handle_brkchars implementation. */
static void
command_completer_handle_brkchars (struct cmd_list_element *ignore,
const char *text, const char *word)
{
set_rl_completer_word_break_characters
(gdb_completer_command_word_break_characters);
}
/* Complete on signals. */ /* Complete on signals. */
VEC (char_ptr) * VEC (char_ptr) *
@ -1232,6 +1265,30 @@ reggroup_completer (struct cmd_list_element *ignore,
complete_reggroup_names); complete_reggroup_names);
} }
/* The default completer_handle_brkchars implementation. */
static void
default_completer_handle_brkchars (struct cmd_list_element *ignore,
const char *text, const char *word)
{
set_rl_completer_word_break_characters
(current_language->la_word_break_characters ());
}
/* See definition in completer.h. */
completer_handle_brkchars_ftype *
completer_handle_brkchars_func_for_completer (completer_ftype *fn)
{
if (fn == filename_completer)
return filename_completer_handle_brkchars;
if (fn == command_completer)
return command_completer_handle_brkchars;
return default_completer_handle_brkchars;
}
/* Get the list of chars that are considered as word breaks /* Get the list of chars that are considered as word breaks
for the current command. */ for the current command. */

View file

@ -112,12 +112,14 @@ extern char *gdb_completion_word_break_characters (void);
not "const char *". */ not "const char *". */
extern void set_rl_completer_word_break_characters (const char *break_chars); extern void set_rl_completer_word_break_characters (const char *break_chars);
/* Set the word break characters array to the corresponding set of /* Get the matching completer_handle_brkchars_ftype function for FN.
chars, based on FN. This function is useful for cases when the FN is one of the core completer functions above (filename,
completer doesn't know the type of the completion until some location, symbol, etc.). This function is useful for cases when
the completer doesn't know the type of the completion until some
calculation is done (e.g., for Python functions). */ calculation is done (e.g., for Python functions). */
extern void set_gdb_completion_word_break_characters (completer_ftype *fn); extern completer_handle_brkchars_ftype *
completer_handle_brkchars_func_for_completer (completer_ftype *fn);
/* Exported to linespec.c */ /* Exported to linespec.c */

View file

@ -293,11 +293,14 @@ cmdpy_completer_handle_brkchars (struct cmd_list_element *command,
} }
else if (value >= 0 && value < (long) N_COMPLETERS) else if (value >= 0 && value < (long) N_COMPLETERS)
{ {
completer_handle_brkchars_ftype *brkchars_fn;
/* This is the core of this function. Depending on which /* This is the core of this function. Depending on which
completer type the Python function returns, we have to completer type the Python function returns, we have to
adjust the break characters accordingly. */ adjust the break characters accordingly. */
set_gdb_completion_word_break_characters brkchars_fn = (completer_handle_brkchars_func_for_completer
(completers[value].completer); (completers[value].completer));
brkchars_fn (command, text, word);
} }
} }
} }