/* GDB commands implemented in Scheme.

   Copyright (C) 2008-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/>.  */

/* See README file in this directory for implementation notes, coding
   conventions, et.al.  */

#include "charset.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "completer.h"
#include "guile-internal.h"

/* The <gdb:command> smob.

   Note: Commands are added to gdb using a two step process:
   1) Call make-command to create a <gdb:command> object.
   2) Call register-command! to add the command to gdb.
   It is done this way so that the constructor, make-command, doesn't have
   any side-effects.  This means that the smob needs to store everything
   that was passed to make-command.  */

struct command_smob
{
  /* This always appears first.  */
  gdb_smob base;

  /* The name of the command, as passed to make-command.  */
  char *name;

  /* The last word of the command.
     This is needed because add_cmd requires us to allocate space
     for it. :-(  */
  char *cmd_name;

  /* Non-zero if this is a prefix command.  */
  int is_prefix;

  /* One of the COMMAND_* constants.  */
  enum command_class cmd_class;

  /* The documentation for the command.  */
  char *doc;

  /* The corresponding gdb command object.
     This is NULL if the command has not been registered yet, or
     is no longer registered.  */
  struct cmd_list_element *command;

  /* A prefix command requires storage for a list of its sub-commands.
     A pointer to this is passed to add_prefix_command, and to add_cmd
     for sub-commands of that prefix.
     This is NULL if the command has not been registered yet, or
     is no longer registered.  If this command is not a prefix
     command, then this field is unused.  */
  struct cmd_list_element *sub_list;

  /* The procedure to call to invoke the command.
     (lambda (self arg from-tty) ...).
     Its result is unspecified.  */
  SCM invoke;

  /* Either #f, one of the COMPLETE_* constants, or a procedure to call to
     perform command completion.  Called as (lambda (self text word) ...).  */
  SCM complete;

  /* The <gdb:command> object we are contained in, needed to protect/unprotect
     the object since a reference to it comes from non-gc-managed space
     (the command context pointer).  */
  SCM containing_scm;
};

static const char command_smob_name[] = "gdb:command";

/* The tag Guile knows the objfile smob by.  */
static scm_t_bits command_smob_tag;

/* Keywords used by make-command.  */
static SCM invoke_keyword;
static SCM command_class_keyword;
static SCM completer_class_keyword;
static SCM prefix_p_keyword;
static SCM doc_keyword;

/* Struct representing built-in completion types.  */
struct cmdscm_completer
{
  /* Scheme symbol name.  */
  const char *name;
  /* Completion function.  */
  completer_ftype *completer;
};

static const struct cmdscm_completer cmdscm_completers[] =
{
  { "COMPLETE_NONE", noop_completer },
  { "COMPLETE_FILENAME", filename_maybe_quoted_completer },
  { "COMPLETE_LOCATION", location_completer },
  { "COMPLETE_COMMAND", command_completer },
  { "COMPLETE_SYMBOL", symbol_completer },
  { "COMPLETE_EXPRESSION", expression_completer },
};

#define N_COMPLETERS (sizeof (cmdscm_completers) \
		      / sizeof (cmdscm_completers[0]))

static int cmdscm_is_valid (command_smob *);

/* Administrivia for command smobs.  */

/* The smob "print" function for <gdb:command>.  */

static int
cmdscm_print_command_smob (SCM self, SCM port, scm_print_state *pstate)
{
  command_smob *c_smob = (command_smob *) SCM_SMOB_DATA (self);

  gdbscm_printf (port, "#<%s", command_smob_name);

  gdbscm_printf (port, " %s",
		 c_smob->name != NULL ? c_smob->name : "{unnamed}");

  if (! cmdscm_is_valid (c_smob))
    scm_puts (" {invalid}", port);

  scm_puts (">", port);

  scm_remember_upto_here_1 (self);

  /* Non-zero means success.  */
  return 1;
}

/* Low level routine to create a <gdb:command> object.
   It's empty in the sense that a command still needs to be associated
   with it.  */

static SCM
cmdscm_make_command_smob (void)
{
  command_smob *c_smob = (command_smob *)
    scm_gc_malloc (sizeof (command_smob), command_smob_name);
  SCM c_scm;

  memset (c_smob, 0, sizeof (*c_smob));
  c_smob->cmd_class = no_class;
  c_smob->invoke = SCM_BOOL_F;
  c_smob->complete = SCM_BOOL_F;
  c_scm = scm_new_smob (command_smob_tag, (scm_t_bits) c_smob);
  c_smob->containing_scm = c_scm;
  gdbscm_init_gsmob (&c_smob->base);

  return c_scm;
}

/* Clear the COMMAND pointer in C_SMOB and unprotect the object from GC.  */

static void
cmdscm_release_command (command_smob *c_smob)
{
  c_smob->command = NULL;
  scm_gc_unprotect_object (c_smob->containing_scm);
}

/* Return non-zero if SCM is a command smob.  */

static int
cmdscm_is_command (SCM scm)
{
  return SCM_SMOB_PREDICATE (command_smob_tag, scm);
}

/* (command? scm) -> boolean */

static SCM
gdbscm_command_p (SCM scm)
{
  return scm_from_bool (cmdscm_is_command (scm));
}

/* Returns the <gdb:command> object in SELF.
   Throws an exception if SELF is not a <gdb:command> object.  */

static SCM
cmdscm_get_command_arg_unsafe (SCM self, int arg_pos, const char *func_name)
{
  SCM_ASSERT_TYPE (cmdscm_is_command (self), self, arg_pos, func_name,
		   command_smob_name);

  return self;
}

/* Returns a pointer to the command smob of SELF.
   Throws an exception if SELF is not a <gdb:command> object.  */

static command_smob *
cmdscm_get_command_smob_arg_unsafe (SCM self, int arg_pos,
				    const char *func_name)
{
  SCM c_scm = cmdscm_get_command_arg_unsafe (self, arg_pos, func_name);
  command_smob *c_smob = (command_smob *) SCM_SMOB_DATA (c_scm);

  return c_smob;
}

/* Return non-zero if command C_SMOB is valid.  */

static int
cmdscm_is_valid (command_smob *c_smob)
{
  return c_smob->command != NULL;
}

/* Returns a pointer to the command smob of SELF.
   Throws an exception if SELF is not a valid <gdb:command> object.  */

static command_smob *
cmdscm_get_valid_command_smob_arg_unsafe (SCM self, int arg_pos,
					  const char *func_name)
{
  command_smob *c_smob
    = cmdscm_get_command_smob_arg_unsafe (self, arg_pos, func_name);

  if (!cmdscm_is_valid (c_smob))
    {
      gdbscm_invalid_object_error (func_name, arg_pos, self,
				   _("<gdb:command>"));
    }

  return c_smob;
}

/* Scheme functions for GDB commands.  */

/* (command-valid? <gdb:command>) -> boolean
   Returns #t if SELF is still valid.  */

static SCM
gdbscm_command_valid_p (SCM self)
{
  command_smob *c_smob
    = cmdscm_get_command_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  return scm_from_bool (cmdscm_is_valid (c_smob));
}

/* (dont-repeat cmd) -> unspecified
   Scheme function which wraps dont_repeat.  */

static SCM
gdbscm_dont_repeat (SCM self)
{
  /* We currently don't need anything from SELF, but still verify it.
     Call for side effects.  */
  cmdscm_get_valid_command_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);

  dont_repeat ();

  return SCM_UNSPECIFIED;
}

/* The make-command function.  */

/* Called if the gdb cmd_list_element is destroyed.  */

static void
cmdscm_destroyer (struct cmd_list_element *self, void *context)
{
  command_smob *c_smob = (command_smob *) context;

  cmdscm_release_command (c_smob);
}

/* Called by gdb to invoke the command.  */

static void
cmdscm_function (const char *args, int from_tty, cmd_list_element *command)
{
  command_smob *c_smob/*obj*/ = (command_smob *) command->context ();
  SCM arg_scm, tty_scm, result;

  gdb_assert (c_smob != NULL);

  if (args == NULL)
    args = "";
  arg_scm = gdbscm_scm_from_string (args, strlen (args), host_charset (), 1);
  if (gdbscm_is_exception (arg_scm))
    error (_("Could not convert arguments to Scheme string."));

  tty_scm = scm_from_bool (from_tty);

  result = gdbscm_safe_call_3 (c_smob->invoke, c_smob->containing_scm,
			       arg_scm, tty_scm, gdbscm_user_error_p);

  if (gdbscm_is_exception (result))
    {
      /* Don't print the stack if this was an error signalled by the command
	 itself.  */
      if (gdbscm_user_error_p (gdbscm_exception_key (result)))
	{
	  gdb::unique_xmalloc_ptr<char> msg
	    = gdbscm_exception_message_to_string (result);

	  error ("%s", msg.get ());
	}
      else
	{
	  gdbscm_print_gdb_exception (SCM_BOOL_F, result);
	  error (_("Error occurred in Scheme-implemented GDB command."));
	}
    }
}

/* Subroutine of cmdscm_completer to simplify it.
   Print an error message indicating that COMPLETION is a bad completion
   result.  */

static void
cmdscm_bad_completion_result (const char *msg, SCM completion)
{
  SCM port = scm_current_error_port ();

  scm_puts (msg, port);
  scm_display (completion, port);
  scm_newline (port);
}

/* Subroutine of cmdscm_completer to simplify it.
   Validate COMPLETION and add to RESULT.
   If an error occurs print an error message.
   The result is a boolean indicating success.  */

static int
cmdscm_add_completion (SCM completion, completion_tracker &tracker)
{
  SCM except_scm;

  if (!scm_is_string (completion))
    {
      /* Inform the user, but otherwise ignore the entire result.  */
      cmdscm_bad_completion_result (_("Bad text from completer: "),
				    completion);
      return 0;
    }

  gdb::unique_xmalloc_ptr<char> item
    = gdbscm_scm_to_string (completion, NULL, host_charset (), 1,
			    &except_scm);
  if (item == NULL)
    {
      /* Inform the user, but otherwise ignore the entire result.  */
      gdbscm_print_gdb_exception (SCM_BOOL_F, except_scm);
      return 0;
    }

  tracker.add_completion (std::move (item));

  return 1;
}

/* Called by gdb for command completion.  */

static void
cmdscm_completer (struct cmd_list_element *command,
		  completion_tracker &tracker,
		  const char *text, const char *word)
{
  command_smob *c_smob/*obj*/ = (command_smob *) command->context ();
  SCM completer_result_scm;
  SCM text_scm, word_scm;

  gdb_assert (c_smob != NULL);
  gdb_assert (gdbscm_is_procedure (c_smob->complete));

  text_scm = gdbscm_scm_from_string (text, strlen (text), host_charset (),
				     1);
  if (gdbscm_is_exception (text_scm))
    error (_("Could not convert \"text\" argument to Scheme string."));
  word_scm = gdbscm_scm_from_string (word, strlen (word), host_charset (),
				     1);
  if (gdbscm_is_exception (word_scm))
    error (_("Could not convert \"word\" argument to Scheme string."));

  completer_result_scm
    = gdbscm_safe_call_3 (c_smob->complete, c_smob->containing_scm,
			  text_scm, word_scm, NULL);

  if (gdbscm_is_exception (completer_result_scm))
    {
      /* Inform the user, but otherwise ignore.  */
      gdbscm_print_gdb_exception (SCM_BOOL_F, completer_result_scm);
      return;
    }

  if (gdbscm_is_true (scm_list_p (completer_result_scm)))
    {
      SCM list = completer_result_scm;

      while (!scm_is_eq (list, SCM_EOL))
	{
	  SCM next = scm_car (list);

	  if (!cmdscm_add_completion (next, tracker))
	    break;

	  list = scm_cdr (list);
	}
    }
  else if (itscm_is_iterator (completer_result_scm))
    {
      SCM iter = completer_result_scm;
      SCM next = itscm_safe_call_next_x (iter, NULL);

      while (gdbscm_is_true (next))
	{
	  if (gdbscm_is_exception (next))
	    {
	      /* Inform the user.  */
	      gdbscm_print_gdb_exception (SCM_BOOL_F, completer_result_scm);
	      break;
	    }

	  if (cmdscm_add_completion (next, tracker))
	    break;

	  next = itscm_safe_call_next_x (iter, NULL);
	}
    }
  else
    {
      /* Inform the user, but otherwise ignore.  */
      cmdscm_bad_completion_result (_("Bad completer result: "),
				    completer_result_scm);
    }
}

/* Helper for gdbscm_make_command which locates the command list to use and
   pulls out the command name.

   NAME is the command name list.  The final word in the list is the
   name of the new command.  All earlier words must be existing prefix
   commands.

   *BASE_LIST is set to the final prefix command's list of sub-commands.

   START_LIST is the list in which the search starts.

   When PREFIX_CMD is not NULL then *PREFIX_CMD is set to the prefix
   command itself, or NULL, if there is no prefix command.

   This function returns the xmalloc()d name of the new command.
   On error a Scheme exception is thrown.  */

char *
gdbscm_parse_command_name (const char *name,
			   const char *func_name, int arg_pos,
			   struct cmd_list_element ***base_list,
			   struct cmd_list_element **start_list,
			   struct cmd_list_element **prefix_cmd)
{
  struct cmd_list_element *elt;
  int len = strlen (name);
  int i, lastchar;
  char *msg;

  if (prefix_cmd != nullptr)
    *prefix_cmd = nullptr;

  /* Skip trailing whitespace.  */
  for (i = len - 1; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
    ;
  if (i < 0)
    {
      gdbscm_out_of_range_error (func_name, arg_pos,
				 gdbscm_scm_from_c_string (name),
				 _("no command name found"));
    }
  lastchar = i;

  /* Find first character of the final word.  */
  for (; i > 0 && valid_cmd_char_p (name[i - 1]); --i)
    ;

  gdb::unique_xmalloc_ptr<char> result
    = make_unique_xstrndup (&name[i], lastchar - i + 1);

  /* Skip whitespace again.  */
  for (--i; i >= 0 && (name[i] == ' ' || name[i] == '\t'); --i)
    ;
  if (i < 0)
    {
      *base_list = start_list;
      return result.release ();
    }

  gdb::unique_xmalloc_ptr<char> prefix_text
    = make_unique_xstrndup (name, i + 1);

  const char *prefix_text2 = prefix_text.get ();
  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
  if (elt == nullptr || elt == CMD_LIST_AMBIGUOUS || *prefix_text2 != '\0')
    {
      msg = xstrprintf (_("could not find command prefix '%s'"),
			prefix_text.get ()).release ();
      scm_dynwind_begin ((scm_t_dynwind_flags) 0);
      gdbscm_dynwind_xfree (msg);
      /* Release memory now as the destructors will not be run when the
	 guile exception is thrown.  */
      result = nullptr;
      prefix_text = nullptr;
      gdbscm_out_of_range_error (func_name, arg_pos,
				 gdbscm_scm_from_c_string (name), msg);
    }

  if (elt->is_prefix ())
    {
      *base_list = elt->subcommands;
      if (prefix_cmd != nullptr)
	*prefix_cmd = elt;
      return result.release ();
    }

  msg = xstrprintf (_("'%s' is not a prefix command"),
		    prefix_text.get ()).release ();
  scm_dynwind_begin ((scm_t_dynwind_flags) 0);
  gdbscm_dynwind_xfree (msg);
  /* Release memory now as the destructors will not be run when the guile
     exception is thrown.  */
  result = nullptr;
  prefix_text = nullptr;
  gdbscm_out_of_range_error (func_name, arg_pos,
			     gdbscm_scm_from_c_string (name), msg);
  /* NOTREACHED */
}

static const scheme_integer_constant command_classes[] =
{
  /* Note: alias and user are special; pseudo appears to be unused,
     and there is no reason to expose tui, I think.  */
  { "COMMAND_NONE", no_class },
  { "COMMAND_RUNNING", class_run },
  { "COMMAND_DATA", class_vars },
  { "COMMAND_STACK", class_stack },
  { "COMMAND_FILES", class_files },
  { "COMMAND_SUPPORT", class_support },
  { "COMMAND_STATUS", class_info },
  { "COMMAND_BREAKPOINTS", class_breakpoint },
  { "COMMAND_TRACEPOINTS", class_trace },
  { "COMMAND_OBSCURE", class_obscure },
  { "COMMAND_MAINTENANCE", class_maintenance },
  { "COMMAND_USER", class_user },

  END_INTEGER_CONSTANTS
};

/* Return non-zero if command_class is a valid command class.  */

int
gdbscm_valid_command_class_p (int command_class)
{
  int i;

  for (i = 0; command_classes[i].name != NULL; ++i)
    {
      if (command_classes[i].value == command_class)
	return 1;
    }

  return 0;
}

/* Return a normalized form of command NAME.
   That is tabs are replaced with spaces and multiple spaces are replaced
   with a single space.
   If WANT_TRAILING_SPACE is non-zero, add one space at the end.  This is for
   prefix commands.
   but that is the caller's responsibility.
   Space for the result is allocated on the GC heap.  */

char *
gdbscm_canonicalize_command_name (const char *name, int want_trailing_space)
{
  int i, out, seen_word;
  char *result
    = (char *) scm_gc_malloc_pointerless (strlen (name) + 2, FUNC_NAME);

  i = out = seen_word = 0;
  while (name[i])
    {
      /* Skip whitespace.  */
      while (name[i] == ' ' || name[i] == '\t')
	++i;
      /* Copy non-whitespace characters.  */
      if (name[i])
	{
	  if (seen_word)
	    result[out++] = ' ';
	  while (name[i] && name[i] != ' ' && name[i] != '\t')
	    result[out++] = name[i++];
	  seen_word = 1;
	}
    }
  if (want_trailing_space)
    result[out++] = ' ';
  result[out] = '\0';

  return result;
}

/* (make-command name [#:invoke lambda]
     [#:command-class class] [#:completer-class completer]
     [#:prefix? <bool>] [#:doc <string>]) -> <gdb:command>

   NAME is the name of the command.  It may consist of multiple words,
   in which case the final word is the name of the new command, and
   earlier words must be prefix commands.

   INVOKE is a procedure of three arguments that performs the command when
   invoked: (lambda (self arg from-tty) ...).
   Its result is unspecified.

   CLASS is the kind of command.  It must be one of the COMMAND_*
   constants defined in the gdb module.  If not specified, "no_class" is used.

   COMPLETER is the kind of completer.  It must be either:
     #f - completion is not supported for this command.
     One of the COMPLETE_* constants defined in the gdb module.
     A procedure of three arguments: (lambda (self text word) ...).
       Its result is one of:
	 A list of strings.
	 A <gdb:iterator> object that returns the set of possible completions,
	 ending with #f.
	 TODO(dje): Once PR 16699 is fixed, add support for returning
	 a COMPLETE_* constant.
   If not specified, then completion is not supported for this command.

   If PREFIX is #t, then this command is a prefix command.

   DOC is the doc string for the command.

   The result is the <gdb:command> Scheme object.
   The command is not available to be used yet, however.
   It must still be added to gdb with register-command!.  */

static SCM
gdbscm_make_command (SCM name_scm, SCM rest)
{
  const SCM keywords[] = {
    invoke_keyword, command_class_keyword, completer_class_keyword,
    prefix_p_keyword, doc_keyword, SCM_BOOL_F
  };
  int invoke_arg_pos = -1, command_class_arg_pos = 1;
  int completer_class_arg_pos = -1, is_prefix_arg_pos = -1;
  int doc_arg_pos = -1;
  char *s;
  char *name;
  enum command_class command_class = no_class;
  SCM completer_class = SCM_BOOL_F;
  int is_prefix = 0;
  char *doc = NULL;
  SCM invoke = SCM_BOOL_F;
  SCM c_scm;
  command_smob *c_smob;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#OiOts",
			      name_scm, &name, rest,
			      &invoke_arg_pos, &invoke,
			      &command_class_arg_pos, &command_class,
			      &completer_class_arg_pos, &completer_class,
			      &is_prefix_arg_pos, &is_prefix,
			      &doc_arg_pos, &doc);

  if (doc == NULL)
    doc = xstrdup (_("This command is not documented."));

  s = name;
  name = gdbscm_canonicalize_command_name (s, is_prefix);
  xfree (s);
  s = doc;
  doc = gdbscm_gc_xstrdup (s);
  xfree (s);

  if (is_prefix
      ? name[0] == ' '
      : name[0] == '\0')
    {
      gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, name_scm,
				 _("no command name found"));
    }

  if (gdbscm_is_true (invoke))
    {
      SCM_ASSERT_TYPE (gdbscm_is_procedure (invoke), invoke,
		       invoke_arg_pos, FUNC_NAME, _("procedure"));
    }

  if (!gdbscm_valid_command_class_p (command_class))
    {
      gdbscm_out_of_range_error (FUNC_NAME, command_class_arg_pos,
				 scm_from_int (command_class),
				 _("invalid command class argument"));
    }

  SCM_ASSERT_TYPE (gdbscm_is_false (completer_class)
		   || scm_is_integer (completer_class)
		   || gdbscm_is_procedure (completer_class),
		   completer_class, completer_class_arg_pos, FUNC_NAME,
		   _("integer or procedure"));
  if (scm_is_integer (completer_class)
      && !scm_is_signed_integer (completer_class, 0, N_COMPLETERS - 1))
    {
      gdbscm_out_of_range_error (FUNC_NAME, completer_class_arg_pos,
				 completer_class,
				 _("invalid completion type argument"));
    }

  c_scm = cmdscm_make_command_smob ();
  c_smob = (command_smob *) SCM_SMOB_DATA (c_scm);
  c_smob->name = name;
  c_smob->is_prefix = is_prefix;
  c_smob->cmd_class = command_class;
  c_smob->doc = doc;
  c_smob->invoke = invoke;
  c_smob->complete = completer_class;

  return c_scm;
}

/* (register-command! <gdb:command>) -> unspecified

   It is an error to register a command more than once.  */

static SCM
gdbscm_register_command_x (SCM self)
{
  command_smob *c_smob
    = cmdscm_get_command_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  char *cmd_name;
  struct cmd_list_element **cmd_list;
  struct cmd_list_element *cmd = NULL;

  if (cmdscm_is_valid (c_smob))
    scm_misc_error (FUNC_NAME, _("command is already registered"), SCM_EOL);

  struct cmd_list_element *prefix_cmd = nullptr;
  cmd_name = gdbscm_parse_command_name (c_smob->name, FUNC_NAME, SCM_ARG1,
					&cmd_list, &cmdlist, &prefix_cmd);
  c_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name);
  xfree (cmd_name);

  gdbscm_gdb_exception exc {};
  try
    {
      if (c_smob->is_prefix)
	{
	  bool has_invoke = gdbscm_is_true (c_smob->invoke) == 1;

	  if (has_invoke)
	    {
	      cmd = add_prefix_cmd (c_smob->cmd_name, c_smob->cmd_class,
				    NULL, c_smob->doc, &c_smob->sub_list,
				    1 /* allow_unknown */, cmd_list);
	      cmd->func = cmdscm_function;
	    }
	  else
	    {
	      /* If there is no 'invoke' method, then create the prefix
		 using the standard prefix callbacks.  This means that for
		 'set prefix' the user will get the help text listing all
		 of the sub-commands, and for 'show prefix', the user will
		 see all of the sub-command values.  */
	      if (prefix_cmd != nullptr)
		{
		  while (prefix_cmd->prefix != nullptr)
		    prefix_cmd = prefix_cmd->prefix;
		}

	      bool is_show = (prefix_cmd != nullptr
			      && prefix_cmd->subcommands == &showlist);

	      if (is_show)
		cmd = add_show_prefix_cmd (c_smob->cmd_name,
					   c_smob->cmd_class,
					   c_smob->doc,
					   &c_smob->sub_list,
					   0 /* allow_unknown */, cmd_list);
	      else
		cmd = add_basic_prefix_cmd (c_smob->cmd_name,
					    c_smob->cmd_class,
					    c_smob->doc,
					    &c_smob->sub_list,
					    0 /* allow_unknown */, cmd_list);
	    }
	}
      else
	{
	  cmd = add_cmd (c_smob->cmd_name, c_smob->cmd_class,
			 c_smob->doc, cmd_list);
	  cmd->func = cmdscm_function;
	}
    }
  catch (const gdb_exception &except)
    {
      exc = unpack (except);
    }
  GDBSCM_HANDLE_GDB_EXCEPTION (exc);

  /* Note: At this point the command exists in gdb.
     So no more errors after this point.  */

  /* There appears to be no API to set this.  */
  cmd->destroyer = cmdscm_destroyer;

  c_smob->command = cmd;
  cmd->set_context (c_smob);

  if (gdbscm_is_true (c_smob->complete))
    {
      set_cmd_completer (cmd,
			 scm_is_integer (c_smob->complete)
			 ? cmdscm_completers[scm_to_int (c_smob->complete)].completer
			 : cmdscm_completer);
    }

  /* The owner of this command is not in GC-controlled memory, so we need
     to protect it from GC until the command is deleted.  */
  scm_gc_protect_object (c_smob->containing_scm);

  return SCM_UNSPECIFIED;
}

/* Initialize the Scheme command support.  */

static const scheme_function command_functions[] =
{
  { "make-command", 1, 0, 1, as_a_scm_t_subr (gdbscm_make_command),
    "\
Make a GDB command object.\n\
\n\
  Arguments: name [#:invoke lambda]\n\
      [#:command-class <class>] [#:completer-class <completer>]\n\
      [#:prefix? <bool>] [#:doc string]\n\
    name: The name of the command.  It may consist of multiple words,\n\
      in which case the final word is the name of the new command, and\n\
      earlier words must be prefix commands.\n\
    invoke: A procedure of three arguments to perform the command.\n\
      (lambda (self arg from-tty) ...)\n\
      Its result is unspecified.\n\
    class: The class of the command, one of COMMAND_*.\n\
      The default is COMMAND_NONE.\n\
    completer: The kind of completer, #f, one of COMPLETE_*, or a procedure\n\
      to perform the completion: (lambda (self text word) ...).\n\
    prefix?: If true then the command is a prefix command.\n\
    doc: The \"doc string\" of the command.\n\
  Returns: <gdb:command> object" },

  { "register-command!", 1, 0, 0, as_a_scm_t_subr (gdbscm_register_command_x),
    "\
Register a <gdb:command> object with GDB." },

  { "command?", 1, 0, 0, as_a_scm_t_subr (gdbscm_command_p),
    "\
Return #t if the object is a <gdb:command> object." },

  { "command-valid?", 1, 0, 0, as_a_scm_t_subr (gdbscm_command_valid_p),
    "\
Return #t if the <gdb:command> object is valid." },

  { "dont-repeat", 1, 0, 0, as_a_scm_t_subr (gdbscm_dont_repeat),
    "\
Prevent command repetition when user enters an empty line.\n\
\n\
  Arguments: <gdb:command>\n\
  Returns: unspecified" },

  END_FUNCTIONS
};

/* Initialize the 'commands' code.  */

void
gdbscm_initialize_commands (void)
{
  int i;

  command_smob_tag
    = gdbscm_make_smob_type (command_smob_name, sizeof (command_smob));
  scm_set_smob_print (command_smob_tag, cmdscm_print_command_smob);

  gdbscm_define_integer_constants (command_classes, 1);
  gdbscm_define_functions (command_functions, 1);

  for (i = 0; i < N_COMPLETERS; ++i)
    {
      scm_c_define (cmdscm_completers[i].name, scm_from_int (i));
      scm_c_export (cmdscm_completers[i].name, NULL);
    }

  invoke_keyword = scm_from_latin1_keyword ("invoke");
  command_class_keyword = scm_from_latin1_keyword ("command-class");
  completer_class_keyword = scm_from_latin1_keyword ("completer-class");
  prefix_p_keyword = scm_from_latin1_keyword ("prefix?");
  doc_keyword = scm_from_latin1_keyword ("doc");
}
