/* MI Command Set - catch commands.
   Copyright (C) 2012-2021 Free Software Foundation, Inc.

   Contributed by Intel Corporation.

   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 "breakpoint.h"
#include "ada-lang.h"
#include "mi-cmds.h"
#include "mi-getopt.h"
#include "mi-cmd-break.h"

/* Handler for the -catch-assert command.  */

void
mi_cmd_catch_assert (const char *cmd, char *argv[], int argc)
{
  struct gdbarch *gdbarch = get_current_arch();
  std::string condition;
  int enabled = 1;
  int temp = 0;

  int oind = 0;
  char *oarg;

  enum opt
    {
      OPT_CONDITION, OPT_DISABLED, OPT_TEMP,
    };
  static const struct mi_opt opts[] =
    {
      { "c", OPT_CONDITION, 1},
      { "d", OPT_DISABLED, 0 },
      { "t", OPT_TEMP, 0 },
      { 0, 0, 0 }
    };

  for (;;)
    {
      int opt = mi_getopt ("-catch-assert", argc, argv, opts,
			   &oind, &oarg);

      if (opt < 0)
	break;

      switch ((enum opt) opt)
	{
	case OPT_CONDITION:
	  condition.assign (oarg);
	  break;
	case OPT_DISABLED:
	  enabled = 0;
	  break;
	case OPT_TEMP:
	  temp = 1;
	  break;
	}
    }

  /* This command does not accept any argument.  Make sure the user
     did not provide any.  */
  if (oind != argc)
    error (_("Invalid argument: %s"), argv[oind]);

  scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  create_ada_exception_catchpoint (gdbarch, ada_catch_assert, std::string (),
				   condition, temp, enabled, 0);
}

/* Handler for the -catch-exception command.  */

void
mi_cmd_catch_exception (const char *cmd, char *argv[], int argc)
{
  struct gdbarch *gdbarch = get_current_arch();
  std::string condition;
  int enabled = 1;
  std::string exception_name;
  int temp = 0;
  enum ada_exception_catchpoint_kind ex_kind = ada_catch_exception;

  int oind = 0;
  char *oarg;

  enum opt
    {
      OPT_CONDITION, OPT_DISABLED, OPT_EXCEPTION_NAME, OPT_TEMP,
      OPT_UNHANDLED,
    };
  static const struct mi_opt opts[] =
    {
      { "c", OPT_CONDITION, 1},
      { "d", OPT_DISABLED, 0 },
      { "e", OPT_EXCEPTION_NAME, 1 },
      { "t", OPT_TEMP, 0 },
      { "u", OPT_UNHANDLED, 0},
      { 0, 0, 0 }
    };

  for (;;)
    {
      int opt = mi_getopt ("-catch-exception", argc, argv, opts,
			   &oind, &oarg);

      if (opt < 0)
	break;

      switch ((enum opt) opt)
	{
	case OPT_CONDITION:
	  condition.assign (oarg);
	  break;
	case OPT_DISABLED:
	  enabled = 0;
	  break;
	case OPT_EXCEPTION_NAME:
	  exception_name = oarg;
	  break;
	case OPT_TEMP:
	  temp = 1;
	  break;
	case OPT_UNHANDLED:
	  ex_kind = ada_catch_exception_unhandled;
	  break;
	}
    }

  /* This command does not accept any argument.  Make sure the user
     did not provide any.  */
  if (oind != argc)
    error (_("Invalid argument: %s"), argv[oind]);

  /* Specifying an exception name does not make sense when requesting
     an unhandled exception breakpoint.  */
  if (ex_kind == ada_catch_exception_unhandled && !exception_name.empty ())
    error (_("\"-e\" and \"-u\" are mutually exclusive"));

  scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  create_ada_exception_catchpoint (gdbarch, ex_kind,
				   exception_name,
				   condition, temp, enabled, 0);
}

/* Handler for the -catch-handlers command.  */

void
mi_cmd_catch_handlers (const char *cmd, char *argv[], int argc)
{
  struct gdbarch *gdbarch = get_current_arch ();
  std::string condition;
  int enabled = 1;
  std::string exception_name;
  int temp = 0;

  int oind = 0;
  char *oarg;

  enum opt
    {
      OPT_CONDITION, OPT_DISABLED, OPT_EXCEPTION_NAME, OPT_TEMP
    };
  static const struct mi_opt opts[] =
    {
      { "c", OPT_CONDITION, 1},
      { "d", OPT_DISABLED, 0 },
      { "e", OPT_EXCEPTION_NAME, 1 },
      { "t", OPT_TEMP, 0 },
      { 0, 0, 0 }
    };

  for (;;)
    {
      int opt = mi_getopt ("-catch-handlers", argc, argv, opts,
			   &oind, &oarg);

      if (opt < 0)
	break;

      switch ((enum opt) opt)
	{
	case OPT_CONDITION:
	  condition.assign (oarg);
	  break;
	case OPT_DISABLED:
	  enabled = 0;
	  break;
	case OPT_EXCEPTION_NAME:
	  exception_name = oarg;
	  break;
	case OPT_TEMP:
	  temp = 1;
	  break;
	}
    }

  /* This command does not accept any argument.  Make sure the user
     did not provide any.  */
  if (oind != argc)
    error (_("Invalid argument: %s"), argv[oind]);

  scoped_restore restore_breakpoint_reporting
    = setup_breakpoint_reporting ();
  create_ada_exception_catchpoint (gdbarch, ada_catch_handlers,
				   exception_name,
				   condition, temp, enabled, 0);
}

/* Common path for the -catch-load and -catch-unload.  */

static void
mi_catch_load_unload (int load, char *argv[], int argc)
{
  const char *actual_cmd = load ? "-catch-load" : "-catch-unload";
  int temp = 0;
  int enabled = 1;
  int oind = 0;
  char *oarg;
  enum opt
    {
      OPT_TEMP,
      OPT_DISABLED,
    };
  static const struct mi_opt opts[] =
    {
      { "t", OPT_TEMP, 0 },
      { "d", OPT_DISABLED, 0 },
      { 0, 0, 0 }
    };

  for (;;)
    {
      int opt = mi_getopt (actual_cmd, argc, argv, opts,
			   &oind, &oarg);

      if (opt < 0)
	break;

      switch ((enum opt) opt)
	{
	case OPT_TEMP:
	  temp = 1;
	  break;
	case OPT_DISABLED:
	  enabled = 0;
	  break;
	}
    }

  if (oind >= argc)
    error (_("-catch-load/unload: Missing <library name>"));
  if (oind < argc -1)
    error (_("-catch-load/unload: Garbage following the <library name>"));

  scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  add_solib_catchpoint (argv[oind], load, temp, enabled);
}

/* Handler for the -catch-load.  */

void
mi_cmd_catch_load (const char *cmd, char *argv[], int argc)
{
  mi_catch_load_unload (1, argv, argc);
}


/* Handler for the -catch-unload.  */

void
mi_cmd_catch_unload (const char *cmd, char *argv[], int argc)
{
  mi_catch_load_unload (0, argv, argc);
}

/* Core handler for -catch-throw, -catch-rethrow, and -catch-catch
   commands.  The argument handling for all of these is identical, we just
   pass KIND through to GDB's core to select the correct event type.  */

static void
mi_cmd_catch_exception_event (enum exception_event_kind kind,
			      const char *cmd, char *argv[], int argc)
{
  char *regex = NULL;
  bool temp = false;
  int oind = 0;
  char *oarg;
  enum opt
    {
      OPT_TEMP,
      OPT_REGEX,
    };
  static const struct mi_opt opts[] =
    {
      { "t", OPT_TEMP, 0 },
      { "r", OPT_REGEX, 1 },
      { 0, 0, 0 }
    };

  for (;;)
    {
      int opt = mi_getopt (cmd, argc, argv, opts,
			   &oind, &oarg);

      if (opt < 0)
	break;

      switch ((enum opt) opt)
	{
	case OPT_TEMP:
	  temp = true;
	  break;
	case OPT_REGEX:
	  regex = oarg;
	  break;
	}
    }

  scoped_restore restore_breakpoint_reporting = setup_breakpoint_reporting ();
  catch_exception_event (kind, regex, temp, 0 /* from_tty */);
}

/* Handler for -catch-throw.  */

void
mi_cmd_catch_throw (const char *cmd, char *argv[], int argc)
{
  mi_cmd_catch_exception_event (EX_EVENT_THROW, cmd, argv, argc);
}

/* Handler for -catch-rethrow.  */

void
mi_cmd_catch_rethrow (const char *cmd, char *argv[], int argc)
{
  mi_cmd_catch_exception_event (EX_EVENT_RETHROW, cmd, argv, argc);
}

/* Handler for -catch-catch.  */

void
mi_cmd_catch_catch (const char *cmd, char *argv[], int argc)
{
  mi_cmd_catch_exception_event (EX_EVENT_CATCH, cmd, argv, argc);
}

