/* Header for GDB line completion.
   Copyright (C) 2000-2025 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDB_COMPLETER_H
#define GDB_COMPLETER_H

#include "gdbsupport/gdb-hashtab.h"
#include "command.h"

/* Types of functions in struct match_list_displayer.  */

struct match_list_displayer;

typedef void mld_crlf_ftype (const struct match_list_displayer *);
typedef void mld_putch_ftype (const struct match_list_displayer *, int);
typedef void mld_puts_ftype (const struct match_list_displayer *,
			     const char *);
typedef void mld_flush_ftype (const struct match_list_displayer *);
typedef void mld_erase_entire_line_ftype (const struct match_list_displayer *);
typedef void mld_beep_ftype (const struct match_list_displayer *);
typedef int mld_read_key_ftype (const struct match_list_displayer *);

/* Interface between CLI/TUI and gdb_match_list_displayer.  */

struct match_list_displayer
{
  /* The screen dimensions to work with when displaying matches.  */
  int height, width;

  /* Print cr,lf.  */
  mld_crlf_ftype *crlf;

  /* Not "putc" to avoid issues where it is a stdio macro.  Sigh.  */
  mld_putch_ftype *putch;

  /* Print a string.  */
  mld_puts_ftype *puts;

  /* Flush all accumulated output.  */
  mld_flush_ftype *flush;

  /* Erase the currently line on the terminal (but don't discard any text the
     user has entered, readline may shortly re-print it).  */
  mld_erase_entire_line_ftype *erase_entire_line;

  /* Ring the bell.  */
  mld_beep_ftype *beep;

  /* Read one key.  */
  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 result of a successful completion match.  When doing symbol
   comparison, we use the symbol search name for the symbol name match
   check, but the matched name that is shown to the user may be
   different.  For example, Ada uses encoded names for lookup, but
   then wants to decode the symbol name to show to the user, and also
   in some cases wrap the matched name in "<sym>" (meaning we can't
   always use the symbol's print name).  */

class completion_match
{
public:
  /* Get the completion match result.  See m_match/m_storage's
     descriptions.  */
  const char *match ()
  { return m_match; }

  /* Set the completion match result.  See m_match/m_storage's
     descriptions.  */
  void set_match (const char *match)
  { m_match = match; }

  /* Get temporary storage for generating a match result, dynamically.
     The built string is only good until the next clear() call.  I.e.,
     good until the next symbol comparison.  */
  std::string &storage ()
  { return m_storage; }

  /* Prepare for another completion matching sequence.  */
  void clear ()
  {
    m_match = NULL;
    m_storage.clear ();
  }

private:
  /* The completion match result.  This can either be a pointer into
     M_STORAGE string, or it can be a pointer into the some other
     string that outlives the completion matching sequence (usually, a
     pointer to a symbol's name).  */
  const char *m_match;

  /* Storage a symbol comparison routine can use for generating a
     match result, dynamically.  The built string is only good until
     the next clear() call.  I.e., good until the next symbol
     comparison.  */
  std::string m_storage;
};

/* The result of a successful completion match, but for least common
   denominator (LCD) computation.  Some completers provide matches
   that don't start with the completion "word".  E.g., completing on
   "b push_ba" on a C++ program usually completes to
   std::vector<...>::push_back, std::string::push_back etc.  In such
   case, the symbol comparison routine will set the LCD match to point
   into the "push_back" substring within the symbol's name string.
   Also, in some cases, the symbol comparison routine will want to
   ignore parts of the symbol name for LCD purposes, such as for
   example symbols with abi tags in C++.  In such cases, the symbol
   comparison routine will set MARK_IGNORED_RANGE to mark the ignored
   substrings of the matched string.  The resulting LCD string with
   the ignored parts stripped out is computed at the end of a
   completion match sequence iff we had a positive match.  */

class completion_match_for_lcd
{
public:
  /* Get the resulting LCD, after a successful match.  */
  const char *match ()
  { return m_match; }

  /* Set the match for LCD.  See m_match's description.  */
  void set_match (const char *match)
  { m_match = match; }

  /* Mark the range between [BEGIN, END) as ignored.  */
  void mark_ignored_range (const char *begin, const char *end)
  {
    gdb_assert (begin < end);
    gdb_assert (m_ignored_ranges.empty ()
		|| m_ignored_ranges.back ().second < begin);
    m_ignored_ranges.emplace_back (begin, end);
  }

  /* Get the resulting LCD, after a successful match.  If there are
     ignored ranges, then this builds a new string with the ignored
     parts removed (and stores it internally).  As such, the result of
     this call is only good for the current completion match
     sequence.  */
  const char *finish ()
  {
    if (m_ignored_ranges.empty ())
      return m_match;
    else
      {
	m_finished_storage.clear ();

	gdb_assert (m_ignored_ranges.back ().second
		    <= (m_match + strlen (m_match)));

	const char *prev = m_match;
	for (const auto &range : m_ignored_ranges)
	  {
	    gdb_assert (prev < range.first);
	    gdb_assert (range.second > range.first);
	    m_finished_storage.append (prev, range.first);
	    prev = range.second;
	  }
	m_finished_storage.append (prev);

	return m_finished_storage.c_str ();
      }
  }

  /* Prepare for another completion matching sequence.  */
  void clear ()
  {
    m_match = NULL;
    m_ignored_ranges.clear ();
  }

  /* Return true if this object has had no match data set since its
     creation, or the last call to clear.  */
  bool empty () const
  {
    return m_match == nullptr && m_ignored_ranges.empty ();
  }

private:
  /* The completion match result for LCD.  This is usually either a
     pointer into to a substring within a symbol's name, or to the
     storage of the pairing completion_match object.  */
  const char *m_match;

  /* The ignored substring ranges within M_MATCH.  E.g., if we were
     looking for completion matches for C++ functions starting with
       "functio"
     and successfully match:
       "function[abi:cxx11](int)"
     the ignored ranges vector will contain an entry that delimits the
     "[abi:cxx11]" substring, such that calling finish() results in:
       "function(int)"
   */
  std::vector<std::pair<const char *, const char *>> m_ignored_ranges;

  /* Storage used by the finish() method, if it has to compute a new
     string.  */
  std::string m_finished_storage;
};

/* Convenience aggregate holding info returned by the symbol name
   matching routines (see symbol_name_matcher_ftype).  */
struct completion_match_result
{
  /* The completion match candidate.  */
  completion_match match;

  /* The completion match, for LCD computation purposes.  */
  completion_match_for_lcd match_for_lcd;

  /* Convenience that sets both MATCH and MATCH_FOR_LCD.  M_FOR_LCD is
     optional.  If not specified, defaults to M.  */
  void set_match (const char *m, const char *m_for_lcd = NULL)
  {
    match.set_match (m);
    if (m_for_lcd == NULL)
      match_for_lcd.set_match (m);
    else
      match_for_lcd.set_match (m_for_lcd);
  }
};

/* 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
{
  /* The type of a function that is used to format completion results when
     using the 'complete' command.  MATCH is the completion word to be
     printed, and QUOTE_CHAR is a trailing quote character to (possibly)
     add at the end of MATCH.  QUOTE_CHAR can be the null-character in
     which case no trailing quote should be added.

     Return the possibly modified completion match word which should be
     presented to the user.  */
  using match_format_func_t = std::string (*) (const char *match,
					       char quote_char);

  /* Create an empty result.  */
  completion_result ();

  /* Create a result.  */
  completion_result (char **match_list, size_t number_matches,
		     bool completion_suppress_append,
		     match_format_func_t match_format_func);

  /* Destroy a result.  */
  ~completion_result ();

  DISABLE_COPY_AND_ASSIGN (completion_result);

  /* Move a result.  */
  completion_result (completion_result &&rhs) noexcept;

  /* Release ownership of the match list array.  */
  char **release_match_list ();

  /* Sort the match list.  */
  void sort_match_list ();

  /* Called to display all matches (used by the 'complete' command).
     PREFIX is everything before the completion word.  WORD is the word
     being completed, this is only used if we reach the maximum number of
     completions, otherwise, each line of output consists of PREFIX
     followed by one of the possible completion words.

     The QUOTE_CHAR is usually appended after each possible completion
     word and should be the quote character that appears before the
     completion word, or the null-character if there is no quote before
     the completion word.

     The QUOTE_CHAR is not always appended to the completion output.  For
     example, filename completions will not append QUOTE_CHAR if the
     completion is a directory name.  This is all handled by calling this
     function.  */
  void print_matches (const std::string &prefix, const char *word,
		      int quote_char);

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;

private:
  /* A function which formats a single completion match ready for display
     as part of the 'complete' command output.  Different completion
     functions can set different formatter functions.  */
  match_format_func_t m_match_formatter;
};

/* 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.

   - The completer's idea of least common denominator (aka the common
     prefix) between all completion matches to hand over to readline.
     Some completers provide matches that don't start with the
     completion "word".  E.g., completing on "b push_ba" on a C++
     program usually completes to std::vector<...>::push_back,
     std::string::push_back etc.  If all matches happen to start with
     "std::", then readline would figure out that the lowest common
     denominator is "std::", and thus would do a partial completion
     with that.  I.e., it would replace "push_ba" in the input buffer
     with "std::", losing the original "push_ba", which is obviously
     undesirable.  To avoid that, such completers pass the substring
     of the match that matters for common denominator computation as
     MATCH_FOR_LCD argument to add_completion.  The end result is
     passed to readline in gdb_rl_attempted_completion_function.

   - The custom word point to hand over to readline, for completers
     that parse the input string in order to dynamically adjust
     themselves depending on exactly what they're completing.  E.g.,
     the linespec completer needs to bypass readline's too-simple word
     breaking algorithm.
*/
class completion_tracker
{
public:
  explicit completion_tracker (bool from_readline);
  ~completion_tracker ();

  DISABLE_COPY_AND_ASSIGN (completion_tracker);

  /* 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,
		       completion_match_for_lcd *match_for_lcd = NULL,
		       const char *text = NULL, const char *word = NULL);

  /* Add all completions matches in LIST.  Elements are moved out of
     LIST.  */
  void add_completions (completion_list &&list);

  /* Remove completion matching NAME from the completion list, does nothing
     if NAME is not already in the completion list.  */
  void remove_completion (const char *name);

  /* Set the quote char to be appended after a unique completion is
     added to the input line.  Set to '\0' to clear.  See
     m_quote_char's description.  */
  void set_quote_char (int quote_char)
  { m_quote_char = quote_char; }

  /* The quote char to be appended after a unique completion is added
     to the input line.  Returns '\0' if no quote char has been set.
     See m_quote_char's description.  */
  int quote_char () { return m_quote_char; }

  /* Tell the tracker that the current completer wants to provide a
     custom word point instead of a list of a break chars, in the
     handle_brkchars phase.  Such completers must also compute their
     completions then.  */
  void set_use_custom_word_point (bool enable)
  { m_use_custom_word_point = enable; }

  /* Whether the current completer computes a custom word point.  */
  bool use_custom_word_point () const
  { return m_use_custom_word_point; }

  /* The custom word point.  */
  int custom_word_point () const
  { return m_custom_word_point; }

  /* Set the custom word point to POINT.  */
  void set_custom_word_point (int point)
  { m_custom_word_point = point; }

  /* Advance the custom word point by LEN.  */
  void advance_custom_word_point_by (int len);

  /* Whether to tell readline to skip appending a whitespace after the
     completion.  See m_suppress_append_ws.  */
  bool suppress_append_ws () const
  { return m_suppress_append_ws; }

  /* Set whether to tell readline to skip appending a whitespace after
     the completion.  See m_suppress_append_ws.  */
  void set_suppress_append_ws (bool suppress)
  { m_suppress_append_ws = suppress; }

  /* Return true if we only have one completion, and it matches
     exactly the completion word.  I.e., completing results in what we
     already have.  */
  bool completes_to_completion_word (const char *word);

  /* Get a reference to the shared (between all the multiple symbol
     name comparison calls) completion_match_result object, ready for
     another symbol name match sequence.  */
  completion_match_result &reset_completion_match_result ()
  {
    completion_match_result &res = m_completion_match_result;

    /* Clear any previous match.  */
    res.match.clear ();
    res.match_for_lcd.clear ();
    return m_completion_match_result;
  }

  /* True if we have any completion match recorded.  */
  bool have_completions () const
  { return htab_elements (m_entries_hash.get ()) > 0; }

  /* Discard the current completion match list and the current
     LCD.  */
  void discard_completions ();

  /* 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);

  /* Tells if the completion task is triggered by readline.  See
     m_from_readline.  */
  bool from_readline () const
  { return m_from_readline; }

  /* Set the function used to format the completion word before displaying
     it to the user to F, this is used by the 'complete' command.  */
  void set_match_format_func (completion_result::match_format_func_t f)
  {
    gdb_assert (f != nullptr);
    m_match_format_func = f;
  }

private:

  /* The type that we place into the m_entries_hash hash table.  */
  class completion_hash_entry;

  /* 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,
			     completion_match_for_lcd *match_for_lcd,
			     const char *text, const char *word);

  /* Ensure that the lowest common denominator held in the member variable
     M_LOWEST_COMMON_DENOMINATOR is valid.  This method must be called if
     there is any chance that new completions have been added to the
     tracker before the lowest common denominator is read.  */
  void recompute_lowest_common_denominator ();

  /* Callback used from recompute_lowest_common_denominator, called for
     every entry in m_entries_hash.  */
  void recompute_lcd_visitor (completion_hash_entry *entry);

  /* Completion match outputs returned by the symbol name matching
     routines (see symbol_name_matcher_ftype).  These results are only
     valid for a single match call.  This is here in order to be able
     to conveniently share the same storage among all the calls to the
     symbol name matching routines.  */
  completion_match_result m_completion_match_result;

  /* 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_up m_entries_hash;

  /* If non-zero, then this is the quote char that needs to be
     appended after completion (iff we have a unique completion).  We
     don't rely on readline appending the quote char as delimiter as
     then readline wouldn't append the ' ' after the completion.
     I.e., we want this:

      before tab: "b 'function("
      after tab:  "b 'function()' "
  */
  int m_quote_char = '\0';

  /* If true, the completer has its own idea of "word" point, and
     doesn't want to rely on readline computing it based on brkchars.
     Set in the handle_brkchars phase.  */
  bool m_use_custom_word_point = false;

  /* The completer's idea of where the "word" we were looking at is
     relative to RL_LINE_BUFFER.  This is advanced in the
     handle_brkchars phase as the completer discovers potential
     completable words.  */
  int m_custom_word_point = 0;

  /* If true, tell readline to skip appending a whitespace after the
     completion.  Automatically set if we have a unique completion
     that already has a space at the end.  A completer may also
     explicitly set this.  E.g., the linespec completer sets this when
     the completion ends with the ":" separator between filename and
     function name.  */
  bool m_suppress_append_ws = false;

  /* Our idea of lowest common denominator to hand over to readline.
     See intro.  */
  char *m_lowest_common_denominator = NULL;

  /* If true, the LCD is unique.  I.e., all completions had the same
     MATCH_FOR_LCD substring, even if the completions were different.
     For example, if "break function<tab>" found "a::function()" and
     "b::function()", the LCD will be "function()" in both cases and
     so we want to tell readline to complete the line with
     "function()", instead of showing all the possible
     completions.  */
  bool m_lowest_common_denominator_unique = false;

  /* True if the value in M_LOWEST_COMMON_DENOMINATOR is correct.  This is
     set to true each time RECOMPUTE_LOWEST_COMMON_DENOMINATOR is called,
     and reset to false whenever a new completion is added.  */
  bool m_lowest_common_denominator_valid = false;

  /* To avoid calls to xrealloc in RECOMPUTE_LOWEST_COMMON_DENOMINATOR, we
     track the maximum possible size of the lowest common denominator,
     which we know as each completion is added.  */
  size_t m_lowest_common_denominator_max_length = 0;

  /* Indicates that the completions are to be displayed by readline
     interactively. The 'complete' command is a way to generate completions
     not to be displayed by readline.  */
  bool m_from_readline;

  /* The function used to format the completion word before it is printed
     in the 'complete' command output.  */
  completion_result::match_format_func_t m_match_format_func;
};

/* Return a string to hand off to readline as a completion match
   candidate, potentially composed of parts of MATCH_NAME and of
   TEXT/WORD.  For a description of TEXT/WORD see completer_ftype.  */

extern gdb::unique_xmalloc_ptr<char>
  make_completion_match_str (const char *match_name,
			     const char *text, const char *word);

/* Like above, but takes ownership of MATCH_NAME (i.e., can
   reuse/return it).  */

extern gdb::unique_xmalloc_ptr<char>
  make_completion_match_str (gdb::unique_xmalloc_ptr<char> &&match_name,
			     const char *text, const char *word);

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 void complete_line (completion_tracker &tracker,
			   const char *text,
			   const char *line_buffer,
			   int point);

/* Complete LINE and return completion results.  For completion purposes,
   cursor position is assumed to be at the end of LINE.  WORD is set to
   the end of word to complete.  QUOTE_CHAR is set to the opening quote
   character if we found an unclosed quoted substring, '\0' otherwise.  */
extern completion_result
  complete (const char *line, char const **word, int *quote_char);

/* Assuming TEXT is an expression in the current language, find the
   completion word point for TEXT, emulating the algorithm readline
   uses to find the word point, using the current language's word
   break characters.  */
const char *advance_to_expression_complete_word_point
  (completion_tracker &tracker, const char *text);

/* Assuming TEXT is a filename, find the completion word point for TEXT,
   emulating the algorithm readline uses to find the word point.  The
   filenames that are located by this function assume no filename
   quoting, this function should be paired with filename_completer.  */
extern const char *advance_to_deprecated_filename_complete_word_point
  (completion_tracker &tracker, const char *text);

/* Assuming TEXT is a filename, find the completion word point for TEXT,
   emulating the algorithm readline uses to find the word point.  The
   filenames that are located by this function assume that filenames
   can be quoted, this function should be paired with
   filename_maybe_quoted_completer.  */
extern const char *advance_to_filename_maybe_quoted_complete_word_point
  (completion_tracker &tracker, const char *text);

extern void noop_completer (struct cmd_list_element *,
			    completion_tracker &tracker,
			    const char *, const char *);

/* Filename completer for commands that don't accept quoted filenames.
   This completer does support completing a list of filenames that are
   separated with the path separator (':' for UNIX and ';' for MS-DOS).

   When adding a new command it is better to write the command so it
   accepts quoted filenames and use filename_maybe_quoted_completer, for
   examples see the 'exec' and 'exec-file' commands.  */

extern void deprecated_filename_completer
  (struct cmd_list_element *, completion_tracker &tracker,
   const char *, const char *);

/* Filename completer for commands where the filename argument can be
   quoted.  This completer also supports completing a list of filenames
   that are separated with the path separator (':' for UNIX and ';' for
   MS-DOS).  */

extern void filename_maybe_quoted_completer (struct cmd_list_element *,
					     completion_tracker &tracker,
					     const char *, const char *);

extern void expression_completer (struct cmd_list_element *,
				  completion_tracker &tracker,
				  const char *, const char *);

extern void location_completer (struct cmd_list_element *,
				completion_tracker &tracker,
				const char *, const char *);

extern void symbol_completer (struct cmd_list_element *,
			      completion_tracker &tracker,
			      const char *, const char *);

extern void command_completer (struct cmd_list_element *,
			       completion_tracker &tracker,
			       const char *, const char *);

extern void signal_completer (struct cmd_list_element *,
			      completion_tracker &tracker,
			      const char *, const char *);

extern void reg_or_group_completer (struct cmd_list_element *,
				    completion_tracker &tracker,
				    const char *, const char *);

extern void reggroup_completer (struct cmd_list_element *,
				completion_tracker &tracker,
				const char *, const char *);

/* Get the matching completer_handle_brkchars_ftype function for FN.
   FN is one of the core completer functions above (filename,
   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).  */

extern completer_handle_brkchars_ftype *
  completer_handle_brkchars_func_for_completer (completer_ftype *fn);

/* Exported to linespec.c */

/* Return a list of all source files whose names begin with matching
   TEXT.  */
extern completion_list complete_source_filenames (const char *text);

/* Complete on expressions.  Often this means completing on symbol
   names, but some language parsers also have support for completing
   field names.  */
extern void complete_expression (completion_tracker &tracker,
				 const char *text, const char *word);

/* Called by custom word point completers that want to recurse into
   the completion machinery to complete a command.  Used to complete
   COMMAND in "thread apply all COMMAND", for example.  Note that
   unlike command_completer, this fully recurses into the proper
   completer for COMMAND, so that e.g.,

     (gdb) thread apply all print -[TAB]

   does the right thing and show the print options.  */
extern void complete_nested_command_line (completion_tracker &tracker,
					  const char *text);

/* Called from command completion function to skip over /FMT
   specifications, allowing the rest of the line to be completed.  Returns
   true if the /FMT is at the end of the current line and there is nothing
   left to complete, otherwise false is returned.

   In either case *ARGS can be updated to point after any part of /FMT that
   is present.

   This function is designed so that trying to complete '/' will offer no
   completions, the user needs to insert the format specification
   themselves.  Trying to complete '/FMT' (where FMT is any non-empty set
   of alphanumeric characters) will cause readline to insert a single
   space, setting the user up to enter the expression.  */

extern bool skip_over_slash_fmt (completion_tracker &tracker,
				 const char **args);

/* Maximum number of candidates to consider before the completer
   bails by throwing MAX_COMPLETIONS_REACHED_ERROR.  Negative values
   disable limiting.  */

extern int max_completions;

#endif /* GDB_COMPLETER_H */
