/* Header for GDB line completion.
   Copyright (C) 2000-2019 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/>.  */

#if !defined (COMPLETER_H)
#define COMPLETER_H 1

#include "common/gdb_vecs.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)
  { 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 ();

	const char *prev = m_match;
	for (const auto &range : m_ignored_ranges)
	  {
	    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 ();
  }

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
{
  /* 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_COPY_AND_ASSIGN (completion_result);

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

   - 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:
  completion_tracker ();
  ~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);

  /* 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 (size_t 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 !m_entries_vec.empty (); }

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

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

  /* Given a new match, recompute the lowest common denominator (LCD)
     to hand over to readline.  Normally readline computes this itself
     based on the whole set of completion matches.  However, some
     completers want to override readline, in order to be able to
     provide a LCD that is not really a prefix of the matches, but the
     lowest common denominator of some relevant substring of each
     match.  E.g., "b push_ba" completes to
     "std::vector<..>::push_back", "std::string::push_back", etc., and
     in this case we want the lowest common denominator to be
     "push_back" instead of "std::".  */
  void recompute_lowest_common_denominator
    (gdb::unique_xmalloc_ptr<char> &&new_match);

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

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

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

/* Find the bounds of the word in TEXT for completion purposes, and
   return a pointer to the end of the word.  Calls the completion
   machinery for a handle_brkchars phase (using TRACKER) to figure out
   the right work break characters for the command in TEXT.
   QUOTE_CHAR, if non-null, is set to the opening quote character if
   we found an unclosed quoted substring, '\0' otherwise.  */
extern const char *completion_find_completion_word (completion_tracker &tracker,
						    const char *text,
						    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);

extern char **gdb_rl_attempted_completion_function (const char *text,
						    int start, int end);

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

extern void filename_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 *);

extern const char *get_gdb_completer_quote_characters (void);

extern char *gdb_completion_word_break_characters (void);

/* Set the word break characters array to BREAK_CHARS.  This function
   is useful as const-correct alternative to direct assignment to
   rl_completer_word_break_characters, which is "char *",
   not "const char *".  */
extern void set_rl_completer_word_break_characters (const char *break_chars);

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

extern const char *skip_quoted_chars (const char *, const char *,
				      const char *);

extern const char *skip_quoted (const char *);

/* 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 /* defined (COMPLETER_H) */
