2013-02-14 Pedro Alves <pedro@codesourcery.com>
authorHafiz Abid Qadeer <abidh@codesourcery.com>
Thu, 14 Feb 2013 10:19:39 +0000 (10:19 +0000)
committerHafiz Abid Qadeer <abidh@codesourcery.com>
Thu, 14 Feb 2013 10:19:39 +0000 (10:19 +0000)
    Hafiz Abid Qadeer  <abidh@codesourcery.com>

gdb/
* tracepoint.h (validate_trace_state_variable_name): Declare.
* tracepoint.c (validate_trace_state_variable_name): New.
(trace_variable_command): Parse the trace state variable's name
without using parse_expression.  Do several validations.
* mi/mi-main.c (mi_cmd_trace_define_variable): Don't parse the
trace state variable's name with parse_expression.  Validate it.

gdb/testsuite/
* gdb.trace/tsv.exp: Adjust tests, and add a few more.

gdb/ChangeLog
gdb/mi/mi-main.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.trace/tsv.exp
gdb/tracepoint.c
gdb/tracepoint.h

index 0f26c12c1d2ea97d8c3a1cfa9c0c3e53f2807c4f..ae09cc1e275e324efd1f1398ab85ee8c7c5d21a2 100644 (file)
@@ -1,3 +1,13 @@
+2013-02-14  Pedro Alves  <pedro@codesourcery.com>
+           Hafiz Abid Qadeer  <abidh@codesourcery.com>
+
+       * tracepoint.h (validate_trace_state_variable_name): Declare.
+       * tracepoint.c (validate_trace_state_variable_name): New.
+       (trace_variable_command): Parse the trace state variable's name
+       without using parse_expression.  Do several validations.
+       * mi/mi-main.c (mi_cmd_trace_define_variable): Don't parse the
+       trace state variable's name with parse_expression.  Validate it.
+
 2013-02-14  Yao Qi  <yao@codesourcery.com>
 
        * infcmd.c (breakpoint_proceeded): Remove it.
index 28de126aa9b4e80204ec42096d81908a89f0f24c..37294e0b5ba1a6ed3271bff3e68649e57349e63d 100644 (file)
@@ -2357,7 +2357,6 @@ void
 mi_cmd_trace_define_variable (char *command, char **argv, int argc)
 {
   struct expression *expr;
-  struct cleanup *back_to;
   LONGEST initval = 0;
   struct trace_state_variable *tsv;
   char *name = 0;
@@ -2365,19 +2364,11 @@ mi_cmd_trace_define_variable (char *command, char **argv, int argc)
   if (argc != 1 && argc != 2)
     error (_("Usage: -trace-define-variable VARIABLE [VALUE]"));
 
-  expr = parse_expression (argv[0]);
-  back_to = make_cleanup (xfree, expr);
-
-  if (expr->nelts == 3 && expr->elts[0].opcode == OP_INTERNALVAR)
-    {
-      struct internalvar *intvar = expr->elts[1].internalvar;
-
-      if (intvar)
-       name = internalvar_name (intvar);
-    }
+  name = argv[0];
+  if (*name++ != '$')
+    error (_("Name of trace variable should start with '$'"));
 
-  if (!name || *name == '\0')
-    error (_("Invalid name of trace variable"));
+  validate_trace_state_variable_name (name);
 
   tsv = find_trace_state_variable (name);
   if (!tsv)
@@ -2387,8 +2378,6 @@ mi_cmd_trace_define_variable (char *command, char **argv, int argc)
     initval = value_as_long (parse_and_eval (argv[1]));
 
   tsv->initial_value = initval;
-
-  do_cleanups (back_to);
 }
 
 void
index cd0989f9f60912631d53bdf63089640131db3df3..9a377259c04cf0d14fa6b47a44c254d77b3fd4ed 100644 (file)
@@ -1,3 +1,8 @@
+2013-02-14  Pedro Alves  <pedro@codesourcery.com>
+           Hafiz Abid Qadeer  <abidh@codesourcery.com>
+
+       * gdb.trace/tsv.exp: Adjust tests, and add a few more.
+
 2013-02-12  Tom Tromey  <tromey@redhat.com>
 
        * gdb.cp/m-static.cc (gnu_obj_1::~gnu_obj_1): New destructor.
index 4ea930f781683d641de11bde7623071b618df826..47d66ad0b2042c3feb6bca0a04fd87a67a02768d 100644 (file)
@@ -46,14 +46,30 @@ gdb_test "tvariable \$tvar3 = 1234567000000" \
   "Trace state variable \\\$tvar3 now has initial value 1234567000000." \
   "Init trace state variable to a 64-bit value"
 
+gdb_test "tvariable $" \
+  "Must supply a non-empty variable name" \
+  "tvariable syntax error, not empty variable name"
+
 gdb_test "tvariable main" \
-  "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \
+  "Name of trace variable should start with '\\\$'" \
   "tvariable syntax error, bad name"
 
+gdb_test "tvariable \$\$" \
+  "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \
+  "tvariable syntax error, bad name 2"
+
+gdb_test "tvariable \$123" \
+  "\\\$123 is not a valid trace state variable name" \
+  "tvariable syntax error, bad name 3"
+
 gdb_test "tvariable \$tvar1 - 93" \
   "Syntax must be \\\$NAME \\\[ = EXPR \\\]" \
   "tvariable syntax error, not an assignment"
 
+gdb_test "tvariable \$tvar0 = 1 = 1" \
+  "Left operand of assignment is not an lvalue\." \
+  "tvariable creation fails with invalid expression"
+
 gdb_test "info tvariables" \
     "Name\[\t \]+Initial\[\t \]+Current.*
 \\\$tvar1\[\t \]+0\[\t \]+<undefined>.*
index d4b0549cc92740265a2ae21b4062e5f7caa2b8bb..2e50164a1ca467723ba28a2271b6f181f830bfc9 100644 (file)
@@ -362,50 +362,67 @@ delete_trace_state_variable (const char *name)
   warning (_("No trace variable named \"$%s\", not deleting"), name);
 }
 
+/* Throws an error if NAME is not valid syntax for a trace state
+   variable's name.  */
+
+void
+validate_trace_state_variable_name (const char *name)
+{
+  const char *p;
+
+  if (*name == '\0')
+    error (_("Must supply a non-empty variable name"));
+
+  /* All digits in the name is reserved for value history
+     references.  */
+  for (p = name; isdigit (*p); p++)
+    ;
+  if (*p == '\0')
+    error (_("$%s is not a valid trace state variable name"), name);
+
+  for (p = name; isalnum (*p) || *p == '_'; p++)
+    ;
+  if (*p != '\0')
+    error (_("$%s is not a valid trace state variable name"), name);
+}
+
 /* The 'tvariable' command collects a name and optional expression to
    evaluate into an initial value.  */
 
 static void
 trace_variable_command (char *args, int from_tty)
 {
-  struct expression *expr;
   struct cleanup *old_chain;
-  struct internalvar *intvar = NULL;
   LONGEST initval = 0;
   struct trace_state_variable *tsv;
+  char *name, *p;
 
   if (!args || !*args)
-    error_no_arg (_("trace state variable name"));
+    error_no_arg (_("Syntax is $NAME [ = EXPR ]"));
 
-  /* All the possible valid arguments are expressions.  */
-  expr = parse_expression (args);
-  old_chain = make_cleanup (free_current_contents, &expr);
+  /* Only allow two syntaxes; "$name" and "$name=value".  */
+  p = skip_spaces (args);
 
-  if (expr->nelts == 0)
-    error (_("No expression?"));
+  if (*p++ != '$')
+    error (_("Name of trace variable should start with '$'"));
 
-  /* Only allow two syntaxes; "$name" and "$name=value".  */
-  if (expr->elts[0].opcode == OP_INTERNALVAR)
-    {
-      intvar = expr->elts[1].internalvar;
-    }
-  else if (expr->elts[0].opcode == BINOP_ASSIGN
-          && expr->elts[1].opcode == OP_INTERNALVAR)
-    {
-      intvar = expr->elts[2].internalvar;
-      initval = value_as_long (evaluate_subexpression_type (expr, 4));
-    }
-  else
+  name = p;
+  while (isalnum (*p) || *p == '_')
+    p++;
+  name = savestring (name, p - name);
+  old_chain = make_cleanup (xfree, name);
+
+  p = skip_spaces (p);
+  if (*p != '=' && *p != '\0')
     error (_("Syntax must be $NAME [ = EXPR ]"));
 
-  if (!intvar)
-    error (_("No name given"));
+  validate_trace_state_variable_name (name);
 
-  if (strlen (internalvar_name (intvar)) <= 0)
-    error (_("Must supply a non-empty variable name"));
+  if (*p == '=')
+    initval = value_as_long (parse_and_eval (++p));
 
   /* If the variable already exists, just change its initial value.  */
-  tsv = find_trace_state_variable (internalvar_name (intvar));
+  tsv = find_trace_state_variable (name);
   if (tsv)
     {
       if (tsv->initial_value != initval)
@@ -421,7 +438,7 @@ trace_variable_command (char *args, int from_tty)
     }
 
   /* Create a new variable.  */
-  tsv = create_trace_state_variable (internalvar_name (intvar));
+  tsv = create_trace_state_variable (name);
   tsv->initial_value = initval;
 
   observer_notify_tsv_created (tsv);
index f95bb545b2c60f9a27dfa6b9109b141c57b91e49..4a3df39e3086bcb94888fd433f49f85fd205c5ae 100644 (file)
@@ -243,6 +243,7 @@ extern void encode_actions (struct breakpoint *t, struct bp_location *tloc,
                            char ***tdp_actions, char ***stepping_actions);
 
 extern void validate_actionline (char **, struct breakpoint *);
+extern void validate_trace_state_variable_name (const char *name);
 
 extern struct trace_state_variable *find_trace_state_variable (const char *name);
 extern struct trace_state_variable *create_trace_state_variable (const char *name);