/* Line completion stuff for GDB, the GNU debugger.
   Copyright (C) 2000-2025 Free Software Foundation, Inc.

   This file is part of GDB.

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

#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "filenames.h"
#include "language.h"
#include "gdbsupport/gdb_signals.h"
#include "target.h"
#include "reggroups.h"
#include "user-regs.h"
#include "arch-utils.h"
#include "location.h"
#include <algorithm>
#include "linespec.h"
#include "cli/cli-decode.h"
#include "gdbsupport/gdb_tilde_expand.h"
#include "readline/readline.h"

/* FIXME: This is needed because of lookup_cmd_1 ().  We should be
   calling a hook instead so we eliminate the CLI dependency.  */
#include "cli/cli-cmds.h"

/* Needed for rl_completer_word_break_characters and for
   rl_filename_completion_function.  */
#include "readline/readline.h"

/* readline defines this.  */
#undef savestring

#include "completer.h"

/* Forward declarations.  */
static const char *completion_find_completion_word (completion_tracker &tracker,
						    const char *text,
						    int *quote_char,
						    bool *found_any_quoting);

static void set_rl_completer_word_break_characters (const char *break_chars);

static bool gdb_path_isdir (const char *filename);

/* See completer.h.  */

class completion_tracker::completion_hash_entry
{
public:
  /* Constructor.  */
  completion_hash_entry (gdb::unique_xmalloc_ptr<char> name,
			 gdb::unique_xmalloc_ptr<char> lcd)
    : m_name (std::move (name)),
      m_lcd (std::move (lcd))
  {
    /* Nothing.  */
  }

  /* Returns a pointer to the lowest common denominator string.  This
     string will only be valid while this hash entry is still valid as the
     string continues to be owned by this hash entry and will be released
     when this entry is deleted.  */
  char *get_lcd () const
  {
    return m_lcd.get ();
  }

  /* Get, and release the name field from this hash entry.  This can only
     be called once, after which the name field is no longer valid.  This
     should be used to pass ownership of the name to someone else.  */
  char *release_name ()
  {
    return m_name.release ();
  }

  /* Return true of the name in this hash entry is STR.  */
  bool is_name_eq (const char *str) const
  {
    return strcmp (m_name.get (), str) == 0;
  }

  /* Return the hash value based on the name of the entry.  */
  hashval_t hash_name () const
  {
    return htab_hash_string (m_name.get ());
  }

private:

  /* The symbol name stored in this hash entry.  */
  gdb::unique_xmalloc_ptr<char> m_name;

  /* The lowest common denominator string computed for this hash entry.  */
  gdb::unique_xmalloc_ptr<char> m_lcd;
};

/* Misc state that needs to be tracked across several different
   readline completer entry point calls, all related to a single
   completion invocation.  */

struct gdb_completer_state
{
  /* The current completion's completion tracker.  This is a global
     because a tracker can be shared between the handle_brkchars and
     handle_completion phases, which involves different readline
     callbacks.  */
  completion_tracker *tracker = NULL;

  /* Whether the current completion was aborted.  */
  bool aborted = false;
};

/* The current completion state.  */
static gdb_completer_state current_completion;

/* An enumeration of the various things a user might attempt to
   complete for a location.  If you change this, remember to update
   the explicit_options array below too.  */

enum explicit_location_match_type
{
    /* The filename of a source file.  */
    MATCH_SOURCE,

    /* The name of a function or method.  */
    MATCH_FUNCTION,

    /* The fully-qualified name of a function or method.  */
    MATCH_QUALIFIED,

    /* A line number.  */
    MATCH_LINE,

    /* The name of a label.  */
    MATCH_LABEL
};

/* Prototypes for local functions.  */

/* readline uses the word breaks for two things:
   (1) In figuring out where to point the TEXT parameter to the
   rl_completion_entry_function.  Since we don't use TEXT for much,
   it doesn't matter a lot what the word breaks are for this purpose,
   but it does affect how much stuff M-? lists.
   (2) If one of the matches contains a word break character, readline
   will quote it.  That's why we switch between
   current_language->word_break_characters () and
   gdb_completer_command_word_break_characters.  I'm not sure when
   we need this behavior (perhaps for funky characters in C++ 
   symbols?).  */

/* Variables which are necessary for fancy command line editing.  */

/* When completing on command names, we remove '-' and '.' from the list of
   word break characters, since we use it in command names.  If the
   readline library sees one in any of the current completion strings,
   it thinks that the string needs to be quoted and automatically
   supplies a leading quote.  */
static const char gdb_completer_command_word_break_characters[] =
" \t\n!@#$%^&*()+=|~`}{[]\"';:?/><,";

/* When completing on file names, we remove from the list of word
   break characters any characters that are commonly used in file
   names, such as '-', '+', '~', etc.  Otherwise, readline displays
   incorrect completion candidates.  */
/* MS-DOS and MS-Windows use colon as part of the drive spec, and most
   programs support @foo style response files.  */
static const char gdb_completer_file_name_break_characters[] =
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
  " \t\n*|\"';?><@";
#else
  " \t\n*|\"';:?><";
#endif

/* When completing on file names, for commands that don't accept quoted
   file names, the only character that can be used as a word separator is
   the path separator.  Every other character is treated as a literal
   character within the filename.  */
static const char gdb_completer_path_break_characters[] =
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
  ";";
#else
  ":";
#endif

/* Characters that can be used to quote expressions.  Note that we can't
   include '"' (double quote) because the gdb C parser treats such quoted
   sequences as strings.  */
static const char gdb_completer_expression_quote_characters[] = "'";

/* Characters that can be used to quote file names.  We do allow '"'
   (double quotes) in this set as file names are not passed through the C
   expression parser.  */
static const char gdb_completer_file_name_quote_characters[] = "'\"";


/* This can be used for functions which don't want to complete on
   symbols but don't want to complete on anything else either.  */

void
noop_completer (struct cmd_list_element *ignore, 
		completion_tracker &tracker,
		const char *text, const char *prefix)
{
}

/* Return 1 if the character at EINDEX in STRING is quoted (there is an
   unclosed quoted string), or if the character at EINDEX is quoted by a
   backslash.  */

static int
gdb_completer_file_name_char_is_quoted (char *string, int eindex)
{
  for (int i = 0; i <= eindex && string[i] != '\0'; )
    {
      char c = string[i];

      if (c == '\\')
	{
	  /* The backslash itself is not quoted.  */
	  if (i >= eindex)
	    return 0;
	  ++i;
	  /* But the next character is.  */
	  if (i >= eindex)
	    return 1;
	  if (string[i] == '\0')
	    return 0;
	  ++i;
	  continue;
	}
      else if (strchr (rl_completer_quote_characters, c) != nullptr)
	{
	  /* This assumes that extract_string_maybe_quoted can handle a
	     string quoted with character C.  Currently this is true as the
	     only characters we put in rl_completer_quote_characters are
	     single and/or double quotes, both of which
	     extract_string_maybe_quoted can handle.  */
	  gdb_assert (c == '"' || c == '\'');
	  const char *tmp = &string[i];
	  (void) extract_string_maybe_quoted (&tmp);
	  i = tmp - string;

	  /* Consider any character within the string we just skipped over
	     as quoted, though this might not be completely correct; the
	     opening and closing quotes are not themselves quoted.  But so
	     far this doesn't seem to have caused any issues.  */
	  if (i > eindex)
	    return 1;
	}
      else
	++i;
    }

  return 0;
}

/* Removing character escaping from FILENAME.  QUOTE_CHAR is the quote
   character around FILENAME or the null-character if there is no quoting
   around FILENAME.  */

static char *
gdb_completer_file_name_dequote (char *filename, int quote_char)
{
  std::string tmp;

  if (quote_char == '\'')
    {
      /* There is no backslash escaping within a single quoted string.  In
	 this case we can just return the input string.  */
      tmp = filename;
    }
  else if (quote_char == '"')
    {
      /* Remove escaping from a double quoted string.  */
      for (const char *input = filename;
	   *input != '\0';
	   ++input)
	{
	  if (input[0] == '\\'
	      && input[1] != '\0'
	      && strchr ("\"\\", input[1]) != nullptr)
	    ++input;
	  tmp += *input;
	}
    }
  else
    {
      gdb_assert (quote_char == '\0');

      /* Remove escaping from an unquoted string.  */
      for (const char *input = filename;
	   *input != '\0';
	   ++input)
	{
	  /* We allow anything to be escaped in an unquoted string.  */
	  if (*input == '\\')
	    {
	      ++input;
	      if (*input == '\0')
		break;
	    }

	  tmp += *input;
	}
    }

  return strdup (tmp.c_str ());
}

/* Implement readline's rl_directory_rewrite_hook.  Remove any quoting from
   the string *DIRNAME,update *DIRNAME, and return non-zero.  If *DIRNAME
   doesn't need updating then return zero.  See readline docs for more
   information.  */

static int
gdb_completer_directory_rewrite (char **dirname)
{
  if (!rl_completion_found_quote)
    return 0;

  int quote_char = rl_completion_quote_character;
  char *new_dirname
    = gdb_completer_file_name_dequote (*dirname, quote_char);
  free (*dirname);
  *dirname = new_dirname;

  return 1;
}

/* Apply character escaping to the filename in TEXT and return a newly
   allocated buffer containing the possibly updated filename.

   QUOTE_CHAR is the quote character surrounding TEXT, or the
   null-character if there are no quotes around TEXT.  */

static char *
gdb_completer_file_name_quote_1 (const char *text, char quote_char)
{
  std::string str;

  if (quote_char == '\'')
    {
      /* There is no backslash escaping permitted within a single quoted
	 string, so in this case we can just return the input string.  */
      str = text;
    }
  else if (quote_char == '"')
    {
      /* Add escaping for a double quoted filename.  */
      for (const char *input = text;
	   *input != '\0';
	   ++input)
	{
	  if (strchr ("\"\\", *input) != nullptr)
	    str += '\\';
	  str += *input;
	}
    }
  else
    {
      gdb_assert (quote_char == '\0');

      /* Add escaping for an unquoted filename.  */
      for (const char *input = text;
	   *input != '\0';
	   ++input)
	{
	  if (strchr (" \t\n\\\"'", *input)
	      != nullptr)
	    str += '\\';
	  str += *input;
	}
    }

  return strdup (str.c_str ());
}

/* Apply character escaping to the filename in TEXT.  QUOTE_PTR points to
   the quote character surrounding TEXT, or points to the null-character if
   there are no quotes around TEXT.  MATCH_TYPE will be one of the readline
   constants SINGLE_MATCH or MULTI_MATCH depending on if there is one or
   many completions.

   We also add a trailing character, either a '/' of closing quote, if
   MATCH_TYPE is 'SINGLE_MATCH'.  We do this because readline will only
   add this trailing character when completing at the end of a line.  */

static char *
gdb_completer_file_name_quote (char *text, int match_type, char *quote_ptr)
{
  char *result = gdb_completer_file_name_quote_1 (text, *quote_ptr);

  if (match_type == SINGLE_MATCH)
    {
      /* Add trailing '/' if TEXT is a directory, otherwise add a closing
	 quote character matching *QUOTE_PTR.  */
      char c = (gdb_path_isdir (gdb_tilde_expand (text).c_str ())
		? '/' : *quote_ptr);

      /* Reallocate RESULT adding C to the end.  But only if C is
	 interesting, otherwise we can save the reallocation.  */
      if (c != '\0')
	{
	  char buf[2] = { c, '\0' };
	  result = reconcat (result, result, buf, nullptr);
	}
    }

  return result;
}

/* The function is used to update the completion word MATCH before
   displaying it to the user in the 'complete' command output.  This
   function is only used for formatting filename or directory names.

   This function checks to see if the completion word MATCH is a directory,
   in which case a trailing "/" (forward-slash) is added, otherwise
   QUOTE_CHAR is added as a trailing quote.

   When ADD_ESCAPES is true any special characters (e.g. whitespace,
   quotes) will be escaped with a backslash.  See
   gdb_completer_file_name_quote_1 for full details on escaping.  When
   ADD_ESCAPES is false then no escaping will be added and MATCH (with the
   correct trailing character) will be used unmodified.

   Return the updated completion word as a string.  */

static std::string
filename_match_formatter_1 (const char *match, char quote_char,
			    bool add_escapes)
{
  std::string result;
  if (add_escapes)
    {
      gdb::unique_xmalloc_ptr<char> quoted_match
	(gdb_completer_file_name_quote_1 (match, quote_char));
      result = quoted_match.get ();
    }
  else
    result = match;

  if (gdb_path_isdir (gdb_tilde_expand (match).c_str ()))
    result += "/";
  else
    result += quote_char;

  return result;
}

/* The formatting function used to format the results of a 'complete'
   command when the result is a filename, but the filename should not have
   any escape characters added.  Most commands that accept a filename don't
   expect the filename to be quoted or to contain escape characters.

   See filename_match_formatter_1 for more argument details.  */

static std::string
filename_unquoted_match_formatter (const char *match, char quote_char)
{
  return filename_match_formatter_1 (match, quote_char, false);
}

/* The formatting function used to format the results of a 'complete'
   command when the result is a filename, and the filename should have any
   special character (e.g. whitespace, quotes) within it escaped with a
   backslash.  A limited number of commands accept this style of filename
   argument.

   See filename_match_formatter_1 for more argument details.  */

static std::string
filename_maybe_quoted_match_formatter (const char *match, char quote_char)
{
  return filename_match_formatter_1 (match, quote_char, true);
}

/* Generate filename completions of WORD, storing the completions into
   TRACKER.  This is used for generating completions for commands that
   only accept unquoted filenames as well as for commands that accept
   quoted and escaped filenames.

   When QUOTE_MATCHES is true TRACKER will be given a match formatter
   function which will add escape characters (if needed) in the results.
   When QUOTE_MATCHES is false the match formatter provided will not add
   any escaping to the results.  */

static void
filename_completer_generate_completions (completion_tracker &tracker,
					 const char *word,
					 bool quote_matches)
{
  if (quote_matches)
    tracker.set_match_format_func (filename_maybe_quoted_match_formatter);
  else
    tracker.set_match_format_func (filename_unquoted_match_formatter);

  int subsequent_name = 0;
  while (1)
    {
      gdb::unique_xmalloc_ptr<char> p_rl
	(rl_filename_completion_function (word, subsequent_name));
      if (p_rl == NULL)
	break;
      /* We need to set subsequent_name to a non-zero value before the
	 continue line below, because otherwise, if the first file
	 seen by GDB is a backup file whose name ends in a `~', we
	 will loop indefinitely.  */
      subsequent_name = 1;
      /* Like emacs, don't complete on old versions.  Especially
	 useful in the "source" command.  */
      const char *p = p_rl.get ();
      if (p[strlen (p) - 1] == '~')
	continue;

      tracker.add_completion
	(make_completion_match_str (std::move (p_rl), word, word));
    }
}

/* The brkchars callback used when completing filenames that can be
   quoted.  */

static void
filename_maybe_quoted_completer_handle_brkchars
	(struct cmd_list_element *ignore, completion_tracker &tracker,
	 const char *text, const char *word)
{
  set_rl_completer_word_break_characters
    (gdb_completer_file_name_break_characters);

  rl_completer_quote_characters = gdb_completer_file_name_quote_characters;
  rl_char_is_quoted_p = gdb_completer_file_name_char_is_quoted;
}

/* Complete on filenames.  This is for commands that accepts possibly
   quoted filenames.  */

void
filename_maybe_quoted_completer (struct cmd_list_element *ignore,
				 completion_tracker &tracker,
				 const char *text, const char *word)
{
  filename_maybe_quoted_completer_handle_brkchars (ignore, tracker,
						   text, word);
  filename_completer_generate_completions (tracker, word, true);
}

/* The brkchars callback used by commands that don't accept quoted
   filenames.  */

static void
deprecated_filename_completer_handle_brkchars
	(struct cmd_list_element *ignore, completion_tracker &tracker,
	 const char *text, const char *word)
{
  gdb_assert (word == nullptr);

  set_rl_completer_word_break_characters (gdb_completer_path_break_characters);
  rl_completer_quote_characters = nullptr;
  rl_filename_quoting_desired = 0;

  tracker.set_use_custom_word_point (true);
  word = advance_to_deprecated_filename_complete_word_point (tracker, text);
  deprecated_filename_completer (ignore, tracker, text, word);
}

/* See completer.h.  */

void
deprecated_filename_completer
	(struct cmd_list_element *ignore, completion_tracker &tracker,
	 const char *text, const char *word)
{
  gdb_assert (tracker.use_custom_word_point ());
  gdb_assert (word != nullptr);
  filename_completer_generate_completions (tracker, word, false);
}

/* Find the bounds of the current word for completion purposes, and
   return a pointer to the end of the word.  This mimics (and is a
   modified version of) readline's _rl_find_completion_word internal
   function.

   This function skips quoted substrings (characters between matched
   pairs of characters in rl_completer_quote_characters).  We try to
   find an unclosed quoted substring on which to do matching.  If one
   is not found, we use the word break characters to find the
   boundaries of the current word.  QC, if non-null, is set to the
   opening quote character if we found an unclosed quoted substring,
   '\0' otherwise.  DP, if non-null, is set to the value of the
   delimiter character that caused a word break.  FOUND_ANY_QUOTING, if
   non-null, is set to true if we found any quote characters (single or
   double quotes, or a backslash) while finding the completion word.  */

struct gdb_rl_completion_word_info
{
  const char *word_break_characters;
  const char *quote_characters;
  const char *basic_quote_characters;
};

static const char *
gdb_rl_find_completion_word (struct gdb_rl_completion_word_info *info,
			     int *qc, int *dp, bool *found_any_quoting,
			     const char *line_buffer)
{
  int scan, end, delimiter, pass_next, isbrk;
  char quote_char;
  const char *brkchars;
  int point = strlen (line_buffer);

  /* The algorithm below does '--point'.  Avoid buffer underflow with
     the empty string.  */
  if (point == 0)
    {
      if (found_any_quoting != nullptr)
	*found_any_quoting = false;
      if (qc != NULL)
	*qc = '\0';
      if (dp != NULL)
	*dp = '\0';
      return line_buffer;
    }

  end = point;
  delimiter = 0;
  quote_char = '\0';
  bool found_quote = false;

  brkchars = info->word_break_characters;

  if (info->quote_characters != NULL)
    {
      /* We have a list of characters which can be used in pairs to
	 quote substrings for the completer.  Try to find the start of
	 an unclosed quoted substring.  */
      for (scan = pass_next = 0;
	   scan < end;
	   scan++)
	{
	  if (pass_next)
	    {
	      pass_next = 0;
	      continue;
	    }

	  /* Shell-like semantics for single quotes -- don't allow
	     backslash to quote anything in single quotes, especially
	     not the closing quote.  If you don't like this, take out
	     the check on the value of quote_char.  */
	  if (quote_char != '\'' && line_buffer[scan] == '\\')
	    {
	      pass_next = 1;
	      found_quote = true;
	      continue;
	    }

	  if (quote_char != '\0')
	    {
	      /* Ignore everything until the matching close quote
		 char.  */
	      if (line_buffer[scan] == quote_char)
		{
		  /* Found matching close.  Abandon this
		     substring.  */
		  quote_char = '\0';
		  point = end;
		}
	    }
	  else if (strchr (info->quote_characters, line_buffer[scan]))
	    {
	      /* Found start of a quoted substring.  */
	      quote_char = line_buffer[scan];
	      point = scan + 1;
	      found_quote = true;
	    }
	}
    }

  if (point == end && quote_char == '\0')
    {
      /* We didn't find an unclosed quoted substring upon which to do
	 completion, so use the word break characters to find the
	 substring on which to complete.  */
      while (--point)
	{
	  scan = line_buffer[point];

	  if (strchr (brkchars, scan) == 0)
	    continue;

	  /* Call the application-specific function to tell us whether
	     this word break character is quoted and should be skipped.
	     The const_cast is needed here to comply with the readline
	     API.  The only function we register for rl_char_is_quoted_p
	     treats the input buffer as 'const', so we're OK.  */
	  if (rl_char_is_quoted_p != nullptr && found_quote
	      && (*rl_char_is_quoted_p) (const_cast<char *> (line_buffer),
					 point))
	    continue;

	  /* Convoluted code, but it avoids an n^2 algorithm with calls
	     to char_is_quoted.  */
	  break;
	}
    }

  /* If we are at an unquoted word break, then advance past it.  */
  scan = line_buffer[point];

  if (scan)
    {
      isbrk = strchr (brkchars, scan) != 0;

      if (isbrk)
	{
	  /* If the character that caused the word break was a quoting
	     character, then remember it as the delimiter.  */
	  if (info->basic_quote_characters
	      && strchr (info->basic_quote_characters, scan)
	      && (end - point) > 1)
	    delimiter = scan;

	  point++;
	}
    }

  if (found_any_quoting != nullptr)
    *found_any_quoting = found_quote;
  if (qc != NULL)
    *qc = quote_char;
  if (dp != NULL)
    *dp = delimiter;

  return line_buffer + point;
}

/* Find the completion word point for TEXT, emulating the algorithm
   readline uses to find the word point, using WORD_BREAK_CHARACTERS
   as word break characters.

   The output argument *FOUND_ANY_QUOTING is set to true if the completion
   word found either has an opening quote, or contains backslash escaping
   within it.  Otherwise *FOUND_ANY_QUOTING is set to false.

   The output argument *QC is set to the opening quote character for the
   completion word that is found, or to the null character if there is no
   opening quote.  */

static const char *
advance_to_completion_word (completion_tracker &tracker,
			    const char *word_break_characters,
			    const char *quote_characters,
			    const char *text,
			    bool *found_any_quoting,
			    int *qc)
{
  gdb_rl_completion_word_info info;

  info.word_break_characters = word_break_characters;
  info.quote_characters = quote_characters;
  info.basic_quote_characters = rl_basic_quote_characters;

  int delimiter;
  const char *start
    = gdb_rl_find_completion_word (&info, qc, &delimiter, found_any_quoting,
				   text);

  tracker.advance_custom_word_point_by (start - text);

  if (delimiter)
    {
      tracker.set_quote_char (delimiter);
      tracker.set_suppress_append_ws (true);
    }

  return start;
}

/* See completer.h.  */

const char *
advance_to_expression_complete_word_point (completion_tracker &tracker,
					   const char *text)
{
  const char *brk_chars = current_language->word_break_characters ();
  const char *quote_chars = gdb_completer_expression_quote_characters;
  return advance_to_completion_word (tracker, brk_chars, quote_chars,
				     text, nullptr, nullptr);
}

/* See completer.h.  */

const char *
advance_to_filename_maybe_quoted_complete_word_point
  (completion_tracker &tracker, const char *text)
{
  const char *brk_chars = gdb_completer_file_name_break_characters;
  const char *quote_chars = gdb_completer_file_name_quote_characters;
  rl_char_is_quoted_p = gdb_completer_file_name_char_is_quoted;
  bool found_any_quoting = false;
  int qc;
  const char *result
    = advance_to_completion_word (tracker, brk_chars, quote_chars,
				  text, &found_any_quoting, &qc);
  rl_completion_found_quote = found_any_quoting ? 1 : 0;
  if (qc != '\0')
    {
      tracker.set_quote_char (qc);
      /* If we're completing for readline (not the 'complete' command) then
	 we want readline to correctly detect the opening quote.  The set
	 of quote characters will have been set during the brkchars phase,
	 so now we move the word point back by one (so it's pointing at
	 the quote character) and now readline will correctly spot the
	 opening quote.  For the 'complete' command setting the quote
	 character in the tracker is enough, so there's no need to move
	 the word point back here.  */
      if (tracker.from_readline ())
	tracker.advance_custom_word_point_by (-1);
    }
  return result;
}

/* See completer.h.  */

const char *
advance_to_deprecated_filename_complete_word_point (completion_tracker &tracker,
						    const char *text)
{
  const char *brk_chars = gdb_completer_path_break_characters;
  const char *quote_chars = nullptr;
  rl_filename_quoting_desired = 0;

  return advance_to_completion_word (tracker, brk_chars, quote_chars,
				     text, nullptr, nullptr);
}

/* See completer.h.  */

bool
completion_tracker::completes_to_completion_word (const char *word)
{
  recompute_lowest_common_denominator ();
  if (m_lowest_common_denominator_unique)
    {
      const char *lcd = m_lowest_common_denominator;

      if (strncmp_iw (word, lcd, strlen (lcd)) == 0)
	{
	  /* Maybe skip the function and complete on keywords.  */
	  size_t wordlen = strlen (word);
	  if (word[wordlen - 1] == ' ')
	    return true;
	}
    }

  return false;
}

/* See completer.h.  */

void
complete_nested_command_line (completion_tracker &tracker, const char *text)
{
  /* Must be called from a custom-word-point completer.  */
  gdb_assert (tracker.use_custom_word_point ());

  /* Disable the custom word point temporarily, because we want to
     probe whether the command we're completing itself uses a custom
     word point.  */
  tracker.set_use_custom_word_point (false);
  size_t save_custom_word_point = tracker.custom_word_point ();

  int quote_char = '\0';
  const char *word = completion_find_completion_word (tracker, text,
						      &quote_char,
						      nullptr);

  if (tracker.use_custom_word_point ())
    {
      /* The command we're completing uses a custom word point, so the
	 tracker already contains the matches.  We're done.  */
      return;
    }

  /* Restore the custom word point settings.  */
  tracker.set_custom_word_point (save_custom_word_point);
  tracker.set_use_custom_word_point (true);

  /* Run the handle_completions completer phase.  */
  complete_line (tracker, word, text, strlen (text));
}

/* Complete on linespecs, which might be of two possible forms:

       file:line
   or
       symbol+offset

   This is intended to be used in commands that set breakpoints
   etc.  */

static void
complete_files_symbols (completion_tracker &tracker,
			const char *text, const char *word)
{
  completion_list fn_list;
  const char *p;
  int quote_found = 0;
  int quoted = *text == '\'' || *text == '"';
  int quote_char = '\0';
  const char *colon = NULL;
  char *file_to_match = NULL;
  const char *symbol_start = text;
  const char *orig_text = text;

  /* Do we have an unquoted colon, as in "break foo.c:bar"?  */
  for (p = text; *p != '\0'; ++p)
    {
      if (*p == '\\' && p[1] == '\'')
	p++;
      else if (*p == '\'' || *p == '"')
	{
	  quote_found = *p;
	  quote_char = *p++;
	  while (*p != '\0' && *p != quote_found)
	    {
	      if (*p == '\\' && p[1] == quote_found)
		p++;
	      p++;
	    }

	  if (*p == quote_found)
	    quote_found = 0;
	  else
	    break;		/* Hit the end of text.  */
	}
#if HAVE_DOS_BASED_FILE_SYSTEM
      /* If we have a DOS-style absolute file name at the beginning of
	 TEXT, and the colon after the drive letter is the only colon
	 we found, pretend the colon is not there.  */
      else if (p < text + 3 && *p == ':' && p == text + 1 + quoted)
	;
#endif
      else if (*p == ':' && !colon)
	{
	  colon = p;
	  symbol_start = p + 1;
	}
      else if (strchr (current_language->word_break_characters (), *p))
	symbol_start = p + 1;
    }

  if (quoted)
    text++;

  /* Where is the file name?  */
  if (colon)
    {
      char *s;

      file_to_match = (char *) xmalloc (colon - text + 1);
      strncpy (file_to_match, text, colon - text);
      file_to_match[colon - text] = '\0';
      /* Remove trailing colons and quotes from the file name.  */
      for (s = file_to_match + (colon - text);
	   s > file_to_match;
	   s--)
	if (*s == ':' || *s == quote_char)
	  *s = '\0';
    }
  /* If the text includes a colon, they want completion only on a
     symbol name after the colon.  Otherwise, we need to complete on
     symbols as well as on files.  */
  if (colon)
    {
      collect_file_symbol_completion_matches (tracker,
					      complete_symbol_mode::EXPRESSION,
					      symbol_name_match_type::EXPRESSION,
					      symbol_start, word,
					      file_to_match);
      xfree (file_to_match);
    }
  else
    {
      size_t text_len = strlen (text);

      collect_symbol_completion_matches (tracker,
					 complete_symbol_mode::EXPRESSION,
					 symbol_name_match_type::EXPRESSION,
					 symbol_start, word);
      /* If text includes characters which cannot appear in a file
	 name, they cannot be asking for completion on files.  */
      if (strcspn (text, gdb_completer_file_name_break_characters)
	  == text_len)
	fn_list = make_source_files_completion_list (text);
    }

  if (!fn_list.empty () && !tracker.have_completions ())
    {
      /* If we only have file names as possible completion, we should
	 bring them in sync with what rl_complete expects.  The
	 problem is that if the user types "break /foo/b TAB", and the
	 possible completions are "/foo/bar" and "/foo/baz"
	 rl_complete expects us to return "bar" and "baz", without the
	 leading directories, as possible completions, because `word'
	 starts at the "b".  But we ignore the value of `word' when we
	 call make_source_files_completion_list above (because that
	 would not DTRT when the completion results in both symbols
	 and file names), so make_source_files_completion_list returns
	 the full "/foo/bar" and "/foo/baz" strings.  This produces
	 wrong results when, e.g., there's only one possible
	 completion, because rl_complete will prepend "/foo/" to each
	 candidate completion.  The loop below removes that leading
	 part.  */
      for (const auto &fn_up: fn_list)
	{
	  char *fn = fn_up.get ();
	  memmove (fn, fn + (word - text), strlen (fn) + 1 - (word - text));
	}
    }

  tracker.add_completions (std::move (fn_list));

  if (!tracker.have_completions ())
    {
      /* No completions at all.  As the final resort, try completing
	 on the entire text as a symbol.  */
      collect_symbol_completion_matches (tracker,
					 complete_symbol_mode::EXPRESSION,
					 symbol_name_match_type::EXPRESSION,
					 orig_text, word);
    }
}

/* See completer.h.  */

completion_list
complete_source_filenames (const char *text)
{
  size_t text_len = strlen (text);

  /* If text includes characters which cannot appear in a file name,
     the user cannot be asking for completion on files.  */
  if (strcspn (text, gdb_completer_file_name_break_characters)
      == text_len)
    return make_source_files_completion_list (text);

  return {};
}

/* Complete address and linespec locations.  */

static void
complete_address_and_linespec_locations (completion_tracker &tracker,
					 const char *text,
					 symbol_name_match_type match_type)
{
  if (*text == '*')
    {
      tracker.advance_custom_word_point_by (1);
      text++;
      const char *word
	= advance_to_expression_complete_word_point (tracker, text);
      complete_expression (tracker, text, word);
    }
  else
    {
      linespec_complete (tracker, text, match_type);
    }
}

/* The explicit location options.  Note that indexes into this array
   must match the explicit_location_match_type enumerators.  */

static const char *const explicit_options[] =
  {
    "-source",
    "-function",
    "-qualified",
    "-line",
    "-label",
    NULL
  };

/* The probe modifier options.  These can appear before a location in
   breakpoint commands.  */
static const char *const probe_options[] =
  {
    "-probe",
    "-probe-stap",
    "-probe-dtrace",
    NULL
  };

/* Returns STRING if not NULL, the empty string otherwise.  */

static const char *
string_or_empty (const char *string)
{
  return string != NULL ? string : "";
}

/* A helper function to collect explicit location matches for the given
   LOCATION, which is attempting to match on WORD.  */

static void
collect_explicit_location_matches (completion_tracker &tracker,
				   location_spec *locspec,
				   enum explicit_location_match_type what,
				   const char *word,
				   const struct language_defn *language)
{
  const explicit_location_spec *explicit_loc
    = as_explicit_location_spec (locspec);

  /* True if the option expects an argument.  */
  bool needs_arg = true;

  /* Note, in the various MATCH_* below, we complete on
     explicit_loc->foo instead of WORD, because only the former will
     have already skipped past any quote char.  */
  switch (what)
    {
    case MATCH_SOURCE:
      {
	const char *source
	  = string_or_empty (explicit_loc->source_filename.get ());
	completion_list matches
	  = make_source_files_completion_list (source);
	tracker.add_completions (std::move (matches));
      }
      break;

    case MATCH_FUNCTION:
      {
	const char *function
	  = string_or_empty (explicit_loc->function_name.get ());
	linespec_complete_function (tracker, function,
				    explicit_loc->func_name_match_type,
				    explicit_loc->source_filename.get ());
      }
      break;

    case MATCH_QUALIFIED:
      needs_arg = false;
      break;
    case MATCH_LINE:
      /* Nothing to offer.  */
      break;

    case MATCH_LABEL:
      {
	const char *label = string_or_empty (explicit_loc->label_name.get ());
	linespec_complete_label (tracker, language,
				 explicit_loc->source_filename.get (),
				 explicit_loc->function_name.get (),
				 explicit_loc->func_name_match_type,
				 label);
      }
      break;

    default:
      gdb_assert_not_reached ("unhandled explicit_location_match_type");
    }

  if (!needs_arg || tracker.completes_to_completion_word (word))
    {
      tracker.discard_completions ();
      tracker.advance_custom_word_point_by (strlen (word));
      complete_on_enum (tracker, explicit_options, "", "");
      complete_on_enum (tracker, linespec_keywords, "", "");
    }
  else if (!tracker.have_completions ())
    {
      /* Maybe we have an unterminated linespec keyword at the tail of
	 the string.  Try completing on that.  */
      size_t wordlen = strlen (word);
      const char *keyword = word + wordlen;

      if (wordlen > 0 && keyword[-1] != ' ')
	{
	  while (keyword > word && *keyword != ' ')
	    keyword--;
	  /* Don't complete on keywords if we'd be completing on the
	     whole explicit linespec option.  E.g., "b -function
	     thr<tab>" should not complete to the "thread"
	     keyword.  */
	  if (keyword != word)
	    {
	      keyword = skip_spaces (keyword);

	      tracker.advance_custom_word_point_by (keyword - word);
	      complete_on_enum (tracker, linespec_keywords, keyword, keyword);
	    }
	}
      else if (wordlen > 0 && keyword[-1] == ' ')
	{
	  /* Assume that we're maybe past the explicit location
	     argument, and we didn't manage to find any match because
	     the user wants to create a pending breakpoint.  Offer the
	     keyword and explicit location options as possible
	     completions.  */
	  tracker.advance_custom_word_point_by (keyword - word);
	  complete_on_enum (tracker, linespec_keywords, keyword, keyword);
	  complete_on_enum (tracker, explicit_options, keyword, keyword);
	}
    }
}

/* If the next word in *TEXT_P is any of the keywords in KEYWORDS,
   then advance both TEXT_P and the word point in the tracker past the
   keyword and return the (0-based) index in the KEYWORDS array that
   matched.  Otherwise, return -1.  */

static int
skip_keyword (completion_tracker &tracker,
	      const char * const *keywords, const char **text_p)
{
  const char *text = *text_p;
  const char *after = skip_to_space (text);
  size_t len = after - text;

  if (text[len] != ' ')
    return -1;

  int found = -1;
  for (int i = 0; keywords[i] != NULL; i++)
    {
      if (strncmp (keywords[i], text, len) == 0)
	{
	  if (found == -1)
	    found = i;
	  else
	    return -1;
	}
    }

  if (found != -1)
    {
      tracker.advance_custom_word_point_by (len + 1);
      text += len + 1;
      *text_p = text;
      return found;
    }

  return -1;
}

/* A completer function for explicit location specs.  This function
   completes both options ("-source", "-line", etc) and values.  If
   completing a quoted string, then QUOTED_ARG_START and
   QUOTED_ARG_END point to the quote characters.  LANGUAGE is the
   current language.  */

static void
complete_explicit_location_spec (completion_tracker &tracker,
				 location_spec *locspec,
				 const char *text,
				 const language_defn *language,
				 const char *quoted_arg_start,
				 const char *quoted_arg_end)
{
  if (*text != '-')
    return;

  int keyword = skip_keyword (tracker, explicit_options, &text);

  if (keyword == -1)
    {
      complete_on_enum (tracker, explicit_options, text, text);
      /* There are keywords that start with "-".   Include them, too.  */
      complete_on_enum (tracker, linespec_keywords, text, text);
    }
  else
    {
      /* Completing on value.  */
      enum explicit_location_match_type what
	= (explicit_location_match_type) keyword;

      if (quoted_arg_start != NULL && quoted_arg_end != NULL)
	{
	  if (quoted_arg_end[1] == '\0')
	    {
	      /* If completing a quoted string with the cursor right
		 at the terminating quote char, complete the
		 completion word without interpretation, so that
		 readline advances the cursor one whitespace past the
		 quote, even if there's no match.  This makes these
		 cases behave the same:

		   before: "b -function function()"
		   after:  "b -function function() "

		   before: "b -function 'function()'"
		   after:  "b -function 'function()' "

		 and trusts the user in this case:

		   before: "b -function 'not_loaded_function_yet()'"
		   after:  "b -function 'not_loaded_function_yet()' "
	      */
	      tracker.add_completion (make_unique_xstrdup (text));
	    }
	  else if (quoted_arg_end[1] == ' ')
	    {
	      /* We're maybe past the explicit location argument.
		 Skip the argument without interpretation, assuming the
		 user may want to create pending breakpoint.  Offer
		 the keyword and explicit location options as possible
		 completions.  */
	      tracker.advance_custom_word_point_by (strlen (text));
	      complete_on_enum (tracker, linespec_keywords, "", "");
	      complete_on_enum (tracker, explicit_options, "", "");
	    }
	  return;
	}

      /* Now gather matches  */
      collect_explicit_location_matches (tracker, locspec, what, text,
					 language);
    }
}

/* A completer for locations.  */

void
location_completer (struct cmd_list_element *ignore,
		    completion_tracker &tracker,
		    const char *text, const char * /* word */)
{
  int found_probe_option = -1;

  /* If we have a probe modifier, skip it.  This can only appear as
     first argument.  Until we have a specific completer for probes,
     falling back to the linespec completer for the remainder of the
     line is better than nothing.  */
  if (text[0] == '-' && text[1] == 'p')
    found_probe_option = skip_keyword (tracker, probe_options, &text);

  const char *option_text = text;
  int saved_word_point = tracker.custom_word_point ();

  const char *copy = text;

  explicit_completion_info completion_info;
  location_spec_up locspec
    = string_to_explicit_location_spec (&copy, current_language,
					&completion_info);
  if (completion_info.quoted_arg_start != NULL
      && completion_info.quoted_arg_end == NULL)
    {
      /* Found an unbalanced quote.  */
      tracker.set_quote_char (*completion_info.quoted_arg_start);
      tracker.advance_custom_word_point_by (1);
    }

  if (completion_info.saw_explicit_location_spec_option)
    {
      if (*copy != '\0')
	{
	  tracker.advance_custom_word_point_by (copy - text);
	  text = copy;

	  /* We found a terminator at the tail end of the string,
	     which means we're past the explicit location options.  We
	     may have a keyword to complete on.  If we have a whole
	     keyword, then complete whatever comes after as an
	     expression.  This is mainly for the "if" keyword.  If the
	     "thread" and "task" keywords gain their own completers,
	     they should be used here.  */
	  int keyword = skip_keyword (tracker, linespec_keywords, &text);

	  if (keyword == -1)
	    {
	      complete_on_enum (tracker, linespec_keywords, text, text);
	    }
	  else
	    {
	      const char *word
		= advance_to_expression_complete_word_point (tracker, text);
	      complete_expression (tracker, text, word);
	    }
	}
      else
	{
	  tracker.advance_custom_word_point_by (completion_info.last_option
						- text);
	  text = completion_info.last_option;

	  complete_explicit_location_spec (tracker, locspec.get (), text,
					   current_language,
					   completion_info.quoted_arg_start,
					   completion_info.quoted_arg_end);

	}
    }
  /* This is an address or linespec location.  */
  else if (locspec != nullptr)
    {
      /* Handle non-explicit location options.  */

      int keyword = skip_keyword (tracker, explicit_options, &text);
      if (keyword == -1)
	complete_on_enum (tracker, explicit_options, text, text);
      else
	{
	  tracker.advance_custom_word_point_by (copy - text);
	  text = copy;

	  symbol_name_match_type match_type
	    = as_explicit_location_spec (locspec.get ())->func_name_match_type;
	  complete_address_and_linespec_locations (tracker, text, match_type);
	}
    }
  else
    {
      /* No options.  */
      complete_address_and_linespec_locations (tracker, text,
					       symbol_name_match_type::WILD);
    }

  /* Add matches for option names, if either:

     - Some completer above found some matches, but the word point did
       not advance (e.g., "b <tab>" finds all functions, or "b -<tab>"
       matches all objc selectors), or;

     - Some completer above advanced the word point, but found no
       matches.
  */
  if ((text[0] == '-' || text[0] == '\0')
      && (!tracker.have_completions ()
	  || tracker.custom_word_point () == saved_word_point))
    {
      tracker.set_custom_word_point (saved_word_point);
      text = option_text;

      if (found_probe_option == -1)
	complete_on_enum (tracker, probe_options, text, text);
      complete_on_enum (tracker, explicit_options, text, text);
    }
}

/* The corresponding completer_handle_brkchars
   implementation.  */

static void
location_completer_handle_brkchars (struct cmd_list_element *ignore,
				    completion_tracker &tracker,
				    const char *text,
				    const char *word_ignored)
{
  tracker.set_use_custom_word_point (true);

  location_completer (ignore, tracker, text, NULL);
}

/* See completer.h.  */

void
complete_expression (completion_tracker &tracker,
		     const char *text, const char *word)
{
  expression_up exp;
  std::unique_ptr<expr_completion_base> expr_completer;

  /* Perform a tentative parse of the expression, to see whether a
     field completion is required.  */
  try
    {
      exp = parse_expression_for_completion (text, &expr_completer);
    }
  catch (const gdb_exception_error &except)
    {
      return;
    }

  /* Part of the parse_expression_for_completion contract.  */
  gdb_assert ((exp == nullptr) == (expr_completer == nullptr));
  if (expr_completer != nullptr
      && expr_completer->complete (exp.get (), tracker))
    return;

  complete_files_symbols (tracker, text, word);
}

/* Complete on expressions.  Often this means completing on symbol
   names, but some language parsers also have support for completing
   field names.  */

void
expression_completer (struct cmd_list_element *ignore,
		      completion_tracker &tracker,
		      const char *text, const char *word)
{
  complete_expression (tracker, text, word);
}

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

static void
set_rl_completer_word_break_characters (const char *break_chars)
{
  rl_completer_word_break_characters = (char *) break_chars;
}

/* Complete on symbols.  */

void
symbol_completer (struct cmd_list_element *ignore,
		  completion_tracker &tracker,
		  const char *text, const char *word)
{
  collect_symbol_completion_matches (tracker, complete_symbol_mode::EXPRESSION,
				     symbol_name_match_type::EXPRESSION,
				     text, word);
}

/* Here are some useful test cases for completion.  FIXME: These
   should be put in the test suite.  They should be tested with both
   M-? and TAB.

   "show output-" "radix"
   "show output" "-radix"
   "p" ambiguous (commands starting with p--path, print, printf, etc.)
   "p "  ambiguous (all symbols)
   "info t foo" no completions
   "info t " no completions
   "info t" ambiguous ("info target", "info terminal", etc.)
   "info ajksdlfk" no completions
   "info ajksdlfk " no completions
   "info" " "
   "info " ambiguous (all info commands)
   "p \"a" no completions (string constant)
   "p 'a" ambiguous (all symbols starting with a)
   "p b-a" ambiguous (all symbols starting with a)
   "p b-" ambiguous (all symbols)
   "file Make" "file" (word break hard to screw up here)
   "file ../gdb.stabs/we" "ird" (needs to not break word at slash)
 */

enum complete_line_internal_reason
{
  /* Preliminary phase, called by gdb_completion_word_break_characters
     function, is used to either:

     #1 - Determine the set of chars that are word delimiters
	  depending on the current command in line_buffer.

     #2 - Manually advance RL_POINT to the "word break" point instead
	  of letting readline do it (based on too-simple character
	  matching).

     Simpler completers that just pass a brkchars array to readline
     (#1 above) must defer generating the completions to the main
     phase (below).  No completion list should be generated in this
     phase.

     OTOH, completers that manually advance the word point(#2 above)
     must set "use_custom_word_point" in the tracker and generate
     their completion in this phase.  Note that this is the convenient
     thing to do since they'll be parsing the input line anyway.  */
  handle_brkchars,

  /* Main phase, called by complete_line function, is used to get the
     list of possible completions.  */
  handle_completions,

  /* Special case when completing a 'help' command.  In this case,
     once sub-command completions are exhausted, we simply return
     NULL.  */
  handle_help,
};

/* Helper for complete_line_internal to simplify it.  */

static void
complete_line_internal_normal_command (completion_tracker &tracker,
				       const char *command, const char *word,
				       const char *cmd_args,
				       complete_line_internal_reason reason,
				       struct cmd_list_element *c)
{
  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, tracker, cmd_args, word);
    }

  if (reason != handle_brkchars && c->completer != NULL)
    (*c->completer) (c, tracker, cmd_args, word);
}

/* Internal function used to handle completions.


   TEXT is the caller's idea of the "word" we are looking at.

   LINE_BUFFER is available to be looked at; it contains the entire
   text of the line.  POINT is the offset in that line of the cursor.
   You should pretend that the line ends at POINT.

   See complete_line_internal_reason for description of REASON.  */

static void
complete_line_internal_1 (completion_tracker &tracker,
			  const char *text,
			  const char *line_buffer, int point,
			  complete_line_internal_reason reason)
{
  char *tmp_command;
  const char *p;
  int ignore_help_classes;
  /* Pointer within tmp_command which corresponds to text.  */
  const char *word;
  struct cmd_list_element *c, *result_list;

  /* Choose the default set of word break characters to break
     completions.  If we later find out that we are doing completions
     on command strings (as opposed to strings supplied by the
     individual command completer functions, which can be any string)
     then we will switch to the special word break set for command
     strings, which leaves out the '-' and '.' character used in some
     commands.  */
  set_rl_completer_word_break_characters
    (current_language->word_break_characters ());

  /* Likewise for the quote characters.  If we later find out that we are
     completing file names then we can switch to the file name quote
     character set (i.e., both single- and double-quotes).  */
  rl_completer_quote_characters = gdb_completer_expression_quote_characters;
  rl_char_is_quoted_p = nullptr;

  /* Decide whether to complete on a list of gdb commands or on
     symbols.  */
  tmp_command = (char *) alloca (point + 1);
  p = tmp_command;

  /* The help command should complete help aliases.  */
  ignore_help_classes = reason != handle_help;

  strncpy (tmp_command, line_buffer, point);
  tmp_command[point] = '\0';
  if (reason == handle_brkchars)
    {
      gdb_assert (text == NULL);
      word = NULL;
    }
  else
    {
      /* Since text always contains some number of characters leading up
	 to point, we can find the equivalent position in tmp_command
	 by subtracting that many characters from the end of tmp_command.  */
      word = tmp_command + point - strlen (text);
    }

  /* Move P up to the start of the command.  */
  p = skip_spaces (p);

  if (*p == '\0')
    {
      /* An empty line is ambiguous; that is, it could be any
	 command.  */
      c = CMD_LIST_AMBIGUOUS;
      result_list = 0;
    }
  else
    c = lookup_cmd_1 (&p, cmdlist, &result_list, NULL, ignore_help_classes,
		      true);

  /* Move p up to the next interesting thing.  */
  while (*p == ' ' || *p == '\t')
    {
      p++;
    }

  tracker.advance_custom_word_point_by (p - tmp_command);

  if (!c)
    {
      /* It is an unrecognized command.  So there are no
	 possible completions.  */
    }
  else if (c == CMD_LIST_AMBIGUOUS)
    {
      const char *q;

      /* lookup_cmd_1 advances p up to the first ambiguous thing, but
	 doesn't advance over that thing itself.  Do so now.  */
      q = p;
      while (valid_cmd_char_p (*q))
	++q;
      if (q != tmp_command + point)
	{
	  /* There is something beyond the ambiguous
	     command, so there are no possible completions.  For
	     example, "info t " or "info t foo" does not complete
	     to anything, because "info t" can be "info target" or
	     "info terminal".  */
	}
      else
	{
	  /* We're trying to complete on the command which was ambiguous.
	     This we can deal with.  */
	  if (result_list)
	    {
	      if (reason != handle_brkchars)
		complete_on_cmdlist (*result_list->subcommands, tracker, p,
				     word, ignore_help_classes);
	    }
	  else
	    {
	      if (reason != handle_brkchars)
		complete_on_cmdlist (cmdlist, tracker, p, word,
				     ignore_help_classes);
	    }
	  /* Ensure that readline does the right thing with respect to
	     inserting quotes.  */
	  set_rl_completer_word_break_characters
	    (gdb_completer_command_word_break_characters);
	}
    }
  else
    {
      /* We've recognized a full command.  */

      if (p == tmp_command + point)
	{
	  /* There is no non-whitespace in the line beyond the
	     command.  */

	  if (p[-1] == ' ' || p[-1] == '\t')
	    {
	      /* The command is followed by whitespace; we need to
		 complete on whatever comes after command.  */
	      if (c->is_prefix ())
		{
		  /* It is a prefix command; what comes after it is
		     a subcommand (e.g. "info ").  */
		  if (reason != handle_brkchars)
		    complete_on_cmdlist (*c->subcommands, tracker, p, word,
					 ignore_help_classes);

		  /* Ensure that readline does the right thing
		     with respect to inserting quotes.  */
		  set_rl_completer_word_break_characters
		    (gdb_completer_command_word_break_characters);
		}
	      else if (reason == handle_help)
		;
	      else if (c->enums)
		{
		  if (reason != handle_brkchars)
		    complete_on_enum (tracker, c->enums, p, word);
		  set_rl_completer_word_break_characters
		    (gdb_completer_command_word_break_characters);
		}
	      else
		{
		  /* It is a normal command; what comes after it is
		     completed by the command's completer function.  */
		  complete_line_internal_normal_command (tracker,
							 tmp_command, word, p,
							 reason, c);
		}
	    }
	  else
	    {
	      /* The command is not followed by whitespace; we need to
		 complete on the command itself, e.g. "p" which is a
		 command itself but also can complete to "print", "ptype"
		 etc.  */
	      const char *q;

	      /* Find the command we are completing on.  */
	      q = p;
	      while (q > tmp_command)
		{
		  if (valid_cmd_char_p (q[-1]))
		    --q;
		  else
		    break;
		}

	      /* Move the custom word point back too.  */
	      tracker.advance_custom_word_point_by (q - p);

	      if (reason != handle_brkchars)
		complete_on_cmdlist (result_list, tracker, q, word,
				     ignore_help_classes);

	      /* Ensure that readline does the right thing
		 with respect to inserting quotes.  */
	      set_rl_completer_word_break_characters
		(gdb_completer_command_word_break_characters);
	    }
	}
      else if (reason == handle_help)
	;
      else
	{
	  /* There is non-whitespace beyond the command.  */

	  if (c->is_prefix () && !c->allow_unknown)
	    {
	      /* It is an unrecognized subcommand of a prefix command,
		 e.g. "info adsfkdj".  */
	    }
	  else if (c->enums)
	    {
	      if (reason != handle_brkchars)
		complete_on_enum (tracker, c->enums, p, word);
	    }
	  else
	    {
	      /* It is a normal command.  */
	      complete_line_internal_normal_command (tracker,
						     tmp_command, word, p,
						     reason, c);
	    }
	}
    }
}

/* Wrapper around complete_line_internal_1 to handle
   MAX_COMPLETIONS_REACHED_ERROR.  */

static void
complete_line_internal (completion_tracker &tracker,
			const char *text,
			const char *line_buffer, int point,
			complete_line_internal_reason reason)
{
  try
    {
      complete_line_internal_1 (tracker, text, line_buffer, point, reason);
    }
  catch (const gdb_exception_error &except)
    {
      if (except.error != MAX_COMPLETIONS_REACHED_ERROR)
	throw;
    }
}

/* See completer.h.  */

int max_completions = 200;

/* Initial size of the table.  It automagically grows from here.  */
#define INITIAL_COMPLETION_HTAB_SIZE 200

/* The function is used to update the completion word MATCH before
   displaying it to the user in the 'complete' command output.  This
   default function is used in all cases except those where a completion
   function overrides this function by calling set_match_format_func.

   This function returns MATCH with QUOTE_CHAR appended.  If QUOTE_CHAR is
   the null-character then the returned string will just contain MATCH.  */

static std::string
default_match_formatter (const char *match, char quote_char)
{
  return std::string (match) + quote_char;
}

/* See completer.h.  */

completion_tracker::completion_tracker (bool from_readline)
  : m_from_readline (from_readline),
    m_match_format_func (default_match_formatter)
{
  discard_completions ();
}

/* See completer.h.  */

void
completion_tracker::discard_completions ()
{
  xfree (m_lowest_common_denominator);
  m_lowest_common_denominator = NULL;

  m_lowest_common_denominator_unique = false;
  m_lowest_common_denominator_valid = false;

  m_entries_hash.reset (nullptr);

  /* A callback used by the hash table to compare new entries with existing
     entries.  We can't use the standard htab_eq_string function here as the
     key to our hash is just a single string, while the values we store in
     the hash are a struct containing multiple strings.  */
  static auto entry_eq_func
    = [] (const void *first, const void *second) -> int
      {
	/* The FIRST argument is the entry already in the hash table, and
	   the SECOND argument is the new item being inserted.  */
	const completion_hash_entry *entry
	  = (const completion_hash_entry *) first;
	const char *name_str = (const char *) second;

	return entry->is_name_eq (name_str);
      };

  /* Callback used by the hash table to compute the hash value for an
     existing entry.  This is needed when expanding the hash table.  */
  static auto entry_hash_func
    = [] (const void *arg) -> hashval_t
      {
	const completion_hash_entry *entry
	  = (const completion_hash_entry *) arg;
	return entry->hash_name ();
      };

  m_entries_hash.reset
    (htab_create_alloc (INITIAL_COMPLETION_HTAB_SIZE,
			entry_hash_func, entry_eq_func,
			htab_delete_entry<completion_hash_entry>,
			xcalloc, xfree));
}

/* See completer.h.  */

completion_tracker::~completion_tracker ()
{
  xfree (m_lowest_common_denominator);
}

/* See completer.h.  */

bool
completion_tracker::maybe_add_completion
  (gdb::unique_xmalloc_ptr<char> name,
   completion_match_for_lcd *match_for_lcd,
   const char *text, const char *word)
{
  void **slot;

  if (max_completions == 0)
    return false;

  if (htab_elements (m_entries_hash.get ()) >= max_completions)
    return false;

  hashval_t hash = htab_hash_string (name.get ());
  slot = htab_find_slot_with_hash (m_entries_hash.get (), name.get (),
				   hash, INSERT);
  if (*slot == HTAB_EMPTY_ENTRY)
    {
      const char *match_for_lcd_str = NULL;

      if (match_for_lcd != NULL)
	match_for_lcd_str = match_for_lcd->finish ();

      if (match_for_lcd_str == NULL)
	match_for_lcd_str = name.get ();

      gdb::unique_xmalloc_ptr<char> lcd
	= make_completion_match_str (match_for_lcd_str, text, word);

      size_t lcd_len = strlen (lcd.get ());
      *slot = new completion_hash_entry (std::move (name), std::move (lcd));

      m_lowest_common_denominator_valid = false;
      m_lowest_common_denominator_max_length
	= std::max (m_lowest_common_denominator_max_length, lcd_len);
    }

  return true;
}

/* See completer.h.  */

void
completion_tracker::add_completion (gdb::unique_xmalloc_ptr<char> name,
				    completion_match_for_lcd *match_for_lcd,
				    const char *text, const char *word)
{
  if (!maybe_add_completion (std::move (name), match_for_lcd, text, word))
    throw_error (MAX_COMPLETIONS_REACHED_ERROR, _("Max completions reached."));
}

/* See completer.h.  */

void
completion_tracker::add_completions (completion_list &&list)
{
  for (auto &candidate : list)
    add_completion (std::move (candidate));
}

/* See completer.h.  */

void
completion_tracker::remove_completion (const char *name)
{
  hashval_t hash = htab_hash_string (name);
  if (htab_find_slot_with_hash (m_entries_hash.get (), name, hash, NO_INSERT)
      != NULL)
    {
      htab_remove_elt_with_hash (m_entries_hash.get (), name, hash);
      m_lowest_common_denominator_valid = false;
    }
}

/* Helper for the make_completion_match_str overloads.  Returns NULL
   as an indication that we want MATCH_NAME exactly.  It is up to the
   caller to xstrdup that string if desired.  */

static char *
make_completion_match_str_1 (const char *match_name,
			     const char *text, const char *word)
{
  char *newobj;

  if (word == text)
    {
      /* Return NULL as an indication that we want MATCH_NAME
	 exactly.  */
      return NULL;
    }
  else if (word > text)
    {
      /* Return some portion of MATCH_NAME.  */
      newobj = xstrdup (match_name + (word - text));
    }
  else
    {
      /* Return some of WORD plus MATCH_NAME.  */
      size_t len = strlen (match_name);
      newobj = (char *) xmalloc (text - word + len + 1);
      memcpy (newobj, word, text - word);
      memcpy (newobj + (text - word), match_name, len + 1);
    }

  return newobj;
}

/* See completer.h.  */

gdb::unique_xmalloc_ptr<char>
make_completion_match_str (const char *match_name,
			   const char *text, const char *word)
{
  char *newobj = make_completion_match_str_1 (match_name, text, word);
  if (newobj == NULL)
    newobj = xstrdup (match_name);
  return gdb::unique_xmalloc_ptr<char> (newobj);
}

/* See completer.h.  */

gdb::unique_xmalloc_ptr<char>
make_completion_match_str (gdb::unique_xmalloc_ptr<char> &&match_name,
			   const char *text, const char *word)
{
  char *newobj = make_completion_match_str_1 (match_name.get (), text, word);
  if (newobj == NULL)
    return std::move (match_name);
  return gdb::unique_xmalloc_ptr<char> (newobj);
}

/* See complete.h.  */

completion_result
complete (const char *line, char const **word, int *quote_char)
{
  completion_tracker tracker_handle_brkchars (false);
  completion_tracker tracker_handle_completions (false);
  completion_tracker *tracker;

  /* The WORD should be set to the end of word to complete.  We initialize
     to the completion point which is assumed to be at the end of LINE.
     This leaves WORD to be initialized to a sensible value in cases
     completion_find_completion_word() fails i.e., throws an exception.
     See bug 24587. */
  *word = line + strlen (line);

  try
    {
      bool found_any_quoting = false;

      *word = completion_find_completion_word (tracker_handle_brkchars,
					       line, quote_char,
					       &found_any_quoting);

      /* Completers that provide a custom word point in the
	 handle_brkchars phase also compute their completions then.
	 Completers that leave the completion word handling to readline
	 must be called twice.  */
      if (tracker_handle_brkchars.use_custom_word_point ())
	tracker = &tracker_handle_brkchars;
      else
	{
	  /* Setting this global matches what readline does within
	     gen_completion_matches.  We need this set correctly in case
	     our completion function calls back into readline to perform
	     completion (e.g. filename_completer does this).  */
	  rl_completion_found_quote = found_any_quoting;

	  complete_line (tracker_handle_completions, *word, line, strlen (line));
	  tracker = &tracker_handle_completions;
	}
    }
  catch (const gdb_exception &ex)
    {
      return {};
    }

  return tracker->build_completion_result (*word, *word - line, strlen (line));
}


/* Generate completions all at once.  Does nothing if max_completions
   is 0.  If max_completions is non-negative, this will collect at
   most max_completions strings.

   TEXT is the caller's idea of the "word" we are looking at.

   LINE_BUFFER is available to be looked at; it contains the entire
   text of the line.

   POINT is the offset in that line of the cursor.  You
   should pretend that the line ends at POINT.  */

void
complete_line (completion_tracker &tracker,
	       const char *text, const char *line_buffer, int point)
{
  if (max_completions == 0)
    return;
  complete_line_internal (tracker, text, line_buffer, point,
			  handle_completions);
}

/* Complete on command names.  Used by "help".  */

void
command_completer (struct cmd_list_element *ignore, 
		   completion_tracker &tracker,
		   const char *text, const char *word)
{
  complete_line_internal (tracker, word, text,
			  strlen (text), handle_help);
}

/* The corresponding completer_handle_brkchars implementation.  */

static void
command_completer_handle_brkchars (struct cmd_list_element *ignore,
				   completion_tracker &tracker,
				   const char *text, const char *word)
{
  set_rl_completer_word_break_characters
    (gdb_completer_command_word_break_characters);
}

/* Complete on signals.  */

void
signal_completer (struct cmd_list_element *ignore,
		  completion_tracker &tracker,
		  const char *text, const char *word)
{
  size_t len = strlen (word);
  int signum;
  const char *signame;

  for (signum = GDB_SIGNAL_FIRST; signum != GDB_SIGNAL_LAST; ++signum)
    {
      /* Can't handle this, so skip it.  */
      if (signum == GDB_SIGNAL_0)
	continue;

      signame = gdb_signal_to_name ((enum gdb_signal) signum);

      /* Ignore the unknown signal case.  */
      if (!signame || strcmp (signame, "?") == 0)
	continue;

      if (strncasecmp (signame, word, len) == 0)
	tracker.add_completion (make_unique_xstrdup (signame));
    }
}

/* Bit-flags for selecting what the register and/or register-group
   completer should complete on.  */

enum reg_completer_target
  {
    complete_register_names = 0x1,
    complete_reggroup_names = 0x2
  };
DEF_ENUM_FLAGS_TYPE (enum reg_completer_target, reg_completer_targets);

/* Complete register names and/or reggroup names based on the value passed
   in TARGETS.  At least one bit in TARGETS must be set.  */

static void
reg_or_group_completer_1 (completion_tracker &tracker,
			  const char *text, const char *word,
			  reg_completer_targets targets)
{
  size_t len = strlen (word);
  struct gdbarch *gdbarch;
  const char *name;

  gdb_assert ((targets & (complete_register_names
			  | complete_reggroup_names)) != 0);
  gdbarch = get_current_arch ();

  if ((targets & complete_register_names) != 0)
    {
      int i;

      for (i = 0;
	   (name = user_reg_map_regnum_to_name (gdbarch, i)) != NULL;
	   i++)
	{
	  if (*name != '\0' && strncmp (word, name, len) == 0)
	    tracker.add_completion (make_unique_xstrdup (name));
	}
    }

  if ((targets & complete_reggroup_names) != 0)
    {
      for (const struct reggroup *group : gdbarch_reggroups (gdbarch))
	{
	  name = group->name ();
	  if (strncmp (word, name, len) == 0)
	    tracker.add_completion (make_unique_xstrdup (name));
	}
    }
}

/* Perform completion on register and reggroup names.  */

void
reg_or_group_completer (struct cmd_list_element *ignore,
			completion_tracker &tracker,
			const char *text, const char *word)
{
  reg_or_group_completer_1 (tracker, text, word,
			    (complete_register_names
			     | complete_reggroup_names));
}

/* Perform completion on reggroup names.  */

void
reggroup_completer (struct cmd_list_element *ignore,
		    completion_tracker &tracker,
		    const char *text, const char *word)
{
  reg_or_group_completer_1 (tracker, text, word,
			    complete_reggroup_names);
}

/* The default completer_handle_brkchars implementation.  */

static void
default_completer_handle_brkchars (struct cmd_list_element *ignore,
				   completion_tracker &tracker,
				   const char *text, const char *word)
{
  set_rl_completer_word_break_characters
    (current_language->word_break_characters ());
}

/* See definition in completer.h.  */

completer_handle_brkchars_ftype *
completer_handle_brkchars_func_for_completer (completer_ftype *fn)
{
  if (fn == deprecated_filename_completer)
    return deprecated_filename_completer_handle_brkchars;

  if (fn == filename_maybe_quoted_completer)
    return filename_maybe_quoted_completer_handle_brkchars;

  if (fn == location_completer)
    return location_completer_handle_brkchars;

  if (fn == command_completer)
    return command_completer_handle_brkchars;

  return default_completer_handle_brkchars;
}

/* Used as brkchars when we want to tell readline we have a custom
   word point.  We do that by making our rl_completion_word_break_hook
   set RL_POINT to the desired word point, and return the character at
   the word break point as the break char.  This is two bytes in order
   to fit one break character plus the terminating null.  */
static char gdb_custom_word_point_brkchars[2];

/* Since rl_basic_quote_characters is not completer-specific, we save
   its original value here, in order to be able to restore it in
   gdb_rl_attempted_completion_function.  */
static const char *gdb_org_rl_basic_quote_characters = rl_basic_quote_characters;

/* Get the list of chars that are considered as word breaks
   for the current command.  */

static char *
gdb_completion_word_break_characters_throw ()
{
  /* New completion starting.  Get rid of the previous tracker and
     start afresh.  */
  delete current_completion.tracker;
  current_completion.tracker = new completion_tracker (true);

  completion_tracker &tracker = *current_completion.tracker;

  complete_line_internal (tracker, NULL, rl_line_buffer,
			  rl_point, handle_brkchars);

  if (tracker.use_custom_word_point ())
    {
      gdb_assert (tracker.custom_word_point () > 0);
      rl_point = tracker.custom_word_point () - 1;

      gdb_assert (rl_point >= 0 && rl_point < strlen (rl_line_buffer));

      gdb_custom_word_point_brkchars[0] = rl_line_buffer[rl_point];
      rl_completer_word_break_characters = gdb_custom_word_point_brkchars;

      /* When performing filename completion we have two options, unquoted
	 filename completion, in which case the quote characters will have
	 already been set to nullptr, or quoted filename completion in
	 which case the quote characters will be set to a string of
	 characters.  In this second case we need readline to perform the
	 check for a quoted string so that it sets its internal notion of
	 the quote character correctly, this allows readline to correctly
	 add the trailing quote (if necessary) after completing a
	 filename.

	 For non-filename completion we manually add a trailing quote if
	 needed, so we clear the quote characters set here.  */
      if (!rl_filename_completion_desired)
	rl_completer_quote_characters = NULL;

      /* Clear this too, so that if we're completing a quoted string,
	 readline doesn't consider the quote character a delimiter.
	 If we didn't do this, readline would auto-complete {b
	 'fun<tab>} to {'b 'function()'}, i.e., add the terminating
	 \', but, it wouldn't append the separator space either, which
	 is not desirable.  So instead we take care of appending the
	 quote character to the LCD ourselves, in
	 gdb_rl_attempted_completion_function.  Since this global is
	 not just completer-specific, we'll restore it back to the
	 default in gdb_rl_attempted_completion_function.  */
      rl_basic_quote_characters = NULL;
    }

  return (char *) rl_completer_word_break_characters;
}

/* Get the list of chars that are considered as word breaks for the current
   command.  This function does not throw any exceptions and is called from
   readline.  See gdb_completion_word_break_characters_throw for details.  */

static char *
gdb_completion_word_break_characters () noexcept
{
  /* New completion starting.  */
  current_completion.aborted = false;

  try
    {
      return gdb_completion_word_break_characters_throw ();
    }
  catch (const gdb_exception &ex)
    {
      /* Set this to that gdb_rl_attempted_completion_function knows
	 to abort early.  */
      current_completion.aborted = true;
    }

  return NULL;
}

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

   The argument *FOUND_ANY_QUOTING is set to true if the completion word is
   either surrounded by quotes, or contains any backslash escapes, but is
   only set if TRACKER.use_custom_word_point() is false, otherwise
   *FOUND_ANY_QUOTING is just set to false.  */

static const char *
completion_find_completion_word (completion_tracker &tracker, const char *text,
				 int *quote_char, bool *found_any_quoting)
{
  size_t point = strlen (text);

  complete_line_internal (tracker, NULL, text, point, handle_brkchars);

  if (tracker.use_custom_word_point ())
    {
      gdb_assert (tracker.custom_word_point () > 0);
      *quote_char = tracker.quote_char ();
      /* If use_custom_word_point is set then the completions have already
	 been calculated, in which case we don't need to have this flag
	 set correctly, which is lucky as we don't currently have any way
	 to know if the completion word included any backslash escapes.  */
      if (found_any_quoting != nullptr)
	*found_any_quoting = false;
      return text + tracker.custom_word_point ();
    }

  gdb_rl_completion_word_info info;

  info.word_break_characters = rl_completer_word_break_characters;
  info.quote_characters = rl_completer_quote_characters;
  info.basic_quote_characters = rl_basic_quote_characters;

  return gdb_rl_find_completion_word (&info, quote_char, nullptr,
				      found_any_quoting, text);
}

/* See completer.h.  */

void
completion_tracker::recompute_lcd_visitor (completion_hash_entry *entry)
{
  if (!m_lowest_common_denominator_valid)
    {
      /* This is the first lowest common denominator that we are
	 considering, just copy it in.  */
      strcpy (m_lowest_common_denominator, entry->get_lcd ());
      m_lowest_common_denominator_unique = true;
      m_lowest_common_denominator_valid = true;
    }
  else
    {
      /* Find the common denominator between the currently-known lowest
	 common denominator and NEW_MATCH_UP.  That becomes the new lowest
	 common denominator.  */
      size_t i;
      const char *new_match = entry->get_lcd ();

      for (i = 0;
	   (new_match[i] != '\0'
	    && new_match[i] == m_lowest_common_denominator[i]);
	   i++)
	;
      if (m_lowest_common_denominator[i] != new_match[i])
	{
	  m_lowest_common_denominator[i] = '\0';
	  m_lowest_common_denominator_unique = false;
	}
    }
}

/* See completer.h.  */

void
completion_tracker::recompute_lowest_common_denominator ()
{
  /* We've already done this.  */
  if (m_lowest_common_denominator_valid)
    return;

  /* Resize the storage to ensure we have enough space, the plus one gives
     us space for the trailing null terminator we will include.  */
  m_lowest_common_denominator
    = (char *) xrealloc (m_lowest_common_denominator,
			 m_lowest_common_denominator_max_length + 1);

  /* Callback used to visit each entry in the m_entries_hash.  */
  auto visitor_func
    = [] (void **slot, void *info) -> int
      {
	completion_tracker *obj = (completion_tracker *) info;
	completion_hash_entry *entry = (completion_hash_entry *) *slot;
	obj->recompute_lcd_visitor (entry);
	return 1;
      };

  htab_traverse_noresize (m_entries_hash.get (), visitor_func, this);
  m_lowest_common_denominator_valid = true;
}

/* See completer.h.  */

void
completion_tracker::advance_custom_word_point_by (int len)
{
  m_custom_word_point += len;
}

/* Build a new C string that is a copy of LCD with the whitespace of
   ORIG/ORIG_LEN preserved.

   Say the user is completing a symbol name, with spaces, like:

     "foo ( i"

   and the resulting completion match is:

     "foo(int)"

   we want to end up with an input line like:

     "foo ( int)"
      ^^^^^^^      => text from LCD [1], whitespace from ORIG preserved.
	     ^^	   => new text from LCD

   [1] - We must take characters from the LCD instead of the original
   text, since some completions want to change upper/lowercase.  E.g.:

     "handle sig<>"

   completes to:

     "handle SIG[QUIT|etc.]"
*/

static char *
expand_preserving_ws (const char *orig, size_t orig_len,
		      const char *lcd)
{
  const char *p_orig = orig;
  const char *orig_end = orig + orig_len;
  const char *p_lcd = lcd;
  std::string res;

  while (p_orig < orig_end)
    {
      if (*p_orig == ' ')
	{
	  while (p_orig < orig_end && *p_orig == ' ')
	    res += *p_orig++;
	  p_lcd = skip_spaces (p_lcd);
	}
      else
	{
	  /* Take characters from the LCD instead of the original
	     text, since some completions change upper/lowercase.
	     E.g.:
	       "handle sig<>"
	     completes to:
	       "handle SIG[QUIT|etc.]"
	  */
	  res += *p_lcd;
	  p_orig++;
	  p_lcd++;
	}
    }

  while (*p_lcd != '\0')
    res += *p_lcd++;

  return xstrdup (res.c_str ());
}

/* See completer.h.  */

completion_result
completion_tracker::build_completion_result (const char *text,
					     int start, int end)
{
  size_t element_count = htab_elements (m_entries_hash.get ());

  if (element_count == 0)
    return {};

  /* +1 for the LCD, and +1 for NULL termination.  */
  char **match_list = XNEWVEC (char *, 1 + element_count + 1);

  /* Build replacement word, based on the LCD.  */

  recompute_lowest_common_denominator ();
  if (rl_filename_completion_desired)
    match_list[0] = xstrdup (m_lowest_common_denominator);
  else
    match_list[0]
      = expand_preserving_ws (text, end - start, m_lowest_common_denominator);

  if (m_lowest_common_denominator_unique)
    {
      bool completion_suppress_append;

      /* For filename completion we rely on readline to append the closing
	 quote.  While for other types of completion we append the closing
	 quote here.  */
      if (from_readline () && !rl_filename_completion_desired)
	{
	  /* We don't rely on readline appending the quote char as
	     delimiter as then readline wouldn't append the ' ' after the
	     completion.  */
	  char buf[2] = { (char) quote_char (), '\0' };

	  match_list[0] = reconcat (match_list[0], match_list[0], buf,
				    (char *) nullptr);

	  /* If the tracker wants to, or we already have a space at the end
	     of the match, tell readline to skip appending another.  */
	  char *match = match_list[0];
	  completion_suppress_append
	    = (suppress_append_ws ()
	       || (match[0] != '\0'
		   && match[strlen (match) - 1] == ' '));
	}
      else
	completion_suppress_append = false;

      match_list[1] = nullptr;

      return completion_result (match_list, 1, completion_suppress_append,
				m_match_format_func);
    }
  else
    {
      /* State object used while building the completion list.  */
      struct list_builder
      {
	list_builder (char **ml)
	  : match_list (ml),
	    index (1)
	{ /* Nothing.  */ }

	/* The list we are filling.  */
	char **match_list;

	/* The next index in the list to write to.  */
	int index;
      };
      list_builder builder (match_list);

      /* Visit each entry in m_entries_hash and add it to the completion
	 list, updating the builder state object.  */
      auto func
	= [] (void **slot, void *info) -> int
	  {
	    completion_hash_entry *entry = (completion_hash_entry *) *slot;
	    list_builder *state = (list_builder *) info;

	    state->match_list[state->index] = entry->release_name ();
	    state->index++;
	    return 1;
	  };

      /* Build the completion list and add a null at the end.  */
      htab_traverse_noresize (m_entries_hash.get (), func, &builder);
      match_list[builder.index] = NULL;

      return completion_result (match_list, builder.index - 1, false,
				m_match_format_func);
    }
}

/* See completer.h  */

completion_result::completion_result ()
  : match_list (NULL), number_matches (0),
    completion_suppress_append (false),
    m_match_formatter (default_match_formatter)
{}

/* See completer.h  */

completion_result::completion_result (char **match_list_,
				      size_t number_matches_,
				      bool completion_suppress_append_,
				      match_format_func_t match_formatter_)
  : match_list (match_list_),
    number_matches (number_matches_),
    completion_suppress_append (completion_suppress_append_),
    m_match_formatter (match_formatter_)
{
  gdb_assert (m_match_formatter != nullptr);
}

/* See completer.h  */

completion_result::~completion_result ()
{
  reset_match_list ();
}

/* See completer.h  */

completion_result::completion_result (completion_result &&rhs) noexcept
  : match_list (rhs.match_list),
    number_matches (rhs.number_matches),
    m_match_formatter (rhs.m_match_formatter)
{
  rhs.match_list = NULL;
  rhs.number_matches = 0;
  rhs.m_match_formatter = default_match_formatter;
}

/* See completer.h  */

char **
completion_result::release_match_list ()
{
  char **ret = match_list;
  match_list = NULL;
  return ret;
}

/* See completer.h  */

void
completion_result::sort_match_list ()
{
  if (number_matches > 1)
    {
      /* Element 0 is special (it's the common prefix), leave it
	 be.  */
      std::sort (&match_list[1],
		 &match_list[number_matches + 1],
		 compare_cstrings);
    }
}

/* See completer.h  */

void
completion_result::reset_match_list ()
{
  if (match_list != NULL)
    {
      for (char **p = match_list; *p != NULL; p++)
	xfree (*p);
      xfree (match_list);
      match_list = NULL;
    }
}

/* See completer.h  */

void
completion_result::print_matches (const std::string &prefix,
				  const char *word, int quote_char)
{
  this->sort_match_list ();

  size_t off = this->number_matches == 1 ? 0 : 1;

  for (size_t i = 0; i < this->number_matches; i++)
    {
      gdb_assert (this->m_match_formatter != nullptr);
      std::string formatted_match
	= this->m_match_formatter (this->match_list[i + off],
				   (char) quote_char);

      printf_unfiltered ("%s%s\n", prefix.c_str (),
			 formatted_match.c_str ());
    }

  if (this->number_matches == max_completions)
    {
      /* PREFIX and WORD are included in the output so that emacs will
	 include the message in the output.  */
      printf_unfiltered (_("%s%s %s\n"),
			 prefix.c_str (), word,
			 get_max_completions_reached_message ());
    }

}

/* Helper for gdb_rl_attempted_completion_function, which does most of
   the work.  This is called by readline to build the match list array
   and to determine the lowest common denominator.  The real matches
   list starts at match[1], while match[0] is the slot holding
   readline's idea of the lowest common denominator of all matches,
   which is what readline replaces the completion "word" with.

   TEXT is the caller's idea of the "word" we are looking at, as
   computed in the handle_brkchars phase.

   START is the offset from RL_LINE_BUFFER where TEXT starts.  END is
   the offset from RL_LINE_BUFFER where TEXT ends (i.e., where
   rl_point is).

   You should thus pretend that the line ends at END (relative to
   RL_LINE_BUFFER).

   RL_LINE_BUFFER contains the entire text of the line.  RL_POINT is
   the offset in that line of the cursor.  You should pretend that the
   line ends at POINT.

   Returns NULL if there are no completions.  */

static char **
gdb_rl_attempted_completion_function_throw (const char *text, int start, int end)
{
  /* Completers that provide a custom word point in the
     handle_brkchars phase also compute their completions then.
     Completers that leave the completion word handling to readline
     must be called twice.  If rl_point (i.e., END) is at column 0,
     then readline skips the handle_brkchars phase, and so we create a
     tracker now in that case too.  */
  if (end == 0 || !current_completion.tracker->use_custom_word_point ())
    {
      delete current_completion.tracker;
      current_completion.tracker = new completion_tracker (true);

      complete_line (*current_completion.tracker, text,
		     rl_line_buffer, rl_point);
    }

  completion_tracker &tracker = *current_completion.tracker;

  completion_result result
    = tracker.build_completion_result (text, start, end);

  rl_completion_suppress_append = result.completion_suppress_append;
  return result.release_match_list ();
}

/* Function installed as "rl_attempted_completion_function" readline
   hook.  Wrapper around gdb_rl_attempted_completion_function_throw
   that catches C++ exceptions, which can't cross readline.  */

static char **
gdb_rl_attempted_completion_function (const char *text, int start, int end)
{
  /* Restore globals that might have been tweaked in
     gdb_completion_word_break_characters.  */
  rl_basic_quote_characters = gdb_org_rl_basic_quote_characters;

  /* If we end up returning NULL, either on error, or simple because
     there are no matches, inhibit readline's default filename
     completer.  */
  rl_attempted_completion_over = 1;

  /* If the handle_brkchars phase was aborted, don't try
     completing.  */
  if (current_completion.aborted)
    return NULL;

  try
    {
      return gdb_rl_attempted_completion_function_throw (text, start, end);
    }
  catch (const gdb_exception &ex)
    {
    }

  return NULL;
}

/* Return a message indicating that the maximum number of completions
   has been reached and that there may be more.  */

const char *
get_max_completions_reached_message (void)
{
  return _("*** List may be truncated, max-completions reached. ***");
}

/* GDB replacement for rl_display_match_list.
   Readline doesn't provide a clean interface for TUI(curses).
   A hack previously used was to send readline's rl_outstream through a pipe
   and read it from the event loop.  Bleah.  IWBN if readline abstracted
   away all the necessary bits, and this is what this code does.  It
   replicates the parts of readline we need and then adds an abstraction
   layer, currently implemented as struct match_list_displayer, so that both
   CLI and TUI can use it.  We copy all this readline code to minimize
   GDB-specific mods to readline.  Once this code performs as desired then
   we can submit it to the readline maintainers.

   N.B. A lot of the code is the way it is in order to minimize differences
   from readline's copy.  */

/* Not supported here.  */
#undef VISIBLE_STATS

#if defined (HANDLE_MULTIBYTE)
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x)   ((x) == 0)
#endif

#define ELLIPSIS_LEN	3

/* gdb version of readline/complete.c:get_y_or_n.
   'y' -> returns 1, and 'n' -> returns 0.
   Also supported: space == 'y', RUBOUT == 'n', ctrl-g == start over.
   If FOR_PAGER is non-zero, then also supported are:
   NEWLINE or RETURN -> returns 2, and 'q' -> returns 0.  */

static int
gdb_get_y_or_n (int for_pager, const struct match_list_displayer *displayer)
{
  int c;

  for (;;)
    {
      RL_SETSTATE (RL_STATE_MOREINPUT);
      c = displayer->read_key (displayer);
      RL_UNSETSTATE (RL_STATE_MOREINPUT);

      if (c == 'y' || c == 'Y' || c == ' ')
	return 1;
      if (c == 'n' || c == 'N' || c == RUBOUT)
	return 0;
      if (c == ABORT_CHAR || c < 0)
	{
	  /* Readline doesn't erase_entire_line here, but without it the
	     --More-- prompt isn't erased and neither is the text entered
	     thus far redisplayed.  */
	  displayer->erase_entire_line (displayer);
	  /* Note: The arguments to rl_abort are ignored.  */
	  rl_abort (0, 0);
	}
      if (for_pager && (c == NEWLINE || c == RETURN))
	return 2;
      if (for_pager && (c == 'q' || c == 'Q'))
	return 0;
      displayer->beep (displayer);
    }
}

/* Pager function for tab-completion.
   This is based on readline/complete.c:_rl_internal_pager.
   LINES is the number of lines of output displayed thus far.
   Returns:
   -1 -> user pressed 'n' or equivalent,
   0 -> user pressed 'y' or equivalent,
   N -> user pressed NEWLINE or equivalent and N is LINES - 1.  */

static int
gdb_display_match_list_pager (int lines,
			      const struct match_list_displayer *displayer)
{
  int i;

  displayer->puts (displayer, "--More--");
  displayer->flush (displayer);
  i = gdb_get_y_or_n (1, displayer);
  displayer->erase_entire_line (displayer);
  if (i == 0)
    return -1;
  else if (i == 2)
    return (lines - 1);
  else
    return 0;
}

/* Return true if FILENAME is a directory.
   Based on readline/complete.c:path_isdir.  */

static bool
gdb_path_isdir (const char *filename)
{
  struct stat finfo;

  return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
}

/* Return the portion of PATHNAME that should be output when listing
   possible completions.  If we are hacking filename completion, we
   are only interested in the basename, the portion following the
   final slash.  Otherwise, we return what we were passed.  Since
   printing empty strings is not very informative, if we're doing
   filename completion, and the basename is the empty string, we look
   for the previous slash and return the portion following that.  If
   there's no previous slash, we just return what we were passed.

   Based on readline/complete.c:printable_part.  */

static char *
gdb_printable_part (char *pathname)
{
  char *temp, *x;

  if (rl_filename_completion_desired == 0)	/* don't need to do anything */
    return (pathname);

  temp = strrchr (pathname, '/');
#if defined (__MSDOS__)
  if (temp == 0 && ISALPHA ((unsigned char)pathname[0]) && pathname[1] == ':')
    temp = pathname + 1;
#endif

  if (temp == 0 || *temp == '\0')
    return (pathname);
  /* If the basename is NULL, we might have a pathname like '/usr/src/'.
     Look for a previous slash and, if one is found, return the portion
     following that slash.  If there's no previous slash, just return the
     pathname we were passed. */
  else if (temp[1] == '\0')
    {
      for (x = temp - 1; x > pathname; x--)
	if (*x == '/')
	  break;
      return ((*x == '/') ? x + 1 : pathname);
    }
  else
    return ++temp;
}

/* Compute width of STRING when displayed on screen by print_filename.
   Based on readline/complete.c:fnwidth.  */

static int
gdb_fnwidth (const char *string)
{
  int width, pos;
#if defined (HANDLE_MULTIBYTE)
  mbstate_t ps;
  int left, w;
  size_t clen;
  wchar_t wc;

  left = strlen (string) + 1;
  memset (&ps, 0, sizeof (mbstate_t));
#endif

  width = pos = 0;
  while (string[pos])
    {
      if (CTRL_CHAR (string[pos]) || string[pos] == RUBOUT)
	{
	  width += 2;
	  pos++;
	}
      else
	{
#if defined (HANDLE_MULTIBYTE)
	  clen = mbrtowc (&wc, string + pos, left - pos, &ps);
	  if (MB_INVALIDCH (clen))
	    {
	      width++;
	      pos++;
	      memset (&ps, 0, sizeof (mbstate_t));
	    }
	  else if (MB_NULLWCH (clen))
	    break;
	  else
	    {
	      pos += clen;
	      w = wcwidth (wc);
	      width += (w >= 0) ? w : 1;
	    }
#else
	  width++;
	  pos++;
#endif
	}
    }

  return width;
}

/* Print TO_PRINT, one matching completion.
   PREFIX_BYTES is number of common prefix bytes.
   Based on readline/complete.c:fnprint.  */

static int
gdb_fnprint (const char *to_print, int prefix_bytes,
	     const struct match_list_displayer *displayer)
{
  int printed_len, w;
  const char *s;
#if defined (HANDLE_MULTIBYTE)
  mbstate_t ps;
  const char *end;
  size_t tlen;
  int width;
  wchar_t wc;

  end = to_print + strlen (to_print) + 1;
  memset (&ps, 0, sizeof (mbstate_t));
#endif

  printed_len = 0;

  /* Don't print only the ellipsis if the common prefix is one of the
     possible completions */
  if (to_print[prefix_bytes] == '\0')
    prefix_bytes = 0;

  if (prefix_bytes)
    {
      char ellipsis;

      ellipsis = (to_print[prefix_bytes] == '.') ? '_' : '.';
      for (w = 0; w < ELLIPSIS_LEN; w++)
	displayer->putch (displayer, ellipsis);
      printed_len = ELLIPSIS_LEN;
    }

  s = to_print + prefix_bytes;
  while (*s)
    {
      if (CTRL_CHAR (*s))
	{
	  displayer->putch (displayer, '^');
	  displayer->putch (displayer, UNCTRL (*s));
	  printed_len += 2;
	  s++;
#if defined (HANDLE_MULTIBYTE)
	  memset (&ps, 0, sizeof (mbstate_t));
#endif
	}
      else if (*s == RUBOUT)
	{
	  displayer->putch (displayer, '^');
	  displayer->putch (displayer, '?');
	  printed_len += 2;
	  s++;
#if defined (HANDLE_MULTIBYTE)
	  memset (&ps, 0, sizeof (mbstate_t));
#endif
	}
      else
	{
#if defined (HANDLE_MULTIBYTE)
	  tlen = mbrtowc (&wc, s, end - s, &ps);
	  if (MB_INVALIDCH (tlen))
	    {
	      tlen = 1;
	      width = 1;
	      memset (&ps, 0, sizeof (mbstate_t));
	    }
	  else if (MB_NULLWCH (tlen))
	    break;
	  else
	    {
	      w = wcwidth (wc);
	      width = (w >= 0) ? w : 1;
	    }
	  for (w = 0; w < tlen; ++w)
	    displayer->putch (displayer, s[w]);
	  s += tlen;
	  printed_len += width;
#else
	  displayer->putch (displayer, *s);
	  s++;
	  printed_len++;
#endif
	}
    }

  return printed_len;
}

/* Output TO_PRINT to rl_outstream.  If VISIBLE_STATS is defined and we
   are using it, check for and output a single character for `special'
   filenames.  Return the number of characters we output.
   Based on readline/complete.c:print_filename.  */

static int
gdb_print_filename (char *to_print, char *full_pathname, int prefix_bytes,
		    const struct match_list_displayer *displayer)
{
  int printed_len, extension_char, slen, tlen;
  char *s, c, *new_full_pathname;
  const char *dn;
  extern int _rl_complete_mark_directories;

  extension_char = 0;
  printed_len = gdb_fnprint (to_print, prefix_bytes, displayer);

#if defined (VISIBLE_STATS)
 if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
#else
 if (rl_filename_completion_desired && _rl_complete_mark_directories)
#endif
    {
      /* If to_print != full_pathname, to_print is the basename of the
	 path passed.  In this case, we try to expand the directory
	 name before checking for the stat character. */
      if (to_print != full_pathname)
	{
	  /* Terminate the directory name. */
	  c = to_print[-1];
	  to_print[-1] = '\0';

	  /* If setting the last slash in full_pathname to a NUL results in
	     full_pathname being the empty string, we are trying to complete
	     files in the root directory.  If we pass a null string to the
	     bash directory completion hook, for example, it will expand it
	     to the current directory.  We just want the `/'. */
	  if (full_pathname == 0 || *full_pathname == 0)
	    dn = "/";
	  else if (full_pathname[0] != '/')
	    dn = full_pathname;
	  else if (full_pathname[1] == 0)
	    dn = "//";		/* restore trailing slash to `//' */
	  else if (full_pathname[1] == '/' && full_pathname[2] == 0)
	    dn = "/";		/* don't turn /// into // */
	  else
	    dn = full_pathname;
	  s = tilde_expand (dn);
	  if (rl_directory_completion_hook)
	    (*rl_directory_completion_hook) (&s);

	  slen = strlen (s);
	  tlen = strlen (to_print);
	  new_full_pathname = (char *)xmalloc (slen + tlen + 2);
	  strcpy (new_full_pathname, s);
	  if (s[slen - 1] == '/')
	    slen--;
	  else
	    new_full_pathname[slen] = '/';
	  new_full_pathname[slen] = '/';
	  strcpy (new_full_pathname + slen + 1, to_print);

#if defined (VISIBLE_STATS)
	  if (rl_visible_stats)
	    extension_char = stat_char (new_full_pathname);
	  else
#endif
	  if (gdb_path_isdir (new_full_pathname))
	    extension_char = '/';

	  xfree (new_full_pathname);
	  to_print[-1] = c;
	}
      else
	{
	  s = tilde_expand (full_pathname);
#if defined (VISIBLE_STATS)
	  if (rl_visible_stats)
	    extension_char = stat_char (s);
	  else
#endif
	    if (gdb_path_isdir (s))
	      extension_char = '/';
	}

      xfree (s);
      if (extension_char)
	{
	  displayer->putch (displayer, extension_char);
	  printed_len++;
	}
    }

  return printed_len;
}

/* GDB version of readline/complete.c:complete_get_screenwidth.  */

static int
gdb_complete_get_screenwidth (const struct match_list_displayer *displayer)
{
  /* Readline has other stuff here which it's not clear we need.  */
  return displayer->width;
}

extern int _rl_completion_prefix_display_length;
extern int _rl_print_completions_horizontally;

extern "C" int _rl_qsort_string_compare (const void *, const void *);
typedef int QSFUNC (const void *, const void *);

/* GDB version of readline/complete.c:rl_display_match_list.
   See gdb_display_match_list for a description of MATCHES, LEN, MAX.
   Returns non-zero if all matches are displayed.  */

static int
gdb_display_match_list_1 (char **matches, int len, int max,
			  const struct match_list_displayer *displayer)
{
  int count, limit, printed_len, lines, cols;
  int i, j, k, l, common_length, sind;
  char *temp, *t;
  int page_completions = displayer->height != INT_MAX && pagination_enabled;

  /* Find the length of the prefix common to all items: length as displayed
     characters (common_length) and as a byte index into the matches (sind) */
  common_length = sind = 0;
  if (_rl_completion_prefix_display_length > 0)
    {
      t = gdb_printable_part (matches[0]);
      temp = strrchr (t, '/');
      common_length = temp ? gdb_fnwidth (temp) : gdb_fnwidth (t);
      sind = temp ? strlen (temp) : strlen (t);

      if (common_length > _rl_completion_prefix_display_length && common_length > ELLIPSIS_LEN)
	max -= common_length - ELLIPSIS_LEN;
      else
	common_length = sind = 0;
    }

  /* How many items of MAX length can we fit in the screen window? */
  cols = gdb_complete_get_screenwidth (displayer);
  max += 2;
  limit = cols / max;
  if (limit != 1 && (limit * max == cols))
    limit--;

  /* If cols == 0, limit will end up -1 */
  if (cols < displayer->width && limit < 0)
    limit = 1;

  /* Avoid a possible floating exception.  If max > cols,
     limit will be 0 and a divide-by-zero fault will result. */
  if (limit == 0)
    limit = 1;

  /* How many iterations of the printing loop? */
  count = (len + (limit - 1)) / limit;

  /* Watch out for special case.  If LEN is less than LIMIT, then
     just do the inner printing loop.
	   0 < len <= limit  implies  count = 1. */

  /* Sort the items if they are not already sorted. */
  if (rl_ignore_completion_duplicates == 0 && rl_sort_completion_matches)
    qsort (matches + 1, len, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);

  displayer->crlf (displayer);

  lines = 0;
  if (_rl_print_completions_horizontally == 0)
    {
      /* Print the sorted items, up-and-down alphabetically, like ls. */
      for (i = 1; i <= count; i++)
	{
	  for (j = 0, l = i; j < limit; j++)
	    {
	      if (l > len || matches[l] == 0)
		break;
	      else
		{
		  temp = gdb_printable_part (matches[l]);
		  printed_len = gdb_print_filename (temp, matches[l], sind,
						    displayer);

		  if (j + 1 < limit)
		    for (k = 0; k < max - printed_len; k++)
		      displayer->putch (displayer, ' ');
		}
	      l += count;
	    }
	  displayer->crlf (displayer);
	  lines++;
	  if (page_completions && lines >= (displayer->height - 1) && i < count)
	    {
	      lines = gdb_display_match_list_pager (lines, displayer);
	      if (lines < 0)
		return 0;
	    }
	}
    }
  else
    {
      /* Print the sorted items, across alphabetically, like ls -x. */
      for (i = 1; matches[i]; i++)
	{
	  temp = gdb_printable_part (matches[i]);
	  printed_len = gdb_print_filename (temp, matches[i], sind, displayer);
	  /* Have we reached the end of this line? */
	  if (matches[i+1])
	    {
	      if (i && (limit > 1) && (i % limit) == 0)
		{
		  displayer->crlf (displayer);
		  lines++;
		  if (page_completions && lines >= displayer->height - 1)
		    {
		      lines = gdb_display_match_list_pager (lines, displayer);
		      if (lines < 0)
			return 0;
		    }
		}
	      else
		for (k = 0; k < max - printed_len; k++)
		  displayer->putch (displayer, ' ');
	    }
	}
      displayer->crlf (displayer);
    }

  return 1;
}

/* Utility for displaying completion list matches, used by both CLI and TUI.

   MATCHES is the list of strings, in argv format, LEN is the number of
   strings in MATCHES, and MAX is the length of the longest string in
   MATCHES.  */

void
gdb_display_match_list (char **matches, int len, int max,
			const struct match_list_displayer *displayer)
{
  /* Readline will never call this if complete_line returned NULL.  */
  gdb_assert (max_completions != 0);

  /* complete_line will never return more than this.  */
  if (max_completions > 0)
    gdb_assert (len <= max_completions);

  if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
    {
      char msg[100];

      /* We can't use *query here because they wait for <RET> which is
	 wrong here.  This follows the readline version as closely as possible
	 for compatibility's sake.  See readline/complete.c.  */

      displayer->crlf (displayer);

      xsnprintf (msg, sizeof (msg),
		 "Display all %d possibilities? (y or n)", len);
      displayer->puts (displayer, msg);
      displayer->flush (displayer);

      if (gdb_get_y_or_n (0, displayer) == 0)
	{
	  displayer->crlf (displayer);
	  return;
	}
    }

  if (gdb_display_match_list_1 (matches, len, max, displayer))
    {
      /* Note: MAX_COMPLETIONS may be -1 or zero, but LEN is always > 0.  */
      if (len == max_completions)
	{
	  /* The maximum number of completions has been reached.  Warn the user
	     that there may be more.  */
	  const char *message = get_max_completions_reached_message ();

	  displayer->puts (displayer, message);
	  displayer->crlf (displayer);
	}
    }
}

/* See completer.h.  */

bool
skip_over_slash_fmt (completion_tracker &tracker, const char **args)
{
  const char *text = *args;

  if (text[0] == '/')
    {
      bool in_fmt;
      tracker.set_use_custom_word_point (true);

      if (text[1] == '\0')
	{
	  /* The user tried to complete after typing just the '/' character
	     of the /FMT string.  Step the completer past the '/', but we
	     don't offer any completions.  */
	  in_fmt = true;
	  ++text;
	}
      else
	{
	  /* The user has typed some characters after the '/', we assume
	     this is a complete /FMT string, first skip over it.  */
	  text = skip_to_space (text);

	  if (*text == '\0')
	    {
	      /* We're at the end of the input string.  The user has typed
		 '/FMT' and asked for a completion.  Push an empty
		 completion string, this will cause readline to insert a
		 space so the user now has '/FMT '.  */
	      in_fmt = true;
	      tracker.add_completion (make_unique_xstrdup (text));
	    }
	  else
	    {
	      /* The user has already typed things after the /FMT, skip the
		 whitespace and return false.  Whoever called this function
		 should then try to complete what comes next.  */
	      in_fmt = false;
	      text = skip_spaces (text);
	    }
	}

      tracker.advance_custom_word_point_by (text - *args);
      *args = text;
      return in_fmt;
    }

  return false;
}

INIT_GDB_FILE (completer)
{
  /* Setup some readline completion globals.  */
  rl_completion_word_break_hook = gdb_completion_word_break_characters;
  rl_attempted_completion_function = gdb_rl_attempted_completion_function;
  set_rl_completer_word_break_characters (default_word_break_characters ());

  /* Setup readline globals relating to filename completion.  */
  rl_filename_quote_characters = " \t\n\\\"'";
  rl_filename_dequoting_function = gdb_completer_file_name_dequote;
  rl_filename_quoting_function = gdb_completer_file_name_quote;
  rl_directory_rewrite_hook = gdb_completer_directory_rewrite;

  add_setshow_zuinteger_unlimited_cmd ("max-completions", no_class,
				       &max_completions, _("\
Set maximum number of completion candidates."), _("\
Show maximum number of completion candidates."), _("\
Use this to limit the number of candidates considered\n\
during completion.  Specifying \"unlimited\" or -1\n\
disables limiting.  Note that setting either no limit or\n\
a very large limit can make completion slow."),
				       NULL, NULL, &setlist, &showlist);
}
