mld_read_key_ftype *read_key;
};
+/* A list of completion candidates. Each element is a malloc string,
+ because ownership of the strings is transferred to readline, which
+ calls free on each element. */
+typedef std::vector<gdb::unique_xmalloc_ptr<char>> completion_list;
+
+/* The final result of a completion that is handed over to either
+ readline or the "completion" command (which pretends to be
+ readline). Mainly a wrapper for a readline-style match list array,
+ though other bits of info are included too. */
+
+struct completion_result
+{
+ /* Create an empty result. */
+ completion_result ();
+
+ /* Create a result. */
+ completion_result (char **match_list, size_t number_matches,
+ bool completion_suppress_append);
+
+ /* Destroy a result. */
+ ~completion_result ();
+
+ /* Disable copying, since we don't need it. */
+ completion_result (const completion_result &rhs) = delete;
+ void operator= (const completion_result &rhs) = delete;
+
+ /* Move a result. */
+ completion_result (completion_result &&rhs);
+
+ /* Release ownership of the match list array. */
+ char **release_match_list ();
+
+ /* Sort the match list. */
+ void sort_match_list ();
+
+private:
+ /* Destroy the match list array and its contents. */
+ void reset_match_list ();
+
+public:
+ /* (There's no point in making these fields private, since the whole
+ point of this wrapper is to build data in the layout expected by
+ readline. Making them private would require adding getters for
+ the "complete" command, which would expose the same
+ implementation details anyway.) */
+
+ /* The match list array, in the format that readline expects.
+ match_list[0] contains the common prefix. The real match list
+ starts at index 1. The list is NULL terminated. If there's only
+ one match, then match_list[1] is NULL. If there are no matches,
+ then this is NULL. */
+ char **match_list;
+ /* The number of matched completions in MATCH_LIST. Does not
+ include the NULL terminator or the common prefix. */
+ size_t number_matches;
+
+ /* Whether readline should suppress appending a whitespace, when
+ there's only one possible completion. */
+ bool completion_suppress_append;
+};
+
+/* Object used by completers to build a completion match list to hand
+ over to readline. It tracks:
+
+ - How many unique completions have been generated, to terminate
+ completion list generation early if the list has grown to a size
+ so large as to be useless. This helps avoid GDB seeming to lock
+ up in the event the user requests to complete on something vague
+ that necessitates the time consuming expansion of many symbol
+ tables.
+*/
+class completion_tracker
+{
+public:
+ completion_tracker ();
+ ~completion_tracker ();
+
+ /* Disable copy. */
+ completion_tracker (const completion_tracker &rhs) = delete;
+ void operator= (const completion_tracker &rhs) = delete;
+
+ /* Add the completion NAME to the list of generated completions if
+ it is not there already. If too many completions were already
+ found, this throws an error. */
+ void add_completion (gdb::unique_xmalloc_ptr<char> name);
+
+ /* Add all completions matches in LIST. Elements are moved out of
+ LIST. */
+ void add_completions (completion_list &&list);
+
+ /* True if we have any completion match recorded. */
+ bool have_completions () const
+ { return !m_entries_vec.empty (); }
+
+ /* Build a completion_result containing the list of completion
+ matches to hand over to readline. The parameters are as in
+ rl_attempted_completion_function. */
+ completion_result build_completion_result (const char *text,
+ int start, int end);
+
+private:
+
+ /* Add the completion NAME to the list of generated completions if
+ it is not there already. If false is returned, too many
+ completions were found. */
+ bool maybe_add_completion (gdb::unique_xmalloc_ptr<char> name);
+
+ /* Given a new match, recompute the lowest common denominator (LCD)
+ to hand over to readline. */
+ void recompute_lowest_common_denominator (const char *new_match);
+
+ /* The completion matches found so far, in a vector. */
+ completion_list m_entries_vec;
+
+ /* The completion matches found so far, in a hash table, for
+ duplicate elimination as entries are added. Otherwise the user
+ is left scratching his/her head: readline and complete_command
+ will remove duplicates, and if removal of duplicates there brings
+ the total under max_completions the user may think gdb quit
+ searching too early. */
+ htab_t m_entries_hash;
+
+ /* Our idea of lowest common denominator to hand over to readline. */
+ char *m_lowest_common_denominator = NULL;
+
+ /* If true, the LCD is unique. I.e., all completion candidates had
+ the same string. */
+ bool m_lowest_common_denominator_unique = false;
+};
+
extern void gdb_display_match_list (char **matches, int len, int max,
const struct match_list_displayer *);
extern const char *get_max_completions_reached_message (void);
-extern VEC (char_ptr) *complete_line (const char *text,
- const char *line_buffer,
- int point);
+extern void complete_line (completion_tracker &tracker,
+ const char *text,
+ const char *line_buffer,
+ int point);
-extern char *readline_line_completion_function (const char *text,
- int matches);
+extern char **gdb_rl_attempted_completion_function (const char *text,
+ int start, int end);
-extern VEC (char_ptr) *noop_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void noop_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *filename_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void filename_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *expression_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void expression_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *location_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void location_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *symbol_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void symbol_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *command_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void command_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *signal_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void signal_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *reg_or_group_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void reg_or_group_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
-extern VEC (char_ptr) *reggroup_completer (struct cmd_list_element *,
- const char *, const char *);
+extern void reggroup_completer (struct cmd_list_element *,
+ completion_tracker &tracker,
+ const char *, const char *);
extern const char *get_gdb_completer_quote_characters (void);
extern int max_completions;
-/* Object to track how many unique completions have been generated.
- Used to limit the size of generated completion lists. */
-
-typedef htab_t completion_tracker_t;
-
-/* Create a new completion tracker.
- The result is a hash table to track added completions, or NULL
- if max_completions <= 0. If max_completions < 0, tracking is disabled.
- If max_completions == 0, the max is indeed zero. */
-
-extern completion_tracker_t new_completion_tracker (void);
-
-/* Make a cleanup to free a completion tracker, and reset its pointer
- to NULL. */
-
-extern struct cleanup *make_cleanup_free_completion_tracker
- (completion_tracker_t *tracker_ptr);
-
-/* Return values for maybe_add_completion. */
-
-enum maybe_add_completion_enum
-{
- /* NAME has been recorded and max_completions has not been reached,
- or completion tracking is disabled (max_completions < 0). */
- MAYBE_ADD_COMPLETION_OK,
-
- /* NAME has been recorded and max_completions has been reached
- (thus the caller can stop searching). */
- MAYBE_ADD_COMPLETION_OK_MAX_REACHED,
-
- /* max-completions entries has been reached.
- Whether NAME is a duplicate or not is not determined. */
- MAYBE_ADD_COMPLETION_MAX_REACHED,
-
- /* NAME has already been recorded.
- Note that this is never returned if completion tracking is disabled
- (max_completions < 0). */
- MAYBE_ADD_COMPLETION_DUPLICATE
-};
-
-/* Add the completion NAME to the list of generated completions if
- it is not there already.
- If max_completions is negative, nothing is done, not even watching
- for duplicates, and MAYBE_ADD_COMPLETION_OK is always returned.
-
- If MAYBE_ADD_COMPLETION_MAX_REACHED is returned, callers are required to
- record at least one more completion. The final list will be pruned to
- max_completions, but recording at least one more than max_completions is
- the signal to the completion machinery that too many completions were
- found. */
-
-extern enum maybe_add_completion_enum
- maybe_add_completion (completion_tracker_t tracker, char *name);
-
-/* Wrapper to throw MAX_COMPLETIONS_REACHED_ERROR. */
-
-extern void throw_max_completions_reached_error (void);
-
#endif /* defined (COMPLETER_H) */