/* GDB CLI command scripting.

   Copyright (C) 1986-2020 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 "defs.h"
#include "value.h"
#include "language.h"		/* For value_true */
#include <ctype.h>

#include "ui-out.h"
#include "top.h"
#include "breakpoint.h"
#include "tracepoint.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "cli/cli-script.h"
#include "cli/cli-style.h"

#include "extension.h"
#include "interps.h"
#include "compile/compile.h"
#include "gdbsupport/gdb_string_view.h"
#include "python/python.h"
#include "guile/guile.h"

#include <vector>

/* Prototypes for local functions.  */

static enum command_control_type
recurse_read_control_structure
    (gdb::function_view<const char * ()> read_next_line_func,
     struct command_line *current_cmd,
     gdb::function_view<void (const char *)> validator);

static void do_define_command (const char *comname, int from_tty,
			       const counted_command_line *commands);

static const char *read_next_line ();

/* Level of control structure when reading.  */
static int control_level;

/* Level of control structure when executing.  */
static int command_nest_depth = 1;

/* This is to prevent certain commands being printed twice.  */
static int suppress_next_print_command_trace = 0;

/* Command element for the 'while' command.  */
static cmd_list_element *while_cmd_element = nullptr;

/* Command element for the 'if' command.  */
static cmd_list_element *if_cmd_element = nullptr;

/* Command element for the 'define' command.  */
static cmd_list_element *define_cmd_element = nullptr;

/* Structure for arguments to user defined functions.  */

class user_args
{
public:
  /* Save the command line and store the locations of arguments passed
     to the user defined function.  */
  explicit user_args (const char *line);

  /* Insert the stored user defined arguments into the $arg arguments
     found in LINE.  */
  std::string insert_args (const char *line) const;

private:
  /* Disable copy/assignment.  (Since the elements of A point inside
     COMMAND, copying would need to reconstruct the A vector in the
     new copy.)  */
  user_args (const user_args &) =delete;
  user_args &operator= (const user_args &) =delete;

  /* It is necessary to store a copy of the command line to ensure
     that the arguments are not overwritten before they are used.  */
  std::string m_command_line;

  /* The arguments.  Each element points inside M_COMMAND_LINE.  */
  std::vector<gdb::string_view> m_args;
};

/* The stack of arguments passed to user defined functions.  We need a
   stack because user-defined functions can call other user-defined
   functions.  */
static std::vector<std::unique_ptr<user_args>> user_args_stack;

/* An RAII-base class used to push/pop args on the user args
   stack.  */
struct scoped_user_args_level
{
  /* Parse the command line and push the arguments in the user args
     stack.  */
  explicit scoped_user_args_level (const char *line)
  {
    user_args_stack.emplace_back (new user_args (line));
  }

  /* Pop the current user arguments from the stack.  */
  ~scoped_user_args_level ()
  {
    user_args_stack.pop_back ();
  }
};


/* Return non-zero if TYPE is a multi-line command (i.e., is terminated
   by "end").  */

static int
multi_line_command_p (enum command_control_type type)
{
  switch (type)
    {
    case if_control:
    case while_control:
    case while_stepping_control:
    case commands_control:
    case compile_control:
    case python_control:
    case guile_control:
    case define_control:
      return 1;
    default:
      return 0;
    }
}

/* Allocate, initialize a new command line structure for one of the
   control commands (if/while).  */

static struct command_line *
build_command_line (enum command_control_type type, const char *args)
{
  if (args == NULL || *args == '\0')
    {
      if (type == if_control)
	error (_("if command requires an argument."));
      else if (type == while_control)
	error (_("while command requires an argument."));
      else if (type == define_control)
	error (_("define command requires an argument."));
    }
  gdb_assert (args != NULL);

  return new struct command_line (type, xstrdup (args));
}

/* Build and return a new command structure for the control commands
   such as "if" and "while".  */

counted_command_line
get_command_line (enum command_control_type type, const char *arg)
{
  /* Allocate and build a new command line structure.  */
  counted_command_line cmd (build_command_line (type, arg),
			    command_lines_deleter ());

  /* Read in the body of this command.  */
  if (recurse_read_control_structure (read_next_line, cmd.get (), 0)
      == invalid_control)
    {
      warning (_("Error reading in canned sequence of commands."));
      return NULL;
    }

  return cmd;
}

/* Recursively print a command (including full control structures).  */

void
print_command_lines (struct ui_out *uiout, struct command_line *cmd,
		     unsigned int depth)
{
  struct command_line *list;

  list = cmd;
  while (list)
    {
      if (depth)
	uiout->spaces (2 * depth);

      /* A simple command, print it and continue.  */
      if (list->control_type == simple_control)
	{
	  uiout->field_string (NULL, list->line);
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      /* loop_continue to jump to the start of a while loop, print it
	 and continue. */
      if (list->control_type == continue_control)
	{
	  uiout->field_string (NULL, "loop_continue");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      /* loop_break to break out of a while loop, print it and
	 continue.  */
      if (list->control_type == break_control)
	{
	  uiout->field_string (NULL, "loop_break");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      /* A while command.  Recursively print its subcommands and
	 continue.  */
      if (list->control_type == while_control
	  || list->control_type == while_stepping_control)
	{
	  /* For while-stepping, the line includes the 'while-stepping'
	     token.  See comment in process_next_line for explanation.
	     Here, take care not print 'while-stepping' twice.  */
	  if (list->control_type == while_control)
	    uiout->field_fmt (NULL, "while %s", list->line);
	  else
	    uiout->field_string (NULL, list->line);
	  uiout->text ("\n");
	  print_command_lines (uiout, list->body_list_0.get (), depth + 1);
	  if (depth)
	    uiout->spaces (2 * depth);
	  uiout->field_string (NULL, "end");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      /* An if command.  Recursively print both arms before
	 continuing.  */
      if (list->control_type == if_control)
	{
	  uiout->field_fmt (NULL, "if %s", list->line);
	  uiout->text ("\n");
	  /* The true arm.  */
	  print_command_lines (uiout, list->body_list_0.get (), depth + 1);

	  /* Show the false arm if it exists.  */
	  if (list->body_list_1 != nullptr)
	    {
	      if (depth)
		uiout->spaces (2 * depth);
	      uiout->field_string (NULL, "else");
	      uiout->text ("\n");
	      print_command_lines (uiout, list->body_list_1.get (), depth + 1);
	    }

	  if (depth)
	    uiout->spaces (2 * depth);
	  uiout->field_string (NULL, "end");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      /* A commands command.  Print the breakpoint commands and
	 continue.  */
      if (list->control_type == commands_control)
	{
	  if (*(list->line))
	    uiout->field_fmt (NULL, "commands %s", list->line);
	  else
	    uiout->field_string (NULL, "commands");
	  uiout->text ("\n");
	  print_command_lines (uiout, list->body_list_0.get (), depth + 1);
	  if (depth)
	    uiout->spaces (2 * depth);
	  uiout->field_string (NULL, "end");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      if (list->control_type == python_control)
	{
	  uiout->field_string (NULL, "python");
	  uiout->text ("\n");
	  /* Don't indent python code at all.  */
	  print_command_lines (uiout, list->body_list_0.get (), 0);
	  if (depth)
	    uiout->spaces (2 * depth);
	  uiout->field_string (NULL, "end");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      if (list->control_type == compile_control)
	{
	  uiout->field_string (NULL, "compile expression");
	  uiout->text ("\n");
	  print_command_lines (uiout, list->body_list_0.get (), 0);
	  if (depth)
	    uiout->spaces (2 * depth);
	  uiout->field_string (NULL, "end");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      if (list->control_type == guile_control)
	{
	  uiout->field_string (NULL, "guile");
	  uiout->text ("\n");
	  print_command_lines (uiout, list->body_list_0.get (), depth + 1);
	  if (depth)
	    uiout->spaces (2 * depth);
	  uiout->field_string (NULL, "end");
	  uiout->text ("\n");
	  list = list->next;
	  continue;
	}

      /* Ignore illegal command type and try next.  */
      list = list->next;
    }				/* while (list) */
}

/* Handle pre-post hooks.  */

class scoped_restore_hook_in
{
public:

  scoped_restore_hook_in (struct cmd_list_element *c)
    : m_cmd (c)
  {
  }

  ~scoped_restore_hook_in ()
  {
    m_cmd->hook_in = 0;
  }

  scoped_restore_hook_in (const scoped_restore_hook_in &) = delete;
  scoped_restore_hook_in &operator= (const scoped_restore_hook_in &) = delete;

private:

  struct cmd_list_element *m_cmd;
};

void
execute_cmd_pre_hook (struct cmd_list_element *c)
{
  if ((c->hook_pre) && (!c->hook_in))
    {
      scoped_restore_hook_in restore_hook (c);
      c->hook_in = 1; /* Prevent recursive hooking.  */
      execute_user_command (c->hook_pre, nullptr);
    }
}

void
execute_cmd_post_hook (struct cmd_list_element *c)
{
  if ((c->hook_post) && (!c->hook_in))
    {
      scoped_restore_hook_in restore_hook (c);
      c->hook_in = 1; /* Prevent recursive hooking.  */
      execute_user_command (c->hook_post, nullptr);
    }
}

/* See cli-script.h.  */

void
execute_control_commands (struct command_line *cmdlines, int from_tty)
{
  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
  scoped_restore save_nesting
    = make_scoped_restore (&command_nest_depth, command_nest_depth + 1);

  while (cmdlines)
    {
      enum command_control_type ret = execute_control_command (cmdlines,
							       from_tty);
      if (ret != simple_control && ret != break_control)
	{
	  warning (_("Error executing canned sequence of commands."));
	  break;
	}
      cmdlines = cmdlines->next;
    }
}

/* See cli-script.h.  */

std::string
execute_control_commands_to_string (struct command_line *commands,
				    int from_tty)
{
  /* GDB_STDOUT should be better already restored during these
     restoration callbacks.  */
  set_batch_flag_and_restore_page_info save_page_info;

  string_file str_file;

  {
    current_uiout->redirect (&str_file);
    ui_out_redirect_pop redirect_popper (current_uiout);

    scoped_restore save_stdout
      = make_scoped_restore (&gdb_stdout, &str_file);
    scoped_restore save_stderr
      = make_scoped_restore (&gdb_stderr, &str_file);
    scoped_restore save_stdlog
      = make_scoped_restore (&gdb_stdlog, &str_file);
    scoped_restore save_stdtarg
      = make_scoped_restore (&gdb_stdtarg, &str_file);
    scoped_restore save_stdtargerr
      = make_scoped_restore (&gdb_stdtargerr, &str_file);

    execute_control_commands (commands, from_tty);
  }

  return std::move (str_file.string ());
}

void
execute_user_command (struct cmd_list_element *c, const char *args)
{
  counted_command_line cmdlines_copy;

  /* Ensure that the user commands can't be deleted while they are
     executing.  */
  cmdlines_copy = c->user_commands;
  if (cmdlines_copy == 0)
    /* Null command */
    return;
  struct command_line *cmdlines = cmdlines_copy.get ();

  scoped_user_args_level push_user_args (args);

  if (user_args_stack.size () > max_user_call_depth)
    error (_("Max user call depth exceeded -- command aborted."));

  /* Set the instream to nullptr, indicating execution of a
     user-defined function.  */
  scoped_restore restore_instream
    = make_scoped_restore (&current_ui->instream, nullptr);

  execute_control_commands (cmdlines, 0);
}

/* This function is called every time GDB prints a prompt.  It ensures
   that errors and the like do not confuse the command tracing.  */

void
reset_command_nest_depth (void)
{
  command_nest_depth = 1;

  /* Just in case.  */
  suppress_next_print_command_trace = 0;
}

/* Print the command, prefixed with '+' to represent the call depth.
   This is slightly complicated because this function may be called
   from execute_command and execute_control_command.  Unfortunately
   execute_command also prints the top level control commands.
   In these cases execute_command will call execute_control_command
   via while_command or if_command.  Inner levels of 'if' and 'while'
   are dealt with directly.  Therefore we can use these functions
   to determine whether the command has been printed already or not.  */
ATTRIBUTE_PRINTF (1, 2)
void
print_command_trace (const char *fmt, ...)
{
  int i;

  if (suppress_next_print_command_trace)
    {
      suppress_next_print_command_trace = 0;
      return;
    }

  if (!source_verbose && !trace_commands)
    return;

  for (i=0; i < command_nest_depth; i++)
    printf_filtered ("+");

  va_list args;

  va_start (args, fmt);
  vprintf_filtered (fmt, args);
  va_end (args);
  puts_filtered ("\n");
}

/* Helper for execute_control_command.  */

static enum command_control_type
execute_control_command_1 (struct command_line *cmd, int from_tty)
{
  struct command_line *current;
  struct value *val;
  struct value *val_mark;
  int loop;
  enum command_control_type ret;

  /* Start by assuming failure, if a problem is detected, the code
     below will simply "break" out of the switch.  */
  ret = invalid_control;

  switch (cmd->control_type)
    {
    case simple_control:
      {
	/* A simple command, execute it and return.  */
	std::string new_line = insert_user_defined_cmd_args (cmd->line);
	execute_command (new_line.c_str (), from_tty);
	ret = cmd->control_type;
	break;
      }

    case continue_control:
      print_command_trace ("loop_continue");

      /* Return for "continue", and "break" so we can either
	 continue the loop at the top, or break out.  */
      ret = cmd->control_type;
      break;

    case break_control:
      print_command_trace ("loop_break");

      /* Return for "continue", and "break" so we can either
	 continue the loop at the top, or break out.  */
      ret = cmd->control_type;
      break;

    case while_control:
      {
	print_command_trace ("while %s", cmd->line);

	/* Parse the loop control expression for the while statement.  */
	std::string new_line = insert_user_defined_cmd_args (cmd->line);
	expression_up expr = parse_expression (new_line.c_str ());

	ret = simple_control;
	loop = 1;

	/* Keep iterating so long as the expression is true.  */
	while (loop == 1)
	  {
	    int cond_result;

	    QUIT;

	    /* Evaluate the expression.  */
	    val_mark = value_mark ();
	    val = evaluate_expression (expr.get ());
	    cond_result = value_true (val);
	    value_free_to_mark (val_mark);

	    /* If the value is false, then break out of the loop.  */
	    if (!cond_result)
	      break;

	    /* Execute the body of the while statement.  */
	    current = cmd->body_list_0.get ();
	    while (current)
	      {
		scoped_restore save_nesting
		  = make_scoped_restore (&command_nest_depth, command_nest_depth + 1);
		ret = execute_control_command_1 (current, from_tty);

		/* If we got an error, or a "break" command, then stop
		   looping.  */
		if (ret == invalid_control || ret == break_control)
		  {
		    loop = 0;
		    break;
		  }

		/* If we got a "continue" command, then restart the loop
		   at this point.  */
		if (ret == continue_control)
		  break;

		/* Get the next statement.  */
		current = current->next;
	      }
	  }

	/* Reset RET so that we don't recurse the break all the way down.  */
	if (ret == break_control)
	  ret = simple_control;

	break;
      }

    case if_control:
      {
	print_command_trace ("if %s", cmd->line);

	/* Parse the conditional for the if statement.  */
	std::string new_line = insert_user_defined_cmd_args (cmd->line);
	expression_up expr = parse_expression (new_line.c_str ());

	current = NULL;
	ret = simple_control;

	/* Evaluate the conditional.  */
	val_mark = value_mark ();
	val = evaluate_expression (expr.get ());

	/* Choose which arm to take commands from based on the value
	   of the conditional expression.  */
	if (value_true (val))
	  current = cmd->body_list_0.get ();
	else if (cmd->body_list_1 != nullptr)
	  current = cmd->body_list_1.get ();
	value_free_to_mark (val_mark);

	/* Execute commands in the given arm.  */
	while (current)
	  {
	    scoped_restore save_nesting
	      = make_scoped_restore (&command_nest_depth, command_nest_depth + 1);
	    ret = execute_control_command_1 (current, from_tty);

	    /* If we got an error, get out.  */
	    if (ret != simple_control)
	      break;

	    /* Get the next statement in the body.  */
	    current = current->next;
	  }

	break;
      }

    case commands_control:
      {
	/* Breakpoint commands list, record the commands in the
	   breakpoint's command list and return.  */
	std::string new_line = insert_user_defined_cmd_args (cmd->line);
	ret = commands_from_control_command (new_line.c_str (), cmd);
	break;
      }

    case compile_control:
      eval_compile_command (cmd, NULL, cmd->control_u.compile.scope,
			    cmd->control_u.compile.scope_data);
      ret = simple_control;
      break;

    case define_control:
      print_command_trace ("define %s", cmd->line);
      do_define_command (cmd->line, 0, &cmd->body_list_0);
      ret = simple_control;
      break;

    case python_control:
    case guile_control:
      {
	eval_ext_lang_from_control_command (cmd);
	ret = simple_control;
	break;
      }

    default:
      warning (_("Invalid control type in canned commands structure."));
      break;
    }

  return ret;
}

enum command_control_type
execute_control_command (struct command_line *cmd, int from_tty)
{
  if (!current_uiout->is_mi_like_p ())
    return execute_control_command_1 (cmd, from_tty);

  /* Make sure we use the console uiout.  It's possible that we are executing
     breakpoint commands while running the MI interpreter.  */
  interp *console = interp_lookup (current_ui, INTERP_CONSOLE);
  scoped_restore save_uiout
    = make_scoped_restore (&current_uiout, console->interp_ui_out ());

  return execute_control_command_1 (cmd, from_tty);
}

/* Like execute_control_command, but first set
   suppress_next_print_command_trace.  */

enum command_control_type
execute_control_command_untraced (struct command_line *cmd)
{
  suppress_next_print_command_trace = 1;
  return execute_control_command (cmd);
}


/* "while" command support.  Executes a body of statements while the
   loop condition is nonzero.  */

static void
while_command (const char *arg, int from_tty)
{
  control_level = 1;
  counted_command_line command = get_command_line (while_control, arg);

  if (command == NULL)
    return;

  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);

  execute_control_command_untraced (command.get ());
}

/* "if" command support.  Execute either the true or false arm depending
   on the value of the if conditional.  */

static void
if_command (const char *arg, int from_tty)
{
  control_level = 1;
  counted_command_line command = get_command_line (if_control, arg);

  if (command == NULL)
    return;

  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);

  execute_control_command_untraced (command.get ());
}

/* Bind the incoming arguments for a user defined command to $arg0,
   $arg1 ... $argN.  */

user_args::user_args (const char *command_line)
{
  const char *p;

  if (command_line == NULL)
    return;

  m_command_line = command_line;
  p = m_command_line.c_str ();

  while (*p)
    {
      const char *start_arg;
      int squote = 0;
      int dquote = 0;
      int bsquote = 0;

      /* Strip whitespace.  */
      while (*p == ' ' || *p == '\t')
	p++;

      /* P now points to an argument.  */
      start_arg = p;

      /* Get to the end of this argument.  */
      while (*p)
	{
	  if (((*p == ' ' || *p == '\t')) && !squote && !dquote && !bsquote)
	    break;
	  else
	    {
	      if (bsquote)
		bsquote = 0;
	      else if (*p == '\\')
		bsquote = 1;
	      else if (squote)
		{
		  if (*p == '\'')
		    squote = 0;
		}
	      else if (dquote)
		{
		  if (*p == '"')
		    dquote = 0;
		}
	      else
		{
		  if (*p == '\'')
		    squote = 1;
		  else if (*p == '"')
		    dquote = 1;
		}
	      p++;
	    }
	}

      m_args.emplace_back (start_arg, p - start_arg);
    }
}

/* Given character string P, return a point to the first argument
   ($arg), or NULL if P contains no arguments.  */

static const char *
locate_arg (const char *p)
{
  while ((p = strchr (p, '$')))
    {
      if (startswith (p, "$arg")
	  && (isdigit (p[4]) || p[4] == 'c'))
	return p;
      p++;
    }
  return NULL;
}

/* See cli-script.h.  */

std::string
insert_user_defined_cmd_args (const char *line)
{
  /* If we are not in a user-defined command, treat $argc, $arg0, et
     cetera as normal convenience variables.  */
  if (user_args_stack.empty ())
    return line;

  const std::unique_ptr<user_args> &args = user_args_stack.back ();
  return args->insert_args (line);
}

/* Insert the user defined arguments stored in user_args into the $arg
   arguments found in line.  */

std::string
user_args::insert_args (const char *line) const
{
  std::string new_line;
  const char *p;

  while ((p = locate_arg (line)))
    {
      new_line.append (line, p - line);

      if (p[4] == 'c')
	{
	  new_line += std::to_string (m_args.size ());
	  line = p + 5;
	}
      else
	{
	  char *tmp;
	  unsigned long i;

	  errno = 0;
	  i = strtoul (p + 4, &tmp, 10);
	  if ((i == 0 && tmp == p + 4) || errno != 0)
	    line = p + 4;
	  else if (i >= m_args.size ())
	    error (_("Missing argument %ld in user function."), i);
	  else
	    {
	      new_line.append (m_args[i].data (), m_args[i].length ());
	      line = tmp;
	    }
	}
    }
  /* Don't forget the tail.  */
  new_line.append (line);

  return new_line;
}


/* Read next line from stdin.  Passed to read_command_line_1 and
   recurse_read_control_structure whenever we need to read commands
   from stdin.  */

static const char *
read_next_line ()
{
  struct ui *ui = current_ui;
  char *prompt_ptr, control_prompt[256];
  int i = 0;
  int from_tty = ui->instream == ui->stdin_stream;

  if (control_level >= 254)
    error (_("Control nesting too deep!"));

  /* Set a prompt based on the nesting of the control commands.  */
  if (from_tty
      || (ui->instream == 0 && deprecated_readline_hook != NULL))
    {
      for (i = 0; i < control_level; i++)
	control_prompt[i] = ' ';
      control_prompt[i] = '>';
      control_prompt[i + 1] = '\0';
      prompt_ptr = (char *) &control_prompt[0];
    }
  else
    prompt_ptr = NULL;

  return command_line_input (prompt_ptr, "commands");
}

/* Given an input line P, skip the command and return a pointer to the
   first argument.  */

static const char *
line_first_arg (const char *p)
{
  const char *first_arg = p + find_command_name_length (p);

  return skip_spaces (first_arg); 
}

/* Process one input line.  If the command is an "end", return such an
   indication to the caller.  If PARSE_COMMANDS is true, strip leading
   whitespace (trailing whitespace is always stripped) in the line,
   attempt to recognize GDB control commands, and also return an
   indication if the command is an "else" or a nop.

   Otherwise, only "end" is recognized.  */

static enum misc_command_type
process_next_line (const char *p, struct command_line **command,
		   int parse_commands,
		   gdb::function_view<void (const char *)> validator)

{
  const char *p_end;
  const char *p_start;
  int not_handled = 0;

  /* Not sure what to do here.  */
  if (p == NULL)
    return end_command;

  /* Strip trailing whitespace.  */
  p_end = p + strlen (p);
  while (p_end > p && (p_end[-1] == ' ' || p_end[-1] == '\t'))
    p_end--;

  p_start = p;
  /* Strip leading whitespace.  */
  while (p_start < p_end && (*p_start == ' ' || *p_start == '\t'))
    p_start++;

  /* 'end' is always recognized, regardless of parse_commands value.
     We also permit whitespace before end and after.  */
  if (p_end - p_start == 3 && startswith (p_start, "end"))
    return end_command;

  if (parse_commands)
    {
      /* Resolve command abbreviations (e.g. 'ws' for 'while-stepping').  */
      const char *cmd_name = p;
      struct cmd_list_element *cmd
	= lookup_cmd_1 (&cmd_name, cmdlist, NULL, NULL, 1);
      cmd_name = skip_spaces (cmd_name);
      bool inline_cmd = *cmd_name != '\0';

      /* If commands are parsed, we skip initial spaces.  Otherwise,
	 which is the case for Python commands and documentation
	 (see the 'document' command), spaces are preserved.  */
      p = p_start;

      /* Blanks and comments don't really do anything, but we need to
	 distinguish them from else, end and other commands which can
	 be executed.  */
      if (p_end == p || p[0] == '#')
	return nop_command;

      /* Is the else clause of an if control structure?  */
      if (p_end - p == 4 && startswith (p, "else"))
	return else_command;

      /* Check for while, if, break, continue, etc and build a new
	 command line structure for them.  */
      if (cmd == while_stepping_cmd_element)
	{
	  /* Because validate_actionline and encode_action lookup
	     command's line as command, we need the line to
	     include 'while-stepping'.

	     For 'ws' alias, the command will have 'ws', not expanded
	     to 'while-stepping'.  This is intentional -- we don't
	     really want frontend to send a command list with 'ws',
	     and next break-info returning command line with
	     'while-stepping'.  This should work, but might cause the
	     breakpoint to be marked as changed while it's actually
	     not.  */
	  *command = build_command_line (while_stepping_control, p);
	}
      else if (cmd == while_cmd_element)
	*command = build_command_line (while_control, line_first_arg (p));
      else if (cmd == if_cmd_element)
	*command = build_command_line (if_control, line_first_arg (p));
      else if (cmd == commands_cmd_element)
	*command = build_command_line (commands_control, line_first_arg (p));
      else if (cmd == define_cmd_element)
	*command = build_command_line (define_control, line_first_arg (p));
      else if (cmd == python_cmd_element && !inline_cmd)
	{
	  /* Note that we ignore the inline "python command" form
	     here.  */
	  *command = build_command_line (python_control, "");
	}
      else if (cmd == compile_cmd_element && !inline_cmd)
	{
	  /* Note that we ignore the inline "compile command" form
	     here.  */
	  *command = build_command_line (compile_control, "");
	  (*command)->control_u.compile.scope = COMPILE_I_INVALID_SCOPE;
	}
      else if (cmd == guile_cmd_element && !inline_cmd)
	{
	  /* Note that we ignore the inline "guile command" form here.  */
	  *command = build_command_line (guile_control, "");
	}
      else if (p_end - p == 10 && startswith (p, "loop_break"))
	*command = new struct command_line (break_control);
      else if (p_end - p == 13 && startswith (p, "loop_continue"))
	*command = new struct command_line (continue_control);
      else
	not_handled = 1;
    }

  if (!parse_commands || not_handled)
    {
      /* A normal command.  */
      *command = new struct command_line (simple_control,
					  savestring (p, p_end - p));
    }

  if (validator)
    {
      try
	{
	  validator ((*command)->line);
	}
      catch (const gdb_exception &ex)
	{
	  free_command_lines (command);
	  throw;
	}
    }

  /* Nothing special.  */
  return ok_command;
}

/* Recursively read in the control structures and create a
   command_line structure from them.  Use read_next_line_func to
   obtain lines of the command.  */

static enum command_control_type
recurse_read_control_structure (gdb::function_view<const char * ()> read_next_line_func,
				struct command_line *current_cmd,
				gdb::function_view<void (const char *)> validator)
{
  enum misc_command_type val;
  enum command_control_type ret;
  struct command_line *child_tail, *next;
  counted_command_line *current_body = &current_cmd->body_list_0;

  child_tail = NULL;

  /* Sanity checks.  */
  if (current_cmd->control_type == simple_control)
    error (_("Recursed on a simple control type."));

  /* Read lines from the input stream and build control structures.  */
  while (1)
    {
      dont_repeat ();

      next = NULL;
      val = process_next_line (read_next_line_func (), &next, 
			       current_cmd->control_type != python_control
			       && current_cmd->control_type != guile_control
			       && current_cmd->control_type != compile_control,
			       validator);

      /* Just skip blanks and comments.  */
      if (val == nop_command)
	continue;

      if (val == end_command)
	{
	  if (multi_line_command_p (current_cmd->control_type))
	    {
	      /* Success reading an entire canned sequence of commands.  */
	      ret = simple_control;
	      break;
	    }
	  else
	    {
	      ret = invalid_control;
	      break;
	    }
	}

      /* Not the end of a control structure.  */
      if (val == else_command)
	{
	  if (current_cmd->control_type == if_control
	      && current_body == &current_cmd->body_list_0)
	    {
	      current_body = &current_cmd->body_list_1;
	      child_tail = NULL;
	      continue;
	    }
	  else
	    {
	      ret = invalid_control;
	      break;
	    }
	}

      if (child_tail)
	{
	  child_tail->next = next;
	}
      else
	*current_body = counted_command_line (next, command_lines_deleter ());

      child_tail = next;

      /* If the latest line is another control structure, then recurse
	 on it.  */
      if (multi_line_command_p (next->control_type))
	{
	  control_level++;
	  ret = recurse_read_control_structure (read_next_line_func, next,
						validator);
	  control_level--;

	  if (ret != simple_control)
	    break;
	}
    }

  dont_repeat ();

  return ret;
}

/* Read lines from the input stream and accumulate them in a chain of
   struct command_line's, which is then returned.  For input from a
   terminal, the special command "end" is used to mark the end of the
   input, and is not included in the returned chain of commands.

   If PARSE_COMMANDS is true, strip leading whitespace (trailing whitespace
   is always stripped) in the line and attempt to recognize GDB control
   commands.  Otherwise, only "end" is recognized.  */

#define END_MESSAGE "End with a line saying just \"end\"."

counted_command_line
read_command_lines (const char *prompt_arg, int from_tty, int parse_commands,
		    gdb::function_view<void (const char *)> validator)
{
  if (from_tty && input_interactive_p (current_ui))
    {
      if (deprecated_readline_begin_hook)
	{
	  /* Note - intentional to merge messages with no newline.  */
	  (*deprecated_readline_begin_hook) ("%s  %s\n", prompt_arg,
					     END_MESSAGE);
	}
      else
	printf_unfiltered ("%s\n%s\n", prompt_arg, END_MESSAGE);
    }


  /* Reading commands assumes the CLI behavior, so temporarily
     override the current interpreter with CLI.  */
  counted_command_line head (nullptr, command_lines_deleter ());
  if (current_interp_named_p (INTERP_CONSOLE))
    head = read_command_lines_1 (read_next_line, parse_commands,
				 validator);
  else
    {
      scoped_restore_interp interp_restorer (INTERP_CONSOLE);

      head = read_command_lines_1 (read_next_line, parse_commands,
				   validator);
    }

  if (from_tty && input_interactive_p (current_ui)
      && deprecated_readline_end_hook)
    {
      (*deprecated_readline_end_hook) ();
    }
  return (head);
}

/* Act the same way as read_command_lines, except that each new line is
   obtained using READ_NEXT_LINE_FUNC.  */

counted_command_line
read_command_lines_1 (gdb::function_view<const char * ()> read_next_line_func,
		      int parse_commands,
		      gdb::function_view<void (const char *)> validator)
{
  struct command_line *tail, *next;
  counted_command_line head (nullptr, command_lines_deleter ());
  enum command_control_type ret;
  enum misc_command_type val;

  control_level = 0;
  tail = NULL;

  while (1)
    {
      dont_repeat ();
      val = process_next_line (read_next_line_func (), &next, parse_commands,
			       validator);

      /* Ignore blank lines or comments.  */
      if (val == nop_command)
	continue;

      if (val == end_command)
	{
	  ret = simple_control;
	  break;
	}

      if (val != ok_command)
	{
	  ret = invalid_control;
	  break;
	}

      if (multi_line_command_p (next->control_type))
	{
	  control_level++;
	  ret = recurse_read_control_structure (read_next_line_func, next,
						validator);
	  control_level--;

	  if (ret == invalid_control)
	    break;
	}

      if (tail)
	{
	  tail->next = next;
	}
      else
	{
	  head = counted_command_line (next, command_lines_deleter ());
	}
      tail = next;
    }

  dont_repeat ();

  if (ret == invalid_control)
    return NULL;

  return head;
}

/* Free a chain of struct command_line's.  */

void
free_command_lines (struct command_line **lptr)
{
  struct command_line *l = *lptr;
  struct command_line *next;

  while (l)
    {
      next = l->next;
      delete l;
      l = next;
    }
  *lptr = NULL;
}

/* Validate that *COMNAME is a valid name for a command.  Return the
   containing command list, in case it starts with a prefix command.
   The prefix must already exist.  *COMNAME is advanced to point after
   any prefix, and a NUL character overwrites the space after the
   prefix.  */

static struct cmd_list_element **
validate_comname (const char **comname)
{
  struct cmd_list_element **list = &cmdlist;
  const char *p, *last_word;

  if (*comname == 0)
    error_no_arg (_("name of command to define"));

  /* Find the last word of the argument.  */
  p = *comname + strlen (*comname);
  while (p > *comname && isspace (p[-1]))
    p--;
  while (p > *comname && !isspace (p[-1]))
    p--;
  last_word = p;

  /* Find the corresponding command list.  */
  if (last_word != *comname)
    {
      struct cmd_list_element *c;

      /* Separate the prefix and the command.  */
      std::string prefix (*comname, last_word - 1);
      const char *tem = prefix.c_str ();

      c = lookup_cmd (&tem, cmdlist, "", NULL, 0, 1);
      if (c->prefixlist == NULL)
	error (_("\"%s\" is not a prefix command."), prefix.c_str ());

      list = c->prefixlist;
      *comname = last_word;
    }

  p = *comname;
  while (*p)
    {
      if (!valid_cmd_char_p (*p))
	error (_("Junk in argument list: \"%s\""), p);
      p++;
    }

  return list;
}

/* This is just a placeholder in the command data structures.  */
static void
user_defined_command (const char *ignore, int from_tty)
{
}

/* Define a user-defined command.  If COMMANDS is NULL, then this is a
   top-level call and the commands will be read using
   read_command_lines.  Otherwise, it is a "define" command in an
   existing command and the commands are provided.  In the
   non-top-level case, various prompts and warnings are disabled.  */

static void
do_define_command (const char *comname, int from_tty,
		   const counted_command_line *commands)
{
  enum cmd_hook_type
    {
      CMD_NO_HOOK = 0,
      CMD_PRE_HOOK,
      CMD_POST_HOOK
    };
  struct cmd_list_element *c, *newc, *hookc = 0, **list;
  const char *tem, *comfull;
  int  hook_type      = CMD_NO_HOOK;
  int  hook_name_size = 0;
   
#define	HOOK_STRING	"hook-"
#define	HOOK_LEN 5
#define HOOK_POST_STRING "hookpost-"
#define HOOK_POST_LEN    9

  comfull = comname;
  list = validate_comname (&comname);

  /* Look it up, and verify that we got an exact match.  */
  tem = comname;
  c = lookup_cmd (&tem, *list, "", NULL, -1, 1);
  if (c && strcmp (comname, c->name) != 0)
    c = 0;

  if (c && commands == nullptr)
    {
      int q;

      if (c->theclass == class_user || c->theclass == class_alias)
	{
	  /* if C is a prefix command that was previously defined,
	     tell the user its subcommands will be kept, and ask
	     if ok to redefine the command.  */
	  if (c->prefixlist != nullptr)
	    q = (c->user_commands.get () == nullptr
		 || query (_("Keeping subcommands of prefix command \"%s\".\n"
			     "Redefine command \"%s\"? "), c->name, c->name));
	  else
	    q = query (_("Redefine command \"%s\"? "), c->name);
	}
      else
	q = query (_("Really redefine built-in command \"%s\"? "), c->name);
      if (!q)
	error (_("Command \"%s\" not redefined."), c->name);
    }

  /* If this new command is a hook, then mark the command which it
     is hooking.  Note that we allow hooking `help' commands, so that
     we can hook the `stop' pseudo-command.  */

  if (!strncmp (comname, HOOK_STRING, HOOK_LEN))
    {
       hook_type      = CMD_PRE_HOOK;
       hook_name_size = HOOK_LEN;
    }
  else if (!strncmp (comname, HOOK_POST_STRING, HOOK_POST_LEN))
    {
      hook_type      = CMD_POST_HOOK;
      hook_name_size = HOOK_POST_LEN;
    }

  if (hook_type != CMD_NO_HOOK)
    {
      /* Look up cmd it hooks, and verify that we got an exact match.  */
      tem = comname + hook_name_size;
      hookc = lookup_cmd (&tem, *list, "", NULL, -1, 0);
      if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0)
	hookc = 0;
      if (!hookc && commands == nullptr)
	{
	  warning (_("Your new `%s' command does not "
		     "hook any existing command."),
		   comfull);
	  if (!query (_("Proceed? ")))
	    error (_("Not confirmed."));
	}
    }

  comname = xstrdup (comname);

  counted_command_line cmds;
  if (commands == nullptr)
    {
      std::string prompt
	= string_printf ("Type commands for definition of \"%s\".", comfull);
      cmds = read_command_lines (prompt.c_str (), from_tty, 1, 0);
    }
  else
    cmds = *commands;

  {
    struct cmd_list_element **c_prefixlist
      = c == nullptr ? nullptr : c->prefixlist;
    const char *c_prefixname = c == nullptr ? nullptr : c->prefixname;

    newc = add_cmd (comname, class_user, user_defined_command,
		    (c != nullptr && c->theclass == class_user)
		    ? c->doc : xstrdup ("User-defined."), list);
    newc->user_commands = std::move (cmds);

    /* If we define or re-define a command that was previously defined
       as a prefix, keep the prefix information.  */
    if (c_prefixlist != nullptr)
      {
	newc->prefixlist = c_prefixlist;
	newc->prefixname = c_prefixname;
	/* allow_unknown: see explanation in equivalent logic in
	   define_prefix_command ().  */
	newc->allow_unknown = newc->user_commands.get () != nullptr;
    }
  }

  /* If this new command is a hook, then mark both commands as being
     tied.  */
  if (hookc)
    {
      switch (hook_type)
	{
	case CMD_PRE_HOOK:
	  hookc->hook_pre  = newc;  /* Target gets hooked.  */
	  newc->hookee_pre = hookc; /* We are marked as hooking target cmd.  */
	  break;
	case CMD_POST_HOOK:
	  hookc->hook_post  = newc;  /* Target gets hooked.  */
	  newc->hookee_post = hookc; /* We are marked as hooking
					target cmd.  */
	  break;
	default:
	  /* Should never come here as hookc would be 0.  */
	  internal_error (__FILE__, __LINE__, _("bad switch"));
	}
    }
}

static void
define_command (const char *comname, int from_tty)
{
  do_define_command (comname, from_tty, nullptr);
}

static void
document_command (const char *comname, int from_tty)
{
  struct cmd_list_element *c, **list;
  const char *tem;
  const char *comfull;

  comfull = comname;
  list = validate_comname (&comname);

  tem = comname;
  c = lookup_cmd (&tem, *list, "", NULL, 0, 1);

  if (c->theclass != class_user)
    error (_("Command \"%s\" is built-in."), comfull);

  std::string prompt = string_printf ("Type documentation for \"%s\".",
				      comfull);
  counted_command_line doclines = read_command_lines (prompt.c_str (),
						      from_tty, 0, 0);

  xfree ((char *) c->doc);

  {
    struct command_line *cl1;
    int len = 0;
    char *doc;

    for (cl1 = doclines.get (); cl1; cl1 = cl1->next)
      len += strlen (cl1->line) + 1;

    doc = (char *) xmalloc (len + 1);
    *doc = 0;

    for (cl1 = doclines.get (); cl1; cl1 = cl1->next)
      {
	strcat (doc, cl1->line);
	if (cl1->next)
	  strcat (doc, "\n");
      }

    c->doc = doc;
  }
}

/* Implementation of the "define-prefix" command.  */

static void
define_prefix_command (const char *comname, int from_tty)
{
  struct cmd_list_element *c, **list;
  const char *tem;
  const char *comfull;

  comfull = comname;
  list = validate_comname (&comname);

  /* Look it up, and verify that we got an exact match.  */
  tem = comname;
  c = lookup_cmd (&tem, *list, "", NULL, -1, 1);
  if (c != nullptr && strcmp (comname, c->name) != 0)
    c = nullptr;

  if (c != nullptr && c->theclass != class_user)
    error (_("Command \"%s\" is built-in."), comfull);

  if (c != nullptr && c->prefixlist != nullptr)
    {
      /* c is already a user defined prefix command.  */
      return;
    }

  /* If the command does not exist at all, create it.  */
  if (c == nullptr)
    {
      comname = xstrdup (comname);
      c = add_cmd (comname, class_user, user_defined_command,
		   xstrdup ("User-defined."), list);
    }

  /* Allocate the c->prefixlist, which marks the command as a prefix
     command.  */
  c->prefixlist = new struct cmd_list_element*;
  *(c->prefixlist) = nullptr;
  c->prefixname = xstrprintf ("%s ", comfull);
  /* If the prefix command C is not a command, then it must be followed
     by known subcommands.  Otherwise, if C is also a normal command,
     it can be followed by C args that must not cause a 'subcommand'
     not recognised error, and thus we must allow unknown.  */
  c->allow_unknown = c->user_commands.get () != nullptr;
}


/* Used to implement source_command.  */

void
script_from_file (FILE *stream, const char *file)
{
  if (stream == NULL)
    internal_error (__FILE__, __LINE__, _("called with NULL file pointer!"));

  scoped_restore restore_line_number
    = make_scoped_restore (&source_line_number, 0);
  scoped_restore restore_file
    = make_scoped_restore<std::string, const std::string &> (&source_file_name,
							     file);

  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);

  try
    {
      read_command_file (stream);
    }
  catch (const gdb_exception_error &e)
    {
      /* Re-throw the error, but with the file name information
	 prepended.  */
      throw_error (e.error,
		   _("%s:%d: Error in sourced command file:\n%s"),
		   source_file_name.c_str (), source_line_number,
		   e.what ());
    }
}

/* Print the definition of user command C to STREAM.  Or, if C is a
   prefix command, show the definitions of all user commands under C
   (recursively).  PREFIX and NAME combined are the name of the
   current command.  */
void
show_user_1 (struct cmd_list_element *c, const char *prefix, const char *name,
	     struct ui_file *stream)
{
  if (cli_user_command_p (c))
    {
      struct command_line *cmdlines = c->user_commands.get ();

      fprintf_filtered (stream, "User %scommand \"",
			c->prefixlist == NULL ? "" : "prefix ");
      fprintf_styled (stream, title_style.style (), "%s%s",
		      prefix, name);
      fprintf_filtered (stream, "\":\n");
      if (cmdlines)
	{
	  print_command_lines (current_uiout, cmdlines, 1);
	  fputs_filtered ("\n", stream);
	}
    }

  if (c->prefixlist != NULL)
    {
      const char *prefixname = c->prefixname;

      for (c = *c->prefixlist; c != NULL; c = c->next)
	if (c->theclass == class_user || c->prefixlist != NULL)
	  show_user_1 (c, prefixname, c->name, gdb_stdout);
    }

}

void _initialize_cli_script ();
void
_initialize_cli_script ()
{
  struct cmd_list_element *c;

  /* "document", "define" and "define-prefix" use command_completer,
     as this helps the user to either type the command name and/or
     its prefixes.  */
  c = add_com ("document", class_support, document_command, _("\
Document a user-defined command.\n\
Give command name as argument.  Give documentation on following lines.\n\
End with a line of just \"end\"."));
  set_cmd_completer (c, command_completer);
  define_cmd_element = add_com ("define", class_support, define_command, _("\
Define a new command name.  Command name is argument.\n\
Definition appears on following lines, one command per line.\n\
End with a line of just \"end\".\n\
Use the \"document\" command to give documentation for the new command.\n\
Commands defined in this way may accept an unlimited number of arguments\n\
accessed via $arg0 .. $argN.  $argc tells how many arguments have\n\
been passed."));
  set_cmd_completer (define_cmd_element, command_completer);
  c = add_com ("define-prefix", class_support, define_prefix_command,
	   _("\
Define or mark a command as a user-defined prefix command.\n\
User defined prefix commands can be used as prefix commands for\n\
other user defined commands.\n\
If the command already exists, it is changed to a prefix command."));
  set_cmd_completer (c, command_completer);

  while_cmd_element = add_com ("while", class_support, while_command, _("\
Execute nested commands WHILE the conditional expression is non zero.\n\
The conditional expression must follow the word `while' and must in turn be\n\
followed by a new line.  The nested commands must be entered one per line,\n\
and should be terminated by the word `end'."));

  if_cmd_element = add_com ("if", class_support, if_command, _("\
Execute nested commands once IF the conditional expression is non zero.\n\
The conditional expression must follow the word `if' and must in turn be\n\
followed by a new line.  The nested commands must be entered one per line,\n\
and should be terminated by the word 'else' or `end'.  If an else clause\n\
is used, the same rules apply to its nested commands as to the first ones."));
}
