Introduce command_line_up
[deliverable/binutils-gdb.git] / gdb / mi / mi-cmd-break.c
index 332d9e287ba35278275aa8c79d55215a7524e893..cfe2d34f23fdd9823a025d82bd4c405d258f92aa 100644 (file)
@@ -1,5 +1,5 @@
 /* MI Command Set - breakpoint and watchpoint commands.
-   Copyright (C) 2000-2014 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions (a Red Hat company).
 
    This file is part of GDB.
@@ -28,6 +28,9 @@
 #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>
 
@@ -153,7 +156,7 @@ mi_argv_to_format (char **argv, int argc)
     }
   obstack_1grow (&obstack, '\0');
 
-  ret = xstrdup (obstack_finish (&obstack));
+  ret = xstrdup ((const char *) obstack_finish (&obstack));
   obstack_free (&obstack, NULL);
 
   return ret;
@@ -164,7 +167,7 @@ mi_argv_to_format (char **argv, int argc)
    If not, it will insert other type breakpoint.  */
 
 static void
-mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
+mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
 {
   char *address = NULL;
   int hardware = 0;
@@ -177,7 +180,10 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
   int tracepoint = 0;
   struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
   enum bptype type_wanted;
+  event_location_up location;
   struct breakpoint_ops *ops;
+  int is_explicit = 0;
+  struct explicit_location explicit_loc;
   char *extra_string = NULL;
 
   enum opt
@@ -185,6 +191,8 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
       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[] =
   {
@@ -196,6 +204,10 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
     {"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 }
   };
 
@@ -204,6 +216,8 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
   int oind = 0;
   char *oarg;
 
+  initialize_explicit_location (&explicit_loc);
+
   while (1)
     {
       int opt = mi_getopt ("-break-insert", argc, argv,
@@ -236,16 +250,31 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
        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)
+  if (oind >= argc && !is_explicit)
     error (_("-%s-insert: Missing <location>"),
           dprintf ? "dprintf" : "break");
-  address = argv[oind];
   if (dprintf)
     {
-      int format_num = oind + 1;
+      int format_num = is_explicit ? oind : oind + 1;
 
       if (hardware || tracepoint)
        error (_("-dprintf-insert: does not support -h or -a"));
@@ -254,11 +283,21 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
 
       extra_string = mi_argv_to_format (argv + format_num, argc - format_num);
       make_cleanup (xfree, extra_string);
+      address = argv[oind];
     }
   else
     {
-      if (oind < argc - 1)
-       error (_("-break-insert: Garbage following <location>"));
+      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!  */
@@ -287,7 +326,27 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
       ops = &bkpt_breakpoint_ops;
     }
 
-  create_breakpoint (get_current_arch (), address, condition, thread,
+  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,
                     0 /* condition and thread are valid.  */,
                     temp_p, type_wanted,
@@ -301,7 +360,7 @@ mi_cmd_break_insert_1 (int dprintf, char *command, char **argv, int argc)
    See the MI manual for the list of possible options.  */
 
 void
-mi_cmd_break_insert (char *command, char **argv, int argc)
+mi_cmd_break_insert (const char *command, char **argv, int argc)
 {
   mi_cmd_break_insert_1 (0, command, argv, argc);
 }
@@ -310,7 +369,7 @@ mi_cmd_break_insert (char *command, char **argv, int argc)
    See the MI manual for the list of possible options.  */
 
 void
-mi_cmd_dprintf_insert (char *command, char **argv, int argc)
+mi_cmd_dprintf_insert (const char *command, char **argv, int argc)
 {
   mi_cmd_break_insert_1 (1, command, argv, argc);
 }
@@ -323,7 +382,7 @@ enum wp_type
 };
 
 void
-mi_cmd_break_passcount (char *command, char **argv, int argc)
+mi_cmd_break_passcount (const char *command, char **argv, int argc)
 {
   int n;
   int p;
@@ -354,7 +413,7 @@ mi_cmd_break_passcount (char *command, char **argv, int argc)
    -break-watch -a <expr> --> insert an access wp.  */
 
 void
-mi_cmd_break_watch (char *command, char **argv, int argc)
+mi_cmd_break_watch (const char *command, char **argv, int argc)
 {
   char *expr = NULL;
   enum wp_type type = REG_WP;
@@ -432,9 +491,9 @@ mi_read_next_line (void)
 }
 
 void
-mi_cmd_break_commands (char *command, char **argv, int argc)
+mi_cmd_break_commands (const char *command, char **argv, int argc)
 {
-  struct command_line *break_command;
+  command_line_up break_command;
   char *endptr;
   int bnum;
   struct breakpoint *b;
@@ -464,6 +523,6 @@ mi_cmd_break_commands (char *command, char **argv, int argc)
   else
     break_command = read_command_lines_1 (mi_read_next_line, 1, 0, 0);
 
-  breakpoint_set_commands (b, break_command);
+  breakpoint_set_commands (b, std::move (break_command));
 }
 
This page took 0.026638 seconds and 4 git commands to generate.