aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2010-08-19 13:33:15 +0000
committerDoug Evans <dje@google.com>2010-08-19 13:33:15 +0000
commitd30f5e1f70ffa9fab08ccdacdba1bd6365d2511d (patch)
treea578156b090268842ed34a2a077d2eb6b6519cd2
parent2837d59e6b7e523fee86a5a5a050ecb5554ccd1b (diff)
downloadgdb-d30f5e1f70ffa9fab08ccdacdba1bd6365d2511d.zip
gdb-d30f5e1f70ffa9fab08ccdacdba1bd6365d2511d.tar.gz
gdb-d30f5e1f70ffa9fab08ccdacdba1bd6365d2511d.tar.bz2
PR exp/11926
* parser-defs.h (parse_float, parse_c_float): Declare. * parse.c (parse_float, parse_c_float): New function. * c-exp.y (parse_number): Call parse_c_float. * objc-exp.y (parse_number): Ditto. * p-exp.y (parse_number): Ditto. Use ANSI/ISO-style definition. * jv-exp.y (parse_number): Call parse_float, fix suffix handling. testsuite/ * gdb.base/printcmds.exp (test_float_accepted): New function. Move existing float tests there. Add tests for floats with suffixes. (test_float_rejected): New function. * gdb.java/jv-print.exp (test_float_accepted): New function. (test_float_rejected): New function. * gdb.objc/print.exp: New file. * gdb.pascal/print.exp: New file. * lib/objc.exp: New file.
-rw-r--r--gdb/ChangeLog10
-rw-r--r--gdb/c-exp.y39
-rw-r--r--gdb/jv-exp.y33
-rw-r--r--gdb/objc-exp.y22
-rw-r--r--gdb/p-exp.y32
-rw-r--r--gdb/parse.c69
-rw-r--r--gdb/parser-defs.h6
-rw-r--r--gdb/testsuite/ChangeLog12
-rw-r--r--gdb/testsuite/gdb.base/printcmds.exp43
-rw-r--r--gdb/testsuite/gdb.java/jv-print.exp24
-rw-r--r--gdb/testsuite/gdb.objc/print.exp68
-rw-r--r--gdb/testsuite/gdb.pascal/print.exp64
-rw-r--r--gdb/testsuite/lib/objc.exp30
13 files changed, 344 insertions, 108 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 580be2b..b165bf8 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,13 @@
+2010-08-19 Doug Evans <dje@google.com>
+
+ PR exp/11926
+ * parser-defs.h (parse_float, parse_c_float): Declare.
+ * parse.c (parse_float, parse_c_float): New function.
+ * c-exp.y (parse_number): Call parse_c_float.
+ * objc-exp.y (parse_number): Ditto.
+ * p-exp.y (parse_number): Ditto. Use ANSI/ISO-style definition.
+ * jv-exp.y (parse_number): Call parse_float, fix suffix handling.
+
2010-08-19 Joel Brobecker <brobecker@adacore.com>
* psymtab.c (map_symbol_filenames_psymtab): Call FUN with
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 030554c..663e778 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -1323,10 +1323,8 @@ parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
if (parsed_float)
{
- /* It's a float since it contains a point or an exponent. */
- char *s;
- int num; /* number of tokens scanned by scanf */
- char saved_char;
+ const char *suffix;
+ int suffix_len;
/* If it ends at "df", "dd" or "dl", take it as type of decimal floating
point. Return DECFLOAT. */
@@ -1364,35 +1362,10 @@ parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
return DECFLOAT;
}
- s = malloc (len);
- saved_char = p[len];
- p[len] = 0; /* null-terminate the token */
- num = sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%s",
- &putithere->typed_val_float.dval, s);
- p[len] = saved_char; /* restore the input stream */
-
- if (num == 1)
- putithere->typed_val_float.type =
- parse_type->builtin_double;
-
- if (num == 2 )
- {
- /* See if it has any float suffix: 'f' for float, 'l' for long
- double. */
- if (!strcasecmp (s, "f"))
- putithere->typed_val_float.type =
- parse_type->builtin_float;
- else if (!strcasecmp (s, "l"))
- putithere->typed_val_float.type =
- parse_type->builtin_long_double;
- else
- {
- free (s);
- return ERROR;
- }
- }
-
- free (s);
+ if (! parse_c_float (parse_gdbarch, p, len,
+ &putithere->typed_val_float.dval,
+ &putithere->typed_val_float.type))
+ return ERROR;
return FLOAT;
}
diff --git a/gdb/jv-exp.y b/gdb/jv-exp.y
index 8109e0c..678a434 100644
--- a/gdb/jv-exp.y
+++ b/gdb/jv-exp.y
@@ -703,25 +703,28 @@ parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
if (parsed_float)
{
- /* It's a float since it contains a point or an exponent. */
- char c;
- int num = 0; /* number of tokens scanned by scanf */
- char saved_char = p[len];
-
- p[len] = 0; /* null-terminate the token */
- num = sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%c",
- &putithere->typed_val_float.dval, &c);
- p[len] = saved_char; /* restore the input stream */
- if (num != 1) /* check scanf found ONLY a float ... */
+ const char *suffix;
+ int suffix_len;
+
+ if (! parse_float (p, len, &putithere->typed_val_float.dval, &suffix))
return ERROR;
- /* See if it has `f' or `d' suffix (float or double). */
- c = tolower (p[len - 1]);
+ suffix_len = p + len - suffix;
- if (c == 'f' || c == 'F')
- putithere->typed_val_float.type = parse_type->builtin_float;
- else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
+ if (suffix_len == 0)
putithere->typed_val_float.type = parse_type->builtin_double;
+ else if (suffix_len == 1)
+ {
+ /* See if it has `f' or `d' suffix (float or double). */
+ if (tolower (*suffix) == 'f')
+ putithere->typed_val_float.type =
+ parse_type->builtin_float;
+ else if (tolower (*suffix) == 'd')
+ putithere->typed_val_float.type =
+ parse_type->builtin_double;
+ else
+ return ERROR;
+ }
else
return ERROR;
diff --git a/gdb/objc-exp.y b/gdb/objc-exp.y
index 888bd20..1f3d1e7 100644
--- a/gdb/objc-exp.y
+++ b/gdb/objc-exp.y
@@ -1012,26 +1012,10 @@ parse_number (p, len, parsed_float, putithere)
if (parsed_float)
{
- char c;
-
- /* It's a float since it contains a point or an exponent. */
-
- sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%c",
- &putithere->typed_val_float.dval, &c);
-
- /* See if it has `f' or `l' suffix (float or long double). */
-
- c = tolower (p[len - 1]);
-
- if (c == 'f')
- putithere->typed_val_float.type = parse_type->builtin_float;
- else if (c == 'l')
- putithere->typed_val_float.type = parse_type->builtin_long_double;
- else if (isdigit (c) || c == '.')
- putithere->typed_val_float.type = parse_type->builtin_double;
- else
+ if (! parse_c_float (parse_gdbarch, p, len,
+ &putithere->typed_val_float.dval,
+ &putithere->typed_val_float.type))
return ERROR;
-
return FLOAT;
}
diff --git a/gdb/p-exp.y b/gdb/p-exp.y
index 2aec487..19f5ceb 100644
--- a/gdb/p-exp.y
+++ b/gdb/p-exp.y
@@ -791,11 +791,7 @@ name_not_typename : NAME
/*** Needs some error checking for the float case ***/
static int
-parse_number (p, len, parsed_float, putithere)
- char *p;
- int len;
- int parsed_float;
- YYSTYPE *putithere;
+parse_number (char *p, int len, int parsed_float, YYSTYPE *putithere)
{
/* FIXME: Shouldn't these be unsigned? We don't deal with negative values
here, and we do kind of silly things like cast to unsigned. */
@@ -820,30 +816,10 @@ parse_number (p, len, parsed_float, putithere)
if (parsed_float)
{
- /* It's a float since it contains a point or an exponent. */
- char c;
- int num = 0; /* number of tokens scanned by scanf */
- char saved_char = p[len];
-
- p[len] = 0; /* null-terminate the token */
- num = sscanf (p, "%" DOUBLEST_SCAN_FORMAT "%c",
- &putithere->typed_val_float.dval, &c);
- p[len] = saved_char; /* restore the input stream */
- if (num != 1) /* check scanf found ONLY a float ... */
+ if (! parse_c_float (parse_gdbarch, p, len,
+ &putithere->typed_val_float.dval,
+ &putithere->typed_val_float.type))
return ERROR;
- /* See if it has `f' or `l' suffix (float or long double). */
-
- c = tolower (p[len - 1]);
-
- if (c == 'f')
- putithere->typed_val_float.type = parse_type->builtin_float;
- else if (c == 'l')
- putithere->typed_val_float.type = parse_type->builtin_long_double;
- else if (isdigit (c) || c == '.')
- putithere->typed_val_float.type = parse_type->builtin_double;
- else
- return ERROR;
-
return FLOAT;
}
diff --git a/gdb/parse.c b/gdb/parse.c
index 035572e..18038ed 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1038,8 +1038,6 @@ prefixify_subexp (struct expression *inexpr,
return result;
}
-/* This page contains the two entry points to this file. */
-
/* Read an expression from the string *STRINGPTR points to,
parse it, and return a pointer to a struct expression that we malloc.
Use block BLOCK as the lexical context for variable names;
@@ -1252,6 +1250,73 @@ void
null_post_parser (struct expression **exp, int void_context_p)
{
}
+
+/* Parse floating point value P of length LEN.
+ Return 0 (false) if invalid, 1 (true) if valid.
+ The successfully parsed number is stored in D.
+ *SUFFIX points to the suffix of the number in P.
+
+ NOTE: This accepts the floating point syntax that sscanf accepts. */
+
+int
+parse_float (const char *p, int len, DOUBLEST *d, const char **suffix)
+{
+ char *copy;
+ char *s;
+ int n, num;
+
+ copy = xmalloc (len + 1);
+ memcpy (copy, p, len);
+ copy[len] = 0;
+
+ num = sscanf (copy, "%" DOUBLEST_SCAN_FORMAT "%n", d, &n);
+ xfree (copy);
+
+ /* The sscanf man page suggests not making any assumptions on the effect
+ of %n on the result, so we don't.
+ That is why we simply test num == 0. */
+ if (num == 0)
+ return 0;
+
+ *suffix = p + n;
+ return 1;
+}
+
+/* Parse floating point value P of length LEN, using the C syntax for floats.
+ Return 0 (false) if invalid, 1 (true) if valid.
+ The successfully parsed number is stored in *D.
+ Its type is taken from builtin_type (gdbarch) and is stored in *T. */
+
+int
+parse_c_float (struct gdbarch *gdbarch, const char *p, int len,
+ DOUBLEST *d, struct type **t)
+{
+ const char *suffix;
+ int suffix_len;
+ const struct builtin_type *builtin_types = builtin_type (gdbarch);
+
+ if (! parse_float (p, len, d, &suffix))
+ return 0;
+
+ suffix_len = p + len - suffix;
+
+ if (suffix_len == 0)
+ *t = builtin_types->builtin_double;
+ else if (suffix_len == 1)
+ {
+ /* Handle suffixes: 'f' for float, 'l' for long double. */
+ if (tolower (*suffix) == 'f')
+ *t = builtin_types->builtin_float;
+ else if (tolower (*suffix) == 'l')
+ *t = builtin_types->builtin_long_double;
+ else
+ return 0;
+ }
+ else
+ return 0;
+
+ return 1;
+}
/* Stuff for maintaining a stack of types. Currently just used by C, but
probably useful for any language which declares its types "backwards". */
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index bb79ae1..1625575 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -204,6 +204,12 @@ extern struct type *follow_types (struct type *);
extern void null_post_parser (struct expression **, int);
+extern int parse_float (const char *p, int len, DOUBLEST *d,
+ const char **suffix);
+
+extern int parse_c_float (struct gdbarch *gdbarch, const char *p, int len,
+ DOUBLEST *d, struct type **t);
+
/* During parsing of a C expression, the pointer to the next character
is in this variable. */
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 3bc7810..547deaf 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2010-08-19 Doug Evans <dje@google.com>
+
+ PR exp/11926
+ * gdb.base/printcmds.exp (test_float_accepted): New function.
+ Move existing float tests there. Add tests for floats with suffixes.
+ (test_float_rejected): New function.
+ * gdb.java/jv-print.exp (test_float_accepted): New function.
+ (test_float_rejected): New function.
+ * gdb.objc/print.exp: New file.
+ * gdb.pascal/print.exp: New file.
+ * lib/objc.exp: New file.
+
2010-08-19 Pierre Muller <muller@ics.u-strasbg.fr>
* gdb.base/default.exp (info set): Avoid full buffer error and force
diff --git a/gdb/testsuite/gdb.base/printcmds.exp b/gdb/testsuite/gdb.base/printcmds.exp
index 4c82ab3..d377597 100644
--- a/gdb/testsuite/gdb.base/printcmds.exp
+++ b/gdb/testsuite/gdb.base/printcmds.exp
@@ -102,17 +102,6 @@ proc test_integer_literals_rejected {} {
test_print_reject "p DEADBEEF"
- # Gdb currently fails this test for all configurations. The C
- # lexer thinks that 123DEADBEEF is a floating point number, but
- # then fails to notice that atof() only eats the 123 part.
- # FIXME: This should be put into PRMS.
- # Fixed, 4/25/97, by Bob Manson.
-
- test_print_reject "p 123DEADBEEF"
- test_print_reject "p 123foobar.bazfoo3"
- test_print_reject "p 123EEEEEEEEEEEEEEEEE33333k333"
- gdb_test "p 123.4+56.7" "180.(099\[0-9]*|100\[0-9\]*)" "check for floating addition"
-
# Test various octal values.
test_print_reject "p 09"
@@ -129,6 +118,36 @@ proc test_integer_literals_rejected {} {
test_print_reject "p 0b12"
}
+proc test_float_accepted {} {
+ # This test is useful to catch successful parsing of the first fp value.
+ gdb_test "p 123.4+56.7" " = 180.(099\[0-9]*|100\[0-9\]*)" "check for floating addition"
+
+ # Test all the suffixes (including no suffix).
+ gdb_test "p 1." " = 1"
+ gdb_test "p 1.5" " = 1.5"
+ gdb_test "p 1.f" " = 1"
+ gdb_test "p 1.5f" " = 1.5"
+ gdb_test "p 1.l" " = 1"
+ gdb_test "p 1.5l" " = 1.5"
+}
+
+proc test_float_rejected {} {
+ # Gdb use to fail this test for all configurations. The C
+ # lexer thought that 123DEADBEEF was a floating point number, but
+ # then failed to notice that atof() only eats the 123 part.
+ # Fixed, 4/25/97, by Bob Manson.
+ test_print_reject "p 123DEADBEEF"
+
+ test_print_reject "p 123foobar.bazfoo3"
+ test_print_reject "p 123EEEEEEEEEEEEEEEEE33333k333"
+ test_print_reject "p 0x1.1"
+
+ # Test bad suffixes.
+ test_print_reject "p 1.1x"
+ test_print_reject "p 1.1ff"
+ test_print_reject "p 1.1ll"
+}
+
proc test_print_all_chars {} {
global gdb_prompt
@@ -781,6 +800,8 @@ if ![runto_main] then {
test_integer_literals_accepted
test_integer_literals_rejected
+test_float_accepted
+test_float_rejected
test_character_literals_accepted
test_print_all_chars
test_print_repeats_10
diff --git a/gdb/testsuite/gdb.java/jv-print.exp b/gdb/testsuite/gdb.java/jv-print.exp
index c78f7d7..cdb598c 100644
--- a/gdb/testsuite/gdb.java/jv-print.exp
+++ b/gdb/testsuite/gdb.java/jv-print.exp
@@ -97,6 +97,28 @@ proc test_integer_literals_rejected {} {
test_print_reject "p 0xAG"
}
+proc test_float_accepted {} {
+ # Test parsing of fp value with legit text following.
+ gdb_test "p 1234.5+1" " = 1235.5" "check fp + text"
+
+ # Test all the suffixes (including no suffix).
+ gdb_test "p 1." " = 1"
+ gdb_test "p 1.5" " = 1.5"
+ gdb_test "p 1.f" " = 1"
+ gdb_test "p 1.5f" " = 1.5"
+ gdb_test "p 1.d" " = 1"
+ gdb_test "p 1.5d" " = 1.5"
+}
+
+proc test_float_rejected {} {
+ # Test invalid fp values.
+ test_print_reject "p 0x1.1"
+
+ # Test bad suffixes.
+ test_print_reject "p 1.1x"
+ test_print_reject "p 1.1ff"
+ test_print_reject "p 1.1dd"
+}
# Start with a fresh gdb.
@@ -117,6 +139,8 @@ if [set_lang_java] then {
test_integer_literals_accepted
test_character_literals_accepted
test_integer_literals_rejected
+ test_float_accepted
+ test_float_rejected
} else {
warning "Java print command tests suppressed"
}
diff --git a/gdb/testsuite/gdb.objc/print.exp b/gdb/testsuite/gdb.objc/print.exp
new file mode 100644
index 0000000..2988d20
--- /dev/null
+++ b/gdb/testsuite/gdb.objc/print.exp
@@ -0,0 +1,68 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2010 Free Software Foundation, Inc.
+
+# 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/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# Test printing of various values.
+# NOTE: The tests here intentionally do not require an objc compiler.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+load_lib "objc.exp"
+
+proc test_float_accepted {} {
+ # Test parsing of fp value with legit text following.
+ gdb_test "p 1234.5+1" " = 1235.5" "check fp + text"
+
+ # Test all the suffixes (including no suffix).
+ gdb_test "p 1." " = 1"
+ gdb_test "p 1.5" " = 1.5"
+ setup_kfail gdb/11925 "*-*-*"
+ gdb_test "p 1.f" " = 1"
+ setup_kfail gdb/11925 "*-*-*"
+ gdb_test "p 1.5f" " = 1.5"
+ setup_kfail gdb/11925 "*-*-*"
+ gdb_test "p 1.l" " = 1"
+ setup_kfail gdb/11925 "*-*-*"
+ gdb_test "p 1.5l" " = 1.5"
+}
+
+proc test_float_rejected {} {
+ # Test invalid fp values.
+ test_print_reject "p 0x1.1"
+
+ # Test bad suffixes.
+ test_print_reject "p 1.1x"
+ test_print_reject "p 1.1ff"
+ test_print_reject "p 1.1ll"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+if [set_lang_objc] {
+ test_float_accepted
+ test_float_rejected
+} else {
+ warning "Objective-c print tests suppressed"
+}
diff --git a/gdb/testsuite/gdb.pascal/print.exp b/gdb/testsuite/gdb.pascal/print.exp
new file mode 100644
index 0000000..61f6d37
--- /dev/null
+++ b/gdb/testsuite/gdb.pascal/print.exp
@@ -0,0 +1,64 @@
+# This testcase is part of GDB, the GNU debugger.
+
+# Copyright 2010 Free Software Foundation, Inc.
+
+# 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/>.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@gnu.org
+
+# Test printing of various values.
+# NOTE: The tests here intentionally do not require a pascal compiler.
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+load_lib "pascal.exp"
+
+proc test_float_accepted {} {
+ # Test parsing of fp value with legit text following.
+ gdb_test "p 1234.5+1" " = 1235.5" "check fp + text"
+
+ # Test all the suffixes (including no suffix).
+ gdb_test "p 1." " = 1"
+ gdb_test "p 1.5" " = 1.5"
+ gdb_test "p 1.f" " = 1"
+ gdb_test "p 1.5f" " = 1.5"
+ gdb_test "p 1.l" " = 1"
+ gdb_test "p 1.5l" " = 1.5"
+}
+
+proc test_float_rejected {} {
+ # Test invalid fp values.
+ test_print_reject "p 0x1.1"
+
+ # Test bad suffixes.
+ test_print_reject "p 1.1x"
+ test_print_reject "p 1.1ff"
+ test_print_reject "p 1.1ll"
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+if [set_lang_pascal] {
+ test_float_accepted
+ test_float_rejected
+} else {
+ warning "Pascal print tests suppressed"
+}
diff --git a/gdb/testsuite/lib/objc.exp b/gdb/testsuite/lib/objc.exp
new file mode 100644
index 0000000..190c715
--- /dev/null
+++ b/gdb/testsuite/lib/objc.exp
@@ -0,0 +1,30 @@
+# This test code is part of GDB, the GNU debugger.
+
+# Copyright 2010 Free Software Foundation, Inc.
+#
+# 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/>.
+
+# Auxiliary function to set the language to fortran.
+# The result is 1 (true) for success, 0 (false) for failure.
+
+proc set_lang_objc {} {
+ if [gdb_test_no_output "set language objective-c"] {
+ return 0
+ }
+ if [gdb_test "show language" ".* source language is \"objective-c\"." \
+ "set language to \"objective-c\""] {
+ return 0
+ }
+ return 1;
+}