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