/* GDB commands implemented in Scheme.

   Copyright (C) 2008-2021 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 "defs.h"
#include <ctype.h>
#include "charset.h"
#include "gdbcmd.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_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.

   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 *elt;
  int len = strlen (name);
  int i, lastchar;
  char *prefix_text;
  const char *prefix_text2;
  char *result, *msg;

  /* 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)
    ;
  result = (char *) xmalloc (lastchar - i + 2);
  memcpy (result, &name[i], lastchar - i + 1);
  result[lastchar - i + 1] = '\0';

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

  prefix_text = (char *) xmalloc (i + 2);
  memcpy (prefix_text, name, i + 1);
  prefix_text[i + 1] = '\0';

  prefix_text2 = prefix_text;
  elt = lookup_cmd_1 (&prefix_text2, *start_list, NULL, NULL, 1);
  if (elt == NULL || elt == CMD_LIST_AMBIGUOUS)
    {
      msg = xstrprintf (_("could not find command prefix '%s'"), prefix_text);
      xfree (prefix_text);
      xfree (result);
      scm_dynwind_begin ((scm_t_dynwind_flags) 0);
      gdbscm_dynwind_xfree (msg);
      gdbscm_out_of_range_error (func_name, arg_pos,
				 gdbscm_scm_from_c_string (name), msg);
    }

  if (elt->is_prefix ())
    {
      xfree (prefix_text);
      *base_list = elt->subcommands;
      return result;
    }

  msg = xstrprintf (_("'%s' is not a prefix command"), prefix_text);
  xfree (prefix_text);
  xfree (result);
  scm_dynwind_begin ((scm_t_dynwind_flags) 0);
  gdbscm_dynwind_xfree (msg);
  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);

  cmd_name = gdbscm_parse_command_name (c_smob->name, FUNC_NAME, SCM_ARG1,
					&cmd_list, &cmdlist);
  c_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name);
  xfree (cmd_name);

  gdbscm_gdb_exception exc {};
  try
    {
      if (c_smob->is_prefix)
	{
	  /* If we have our own "invoke" method, then allow unknown
	     sub-commands.  */
	  int allow_unknown = gdbscm_is_true (c_smob->invoke);

	  cmd = add_prefix_cmd (c_smob->cmd_name, c_smob->cmd_class,
				NULL, c_smob->doc, &c_smob->sub_list,
				allow_unknown, cmd_list);
	}
      else
	{
	  cmd = add_cmd (c_smob->cmd_name, c_smob->cmd_class,
			 c_smob->doc, cmd_list);
	}
    }
  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->func = cmdscm_function;
  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");
}
