/* MI Command Set - breakpoint and watchpoint commands.
   Copyright (C) 2000-2017 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 "observer.h"
#include "mi-main.h"
#include "mi-cmd-break.h"
#include "language.h"
#include "location.h"
#include "linespec.h"
#include "gdb_obstack.h"
#include <ctype.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 (ex, RETURN_MASK_ALL)
	{
	  exception_print (gdb_stderr, ex);
	}
      END_CATCH
    }
}

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)
    {
      observer_attach_breakpoint_created (breakpoint_notify);
      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;
  enum bptype type_wanted;
  event_location_up location;
  struct breakpoint_ops *ops;
  int is_explicit = 0;
  struct explicit_location explicit_loc;
  std::string extra_string;

  enum opt
    {
      HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
      IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT, DISABLE_OPT,
      TRACEPOINT_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},
    {"-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;

  initialize_explicit_location (&explicit_loc);

  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 EXPLICIT_SOURCE_OPT:
	  is_explicit = 1;
	  explicit_loc.source_filename = oarg;
	  break;
	case EXPLICIT_FUNC_OPT:
	  is_explicit = 1;
	  explicit_loc.function_name = oarg;
	  break;
	case EXPLICIT_LABEL_OPT:
	  is_explicit = 1;
	  explicit_loc.label_name = oarg;
	  break;
	case EXPLICIT_LINE_OPT:
	  is_explicit = 1;
	  explicit_loc.line_offset = linespec_parse_line_offset (oarg);
	  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 = &tracepoint_breakpoint_ops;
    }
  else if (dprintf)
    {
      type_wanted = bp_dprintf;
      ops = &dprintf_breakpoint_ops;
    }
  else
    {
      type_wanted = hardware ? bp_hardware_breakpoint : bp_breakpoint;
      ops = &bkpt_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");

      location = new_explicit_location (&explicit_loc);
    }
  else
    {
      location = string_to_event_location_basic (&address, current_language);
      if (*address)
	error (_("Garbage '%s' at end of location"), address);
    }

  create_breakpoint (get_current_arch (), location.get (), condition, thread,
		     extra_string.c_str (),
		     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);
}

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;
      observer_notify_breakpoint_modified (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, 0);
      break;
    case READ_WP:
      rwatch_command_wrapper (expr, FROM_TTY, 0);
      break;
    case ACCESS_WP:
      awatch_command_wrapper (expr, FROM_TTY, 0);
      break;
    default:
      error (_("-break-watch: Unknown watchpoint type."));
    }
}

/* The mi_read_next_line consults these variable to return successive
   command lines.  While it would be clearer to use a closure pointer,
   it is not expected that any future code will use read_command_lines_1,
   therefore no point of overengineering.  */

static char **mi_command_line_array;
static int mi_command_line_array_cnt;
static int mi_command_line_array_ptr;

static char *
mi_read_next_line (void)
{
  if (mi_command_line_array_ptr == mi_command_line_array_cnt)
    return NULL;
  else
    return mi_command_line_array[mi_command_line_array_ptr++];
}

void
mi_cmd_break_commands (const char *command, char **argv, int argc)
{
  command_line_up 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);

  mi_command_line_array = argv;
  mi_command_line_array_ptr = 1;
  mi_command_line_array_cnt = argc;

  if (is_tracepoint (b))
    break_command = read_command_lines_1 (mi_read_next_line, 1,
					  check_tracepoint_command, b);
  else
    break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);

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

