/* MI Command Set - breakpoint and watchpoint commands.
   Copyright (C) 2000-2022 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions (a Red Hat company).

   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 "arch-utils.h"
#include "mi-cmds.h"
#include "ui-out.h"
#include "mi-out.h"
#include "breakpoint.h"
#include "mi-getopt.h"
#include "observable.h"
#include "mi-main.h"
#include "mi-cmd-break.h"
#include "language.h"
#include "location.h"
#include "linespec.h"
#include "gdbsupport/gdb_obstack.h"
#include <ctype.h>
#include "tracepoint.h"

enum
  {
    FROM_TTY = 0
  };

/* True if MI breakpoint observers have been registered.  */

static int mi_breakpoint_observers_installed;

/* Control whether breakpoint_notify may act.  */

static int mi_can_breakpoint_notify;

/* Output a single breakpoint, when allowed.  */

static void
breakpoint_notify (struct breakpoint *b)
{
  if (mi_can_breakpoint_notify)
    {
      try
	{
	  print_breakpoint (b);
	}
      catch (const gdb_exception &ex)
	{
	  exception_print (gdb_stderr, ex);
	}
    }
}

enum bp_type
  {
    REG_BP,
    HW_BP,
    REGEXP_BP
  };

/* Arrange for all new breakpoints and catchpoints to be reported to
   CURRENT_UIOUT until the destructor of the returned scoped_restore
   is run.

   Note that MI output will be probably invalid if more than one
   breakpoint is created inside one MI command.  */

scoped_restore_tmpl<int>
setup_breakpoint_reporting (void)
{
  if (! mi_breakpoint_observers_installed)
    {
      gdb::observers::breakpoint_created.attach (breakpoint_notify,
						 "mi-cmd-break");
      mi_breakpoint_observers_installed = 1;
    }

  return make_scoped_restore (&mi_can_breakpoint_notify, 1);
}


/* Convert arguments in ARGV to the string in "format",argv,argv...
   and return it.  */

static std::string
mi_argv_to_format (char **argv, int argc)
{
  int i;
  std::string result;

  /* Convert ARGV[OIND + 1] to format string and save to FORMAT.  */
  result += '\"';
  for (i = 0; i < strlen (argv[0]); i++)
    {
      switch (argv[0][i])
	{
	case '\\':
	  result += "\\\\";
	  break;
	case '\a':
	  result += "\\a";
	  break;
	case '\b':
	  result += "\\b";
	  break;
	case '\f':
	  result += "\\f";
	  break;
	case '\n':
	  result += "\\n";
	  break;
	case '\r':
	  result += "\\r";
	  break;
	case '\t':
	  result += "\\t";
	  break;
	case '\v':
	  result += "\\v";
	  break;
	case '"':
	  result += "\\\"";
	  break;
	default:
	  if (isprint (argv[0][i]))
	    result += argv[0][i];
	  else
	    {
	      char tmp[5];

	      xsnprintf (tmp, sizeof (tmp), "\\%o",
			 (unsigned char) argv[0][i]);
	      result += tmp;
	    }
	  break;
	}
    }
  result += '\"';

  /* Apply other argv to FORMAT.  */
  for (i = 1; i < argc; i++)
    {
      result += ',';
      result += argv[i];
    }

  return result;
}

/* Insert breakpoint.
   If dprintf is true, it will insert dprintf.
   If not, it will insert other type breakpoint.  */

static void
mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
{
  const char *address = NULL;
  int hardware = 0;
  int temp_p = 0;
  int thread = -1;
  int ignore_count = 0;
  char *condition = NULL;
  int pending = 0;
  int enabled = 1;
  int tracepoint = 0;
  symbol_name_match_type match_type = symbol_name_match_type::WILD;
  enum bptype type_wanted;
  location_spec_up locspec;
  const struct breakpoint_ops *ops;
  int is_explicit = 0;
  std::unique_ptr<explicit_location_spec> explicit_loc
    (new explicit_location_spec ());
  std::string extra_string;
  bool force_condition = false;

  enum opt
    {
      HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
      IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
      TRACEPOINT_OPT,
      FORCE_CONDITION_OPT,
      QUALIFIED_OPT,
      EXPLICIT_SOURCE_OPT, EXPLICIT_FUNC_OPT,
      EXPLICIT_LABEL_OPT, EXPLICIT_LINE_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"h", HARDWARE_OPT, 0},
    {"t", TEMP_OPT, 0},
    {"c", CONDITION_OPT, 1},
    {"i", IGNORE_COUNT_OPT, 1},
    {"p", THREAD_OPT, 1},
    {"f", PENDING_OPT, 0},
    {"d", DISABLE_OPT, 0},
    {"a", TRACEPOINT_OPT, 0},
    {"-force-condition", FORCE_CONDITION_OPT, 0},
    {"-qualified", QUALIFIED_OPT, 0},
    {"-source" , EXPLICIT_SOURCE_OPT, 1},
    {"-function", EXPLICIT_FUNC_OPT, 1},
    {"-label", EXPLICIT_LABEL_OPT, 1},
    {"-line", EXPLICIT_LINE_OPT, 1},
    { 0, 0, 0 }
  };

  /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
     to denote the end of the option list. */
  int oind = 0;
  char *oarg;

  while (1)
    {
      int opt = mi_getopt ("-break-insert", argc, argv,
			   opts, &oind, &oarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case TEMP_OPT:
	  temp_p = 1;
	  break;
	case HARDWARE_OPT:
	  hardware = 1;
	  break;
	case CONDITION_OPT:
	  condition = oarg;
	  break;
	case IGNORE_COUNT_OPT:
	  ignore_count = atol (oarg);
	  break;
	case THREAD_OPT:
	  thread = atol (oarg);
	  break;
	case PENDING_OPT:
	  pending = 1;
	  break;
	case DISABLE_OPT:
	  enabled = 0;
	  break;
	case TRACEPOINT_OPT:
	  tracepoint = 1;
	  break;
	case QUALIFIED_OPT:
	  match_type = symbol_name_match_type::FULL;
	  break;
	case EXPLICIT_SOURCE_OPT:
	  is_explicit = 1;
	  explicit_loc->source_filename = xstrdup (oarg);
	  break;
	case EXPLICIT_FUNC_OPT:
	  is_explicit = 1;
	  explicit_loc->function_name = xstrdup (oarg);
	  break;
	case EXPLICIT_LABEL_OPT:
	  is_explicit = 1;
	  explicit_loc->label_name = xstrdup (oarg);
	  break;
	case EXPLICIT_LINE_OPT:
	  is_explicit = 1;
	  explicit_loc->line_offset = linespec_parse_line_offset (oarg);
	  break;
	case FORCE_CONDITION_OPT:
	  force_condition = true;
	  break;
	}
    }

  if (oind >= argc && !is_explicit)
    error (_("-%s-insert: Missing <location>"),
	   dprintf ? "dprintf" : "break");
  if (dprintf)
    {
      int format_num = is_explicit ? oind : oind + 1;

      if (hardware || tracepoint)
	error (_("-dprintf-insert: does not support -h or -a"));
      if (format_num >= argc)
	error (_("-dprintf-insert: Missing <format>"));

      extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
      address = argv[oind];
    }
  else
    {
      if (is_explicit)
	{
	  if (oind < argc)
	    error (_("-break-insert: Garbage following explicit location"));
	}
      else
	{
	  if (oind < argc - 1)
	    error (_("-break-insert: Garbage following <location>"));
	  address = argv[oind];
	}
    }

  /* Now we have what we need, let's insert the breakpoint!  */
  scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();

  if (tracepoint)
    {
      /* Note that to request a fast tracepoint, the client uses the
	 "hardware" flag, although there's nothing of hardware related to
	 fast tracepoints -- one can implement slow tracepoints with
	 hardware breakpoints, but fast tracepoints are always software.
	 "fast" is a misnomer, actually, "jump" would be more appropriate.
	 A simulator or an emulator could conceivably implement fast
	 regular non-jump based tracepoints.  */
      type_wanted = hardware ? bp_fast_tracepoint : bp_tracepoint;
      ops = breakpoint_ops_for_location_spec (nullptr, true);
    }
  else if (dprintf)
    {
      type_wanted = bp_dprintf;
      ops = &code_breakpoint_ops;
    }
  else
    {
      type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
      ops = &code_breakpoint_ops;
    }

  if (is_explicit)
    {
      /* Error check -- we must have one of the other
	 parameters specified.  */
      if (explicit_loc->source_filename != NULL
	  && explicit_loc->function_name == NULL
	  && explicit_loc->label_name == NULL
	  && explicit_loc->line_offset.sign == LINE_OFFSET_UNKNOWN)
	error (_("-%s-insert: --source option requires --function, --label,"
		 " or --line"), dprintf ? "dprintf" : "break");

      explicit_loc->func_name_match_type = match_type;

      locspec = std::move (explicit_loc);
    }
  else
    {
      locspec = string_to_location_spec_basic (&address, current_language,
					       match_type);
      if (*address)
	error (_("Garbage '%s' at end of location"), address);
    }

  create_breakpoint (get_current_arch (), locspec.get (), condition, thread,
		     extra_string.c_str (),
		     force_condition,
		     0 /* condition and thread are valid.  */,
		     temp_p, type_wanted,
		     ignore_count,
		     pending ? AUTO_BOOLEAN_TRUE : AUTO_BOOLEAN_FALSE,
		     ops, 0, enabled, 0, 0);
}

/* Implements the -break-insert command.
   See the MI manual for the list of possible options.  */

void
mi_cmd_break_insert (const char *command, char **argv, int argc)
{
  mi_cmd_break_insert_1 (0, command, argv, argc);
}

/* Implements the -dprintf-insert command.
   See the MI manual for the list of possible options.  */

void
mi_cmd_dprintf_insert (const char *command, char **argv, int argc)
{
  mi_cmd_break_insert_1 (1, command, argv, argc);
}

/* Implements the -break-condition command.
   See the MI manual for the list of options.  */

void
mi_cmd_break_condition (const char *command, char **argv, int argc)
{
  enum option
    {
      FORCE_CONDITION_OPT,
    };

  static const struct mi_opt opts[] =
  {
    {"-force", FORCE_CONDITION_OPT, 0},
    { 0, 0, 0 }
  };

  /* Parse arguments.  */
  int oind = 0;
  char *oarg;
  bool force_condition = false;

  while (true)
    {
      int opt = mi_getopt ("-break-condition", argc, argv,
			   opts, &oind, &oarg);
      if (opt < 0)
	break;

      switch (opt)
	{
	case FORCE_CONDITION_OPT:
	  force_condition = true;
	  break;
	}
    }

  /* There must be at least one more arg: a bpnum.  */
  if (oind >= argc)
    error (_("-break-condition: Missing the <number> argument"));

  int bpnum = atoi (argv[oind]);

  /* The rest form the condition expr.  */
  std::string expr = "";
  for (int i = oind + 1; i < argc; ++i)
    {
      expr += argv[i];
      if (i + 1 < argc)
	expr += " ";
    }

  set_breakpoint_condition (bpnum, expr.c_str (), 0 /* from_tty */,
			    force_condition);
}

enum wp_type
{
  REG_WP,
  READ_WP,
  ACCESS_WP
};

void
mi_cmd_break_passcount (const char *command, char **argv, int argc)
{
  int n;
  int p;
  struct tracepoint *t;

  if (argc != 2)
    error (_("Usage: tracepoint-number passcount"));

  n = atoi (argv[0]);
  p = atoi (argv[1]);
  t = get_tracepoint (n);

  if (t)
    {
      t->pass_count = p;
      gdb::observers::breakpoint_modified.notify (t);
    }
  else
    {
      error (_("Could not find tracepoint %d"), n);
    }
}

/* Insert a watchpoint. The type of watchpoint is specified by the
   first argument: 
   -break-watch <expr> --> insert a regular wp.  
   -break-watch -r <expr> --> insert a read watchpoint.
   -break-watch -a <expr> --> insert an access wp.  */

void
mi_cmd_break_watch (const char *command, char **argv, int argc)
{
  char *expr = NULL;
  enum wp_type type = REG_WP;
  enum opt
    {
      READ_OPT, ACCESS_OPT
    };
  static const struct mi_opt opts[] =
  {
    {"r", READ_OPT, 0},
    {"a", ACCESS_OPT, 0},
    { 0, 0, 0 }
  };

  /* Parse arguments. */
  int oind = 0;
  char *oarg;

  while (1)
    {
      int opt = mi_getopt ("-break-watch", argc, argv,
			   opts, &oind, &oarg);

      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case READ_OPT:
	  type = READ_WP;
	  break;
	case ACCESS_OPT:
	  type = ACCESS_WP;
	  break;
	}
    }
  if (oind >= argc)
    error (_("-break-watch: Missing <expression>"));
  if (oind < argc - 1)
    error (_("-break-watch: Garbage following <expression>"));
  expr = argv[oind];

  /* Now we have what we need, let's insert the watchpoint!  */
  switch (type)
    {
    case REG_WP:
      watch_command_wrapper (expr, FROM_TTY, false);
      break;
    case READ_WP:
      rwatch_command_wrapper (expr, FROM_TTY, false);
      break;
    case ACCESS_WP:
      awatch_command_wrapper (expr, FROM_TTY, false);
      break;
    default:
      error (_("-break-watch: Unknown watchpoint type."));
    }
}

void
mi_cmd_break_commands (const char *command, char **argv, int argc)
{
  counted_command_line break_command;
  char *endptr;
  int bnum;
  struct breakpoint *b;

  if (argc < 1)
    error (_("USAGE: %s <BKPT> [<COMMAND> [<COMMAND>...]]"), command);

  bnum = strtol (argv[0], &endptr, 0);
  if (endptr == argv[0])
    error (_("breakpoint number argument \"%s\" is not a number."),
	   argv[0]);
  else if (*endptr != '\0')
    error (_("junk at the end of breakpoint number argument \"%s\"."),
	   argv[0]);

  b = get_breakpoint (bnum);
  if (b == NULL)
    error (_("breakpoint %d not found."), bnum);

  int count = 1;
  auto reader
    = [&] ()
      {
	const char *result = nullptr;
	if (count < argc)
	  result = argv[count++];
	return result;
      };

  if (is_tracepoint (b))
    break_command = read_command_lines_1 (reader, 1,
					  [=] (const char *line)
					    {
					      validate_actionline (line, b);
					    });
  else
    break_command = read_command_lines_1 (reader, 1, 0);

  breakpoint_set_commands (b, std::move (break_command));
}

