2000-03-21 J.T. Conklin <jtc@redback.com>
[platform/upstream/binutils.git] / gdb / tracepoint.c
index 988cb12..245f1d0 100644 (file)
@@ -30,6 +30,7 @@
 #include "gdb_string.h"
 #include "inferior.h"
 #include "tracepoint.h"
+#include "remote.h"
 
 #include "ax.h"
 #include "ax-gdb.h"
@@ -193,22 +194,15 @@ trace_error (buf)
     }
 }
 
-/* Entry points into remote.c (FIXME: move this interface down to tgt vector)
- */
-
-extern int  putpkt PARAMS ((char *));
-extern void getpkt PARAMS ((char *, int));
-extern void remote_console_output PARAMS ((char *));
-
 /* Utility: wait for reply from stub, while accepting "O" packets */
 static char *
-remote_get_noisy_reply (buf)
-     char *buf;
+remote_get_noisy_reply (char *buf,
+                       long sizeof_buf)
 {
   do                           /* loop on reply from remote stub */
     {
       QUIT;                    /* allow user to bail out with ^C */
-      getpkt (buf, 0);
+      getpkt (buf, sizeof_buf, 0);
       if (buf[0] == 0)
        error ("Target does not support this command.");
       else if (buf[0] == 'E')
@@ -505,7 +499,7 @@ tracepoints_info (tpnum_exp, from_tty)
        printf_filtered ("%s ",
                         local_hex_string_custom ((unsigned long) t->address,
                                                  "08l"));
-      printf_filtered ("%-5d %-5d ", t->pass_count, t->step_count);
+      printf_filtered ("%-5d %-5ld ", t->pass_count, t->step_count);
 
       if (t->source_file)
        {
@@ -562,6 +556,9 @@ tracepoint_operation (t, from_tty, opcode)
 {
   struct tracepoint *t2;
 
+  if (t == NULL)       /* no tracepoint operand */
+    return;
+
   switch (opcode)
     {
     case enable_op:
@@ -601,51 +598,47 @@ tracepoint_operation (t, from_tty, opcode)
     }
 }
 
-/* Utility: parse a tracepoint number and look it up in the list.  */
+/* Utility: parse a tracepoint number and look it up in the list.
+   If MULTI_P is true, there might be a range of tracepoints in ARG.
+   if OPTIONAL_P is true, then if the argument is missing, the most
+   recent tracepoint (tracepoint_count) is returned.  */
 struct tracepoint *
-get_tracepoint_by_number (arg)
+get_tracepoint_by_number (arg, multi_p, optional_p)
      char **arg;
+     int multi_p, optional_p;
 {
   struct tracepoint *t;
-  char *end, *copy;
-  value_ptr val;
   int tpnum;
+  char *instring = arg == NULL ? NULL : *arg;
 
-  if (arg == 0)
-    error ("Bad tracepoint argument");
-
-  if (*arg == 0 || **arg == 0) /* empty arg means refer to last tp */
-    tpnum = tracepoint_count;
-  else if (**arg == '$')       /* handle convenience variable */
+  if (arg == NULL || *arg == NULL || ! **arg)
     {
-      /* Make a copy of the name, so we can null-terminate it
-         to pass to lookup_internalvar().  */
-      end = *arg + 1;
-      while (isalnum ((int) *end) || *end == '_')
-       end++;
-      copy = (char *) alloca (end - *arg);
-      strncpy (copy, *arg + 1, (end - *arg - 1));
-      copy[end - *arg - 1] = '\0';
-      *arg = end;
-
-      val = value_of_internalvar (lookup_internalvar (copy));
-      if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_INT)
-       error ("Convenience variable must have integral type.");
-      tpnum = (int) value_as_long (val);
+      if (optional_p)
+       tpnum = tracepoint_count;
+      else
+       error_no_arg ("tracepoint number");
     }
   else
-    /* handle tracepoint number */
+    tpnum = multi_p ? get_number_or_range (arg) : get_number (arg);
+
+  if (tpnum <= 0)
     {
-      tpnum = strtol (*arg, arg, 0);
-      if (tpnum == 0)          /* possible strtol failure */
-       while (**arg && !isspace ((int) **arg))
-         (*arg)++;             /* advance to next white space, if any */
+      if (instring && *instring)
+       printf_filtered ("bad tracepoint number at or near '%s'\n", instring);
+      else
+       printf_filtered ("Tracepoint argument missing and no previous tracepoint\n");
+      return NULL;
     }
+
   ALL_TRACEPOINTS (t)
     if (t->number == tpnum)
     {
       return t;
     }
+
+  /* FIXME: if we are in the middle of a range we don't want to give
+     a message.  The current interface to get_number_or_range doesn't
+     allow us to discover this.  */
   printf_unfiltered ("No tracepoint number %d.\n", tpnum);
   return NULL;
 }
@@ -666,9 +659,8 @@ map_args_over_tracepoints (args, from_tty, opcode)
     while (*args)
       {
        QUIT;                   /* give user option to bail out with ^C */
-       t = get_tracepoint_by_number (&args);
-       if (t)
-         tracepoint_operation (t, from_tty, opcode);
+       t = get_tracepoint_by_number (&args, 1, 0);
+       tracepoint_operation (t, from_tty, opcode);
        while (*args == ' ' || *args == '\t')
          args++;
       }
@@ -723,9 +715,10 @@ trace_pass_command (args, from_tty)
 {
   struct tracepoint *t1 = (struct tracepoint *) -1, *t2;
   unsigned int count;
+  int all = 0;
 
   if (args == 0 || *args == 0)
-    error ("PASS command requires an argument (count + optional TP num)");
+    error ("passcount command requires an argument (count + optional TP num)");
 
   count = strtoul (args, &args, 10);   /* count comes first, then TP num */
 
@@ -733,26 +726,34 @@ trace_pass_command (args, from_tty)
     args++;
 
   if (*args && strncasecmp (args, "all", 3) == 0)
-    args += 3;                 /* skip special argument "all" */
+    {
+      args += 3;                       /* skip special argument "all" */
+      all = 1;
+      if (*args)
+       error ("Junk at end of arguments.");
+    }
   else
-    t1 = get_tracepoint_by_number (&args);
-
-  if (*args)
-    error ("Junk at end of arguments.");
+    t1 = get_tracepoint_by_number (&args, 1, 1);
 
-  if (t1 == NULL)
-    return;                    /* error, bad tracepoint number */
-
-  ALL_TRACEPOINTS (t2)
-    if (t1 == (struct tracepoint *) -1 || t1 == t2)
+  do
     {
-      t2->pass_count = count;
-      if (modify_tracepoint_hook)
-       modify_tracepoint_hook (t2);
-      if (from_tty)
-       printf_filtered ("Setting tracepoint %d's passcount to %d\n",
-                        t2->number, count);
+      if (t1)
+       {
+         ALL_TRACEPOINTS (t2)
+           if (t1 == (struct tracepoint *) -1 || t1 == t2)
+             {
+               t2->pass_count = count;
+               if (modify_tracepoint_hook)
+                 modify_tracepoint_hook (t2);
+               if (from_tty)
+                 printf_filtered ("Setting tracepoint %d's passcount to %d\n",
+                                  t2->number, count);
+             }
+         if (! all && *args)
+           t1 = get_tracepoint_by_number (&args, 1, 0);
+       }
     }
+  while (*args);
 }
 
 /* ACTIONS functions: */
@@ -803,7 +804,7 @@ trace_actions_command (args, from_tty)
   char tmpbuf[128];
   char *end_msg = "End with a line saying just \"end\".";
 
-  t = get_tracepoint_by_number (&args);
+  t = get_tracepoint_by_number (&args, 0, 1);
   if (t)
     {
       sprintf (tmpbuf, "Enter actions for tracepoint %d, one per line.",
@@ -823,10 +824,9 @@ trace_actions_command (args, from_tty)
 
       if (readline_end_hook)
        (*readline_end_hook) ();
-
       /* tracepoints_changed () */
     }
-  /* else error, just return; */
+  /* else just return */
 }
 
 /* worker function */
@@ -848,7 +848,7 @@ read_actions (t)
 #ifdef STOP_SIGNAL
   if (job_control)
     {
-      if (async_p)
+      if (event_loop_p)
        signal (STOP_SIGNAL, handle_stop_sig);
       else
        signal (STOP_SIGNAL, stop_sig);
@@ -1736,7 +1736,7 @@ remote_set_transparent_ranges (void)
   if (anysecs)
     {
       putpkt (target_buf);
-      getpkt (target_buf, 0);
+      getpkt (target_buf, sizeof (target_buf), 0);
     }
 }
 
@@ -1764,7 +1764,7 @@ trace_start_command (args, from_tty)
   if (target_is_remote ())
     {
       putpkt ("QTinit");
-      remote_get_noisy_reply (target_buf);
+      remote_get_noisy_reply (target_buf, sizeof (target_buf));
       if (strcmp (target_buf, "OK"))
        error ("Target does not support this command.");
 
@@ -1773,14 +1773,14 @@ trace_start_command (args, from_tty)
        char tmp[40];
 
        sprintf_vma (tmp, t->address);
-       sprintf (buf, "QTDP:%x:%s:%c:%x:%x", t->number, tmp, /* address */
+       sprintf (buf, "QTDP:%x:%s:%c:%lx:%x", t->number, tmp, /* address */
                 t->enabled == enabled ? 'E' : 'D',
                 t->step_count, t->pass_count);
 
        if (t->actions)
          strcat (buf, "-");
        putpkt (buf);
-       remote_get_noisy_reply (target_buf);
+       remote_get_noisy_reply (target_buf, sizeof (target_buf));
        if (strcmp (target_buf, "OK"))
          error ("Target does not support tracepoints.");
 
@@ -1804,7 +1804,7 @@ trace_start_command (args, from_tty)
                             ((tdp_actions[ndx + 1] || stepping_actions)
                              ? '-' : 0));
                    putpkt (buf);
-                   remote_get_noisy_reply (target_buf);
+                   remote_get_noisy_reply (target_buf, sizeof (target_buf));
                    if (strcmp (target_buf, "OK"))
                      error ("Error on target while setting tracepoints.");
                  }
@@ -1820,7 +1820,7 @@ trace_start_command (args, from_tty)
                             stepping_actions[ndx],
                             (stepping_actions[ndx + 1] ? "-" : ""));
                    putpkt (buf);
-                   remote_get_noisy_reply (target_buf);
+                   remote_get_noisy_reply (target_buf, sizeof (target_buf));
                    if (strcmp (target_buf, "OK"))
                      error ("Error on target while setting tracepoints.");
                  }
@@ -1833,7 +1833,7 @@ trace_start_command (args, from_tty)
       remote_set_transparent_ranges ();
       /* Now insert traps and begin collecting data */
       putpkt ("QTStart");
-      remote_get_noisy_reply (target_buf);
+      remote_get_noisy_reply (target_buf, sizeof (target_buf));
       if (strcmp (target_buf, "OK"))
        error ("Bogus reply from target: %s", target_buf);
       set_traceframe_num (-1); /* all old traceframes invalidated */
@@ -1857,7 +1857,7 @@ trace_stop_command (args, from_tty)
   if (target_is_remote ())
     {
       putpkt ("QTStop");
-      remote_get_noisy_reply (target_buf);
+      remote_get_noisy_reply (target_buf, sizeof (target_buf));
       if (strcmp (target_buf, "OK"))
        error ("Bogus reply from target: %s", target_buf);
       trace_running_p = 0;
@@ -1879,7 +1879,7 @@ trace_status_command (args, from_tty)
   if (target_is_remote ())
     {
       putpkt ("qTStatus");
-      remote_get_noisy_reply (target_buf);
+      remote_get_noisy_reply (target_buf, sizeof (target_buf));
 
       if (target_buf[0] != 'T' ||
          (target_buf[1] != '0' && target_buf[1] != '1'))
@@ -1894,9 +1894,9 @@ trace_status_command (args, from_tty)
 
 /* Worker function for the various flavors of the tfind command */
 static void
-finish_tfind_command (msg, from_tty)
-     char *msg;
-     int from_tty;
+finish_tfind_command (char *msg,
+                     long sizeof_msg,
+                     int from_tty)
 {
   int target_frameno = -1, target_tracept = -1;
   CORE_ADDR old_frame_addr;
@@ -1907,7 +1907,7 @@ finish_tfind_command (msg, from_tty)
   old_func = find_pc_function (read_pc ());
 
   putpkt (msg);
-  reply = remote_get_noisy_reply (msg);
+  reply = remote_get_noisy_reply (msg, sizeof_msg);
 
   while (reply && *reply)
     switch (*reply)
@@ -2051,7 +2051,7 @@ trace_find_command (args, from_tty)
        error ("invalid input (%d is less than zero)", frameno);
 
       sprintf (target_buf, "QTFrame:%x", frameno);
-      finish_tfind_command (target_buf, from_tty);
+      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
     }
   else
     error ("Trace can only be run on remote targets.");
@@ -2102,7 +2102,7 @@ trace_find_pc_command (args, from_tty)
 
       sprintf_vma (tmp, pc);
       sprintf (target_buf, "QTFrame:pc:%s", tmp);
-      finish_tfind_command (target_buf, from_tty);
+      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
     }
   else
     error ("Trace can only be run on remote targets.");
@@ -2127,7 +2127,7 @@ trace_find_tracepoint_command (args, from_tty)
        tdp = parse_and_eval_address (args);
 
       sprintf (target_buf, "QTFrame:tdp:%x", tdp);
-      finish_tfind_command (target_buf, from_tty);
+      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
     }
   else
     error ("Trace can only be run on remote targets.");
@@ -2223,7 +2223,7 @@ trace_find_line_command (args, from_tty)
        sprintf (target_buf, "QTFrame:range:%s:%s", startpc_str, endpc_str);
       else                     /* find OUTSIDE OF range of CURRENT line */
        sprintf (target_buf, "QTFrame:outside:%s:%s", startpc_str, endpc_str);
-      finish_tfind_command (target_buf, from_tty);
+      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
       do_cleanups (old_chain);
     }
   else
@@ -2265,7 +2265,7 @@ trace_find_range_command (args, from_tty)
       sprintf_vma (start_str, start);
       sprintf_vma (stop_str, stop);
       sprintf (target_buf, "QTFrame:range:%s:%s", start_str, stop_str);
-      finish_tfind_command (target_buf, from_tty);
+      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
     }
   else
     error ("Trace can only be run on remote targets.");
@@ -2306,7 +2306,7 @@ trace_find_outside_command (args, from_tty)
       sprintf_vma (start_str, start);
       sprintf_vma (stop_str, stop);
       sprintf (target_buf, "QTFrame:outside:%s:%s", start_str, stop_str);
-      finish_tfind_command (target_buf, from_tty);
+      finish_tfind_command (target_buf, sizeof (target_buf), from_tty);
     }
   else
     error ("Trace can only be run on remote targets.");