aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <jsm28@cam.ac.uk>2000-10-12 08:29:01 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2000-10-12 08:29:01 +0100
commit4831bc8477cc012c0be6c8da357537016877cd6a (patch)
tree3f02f20a32fcd6807d309ecbde7b43d4b9122daa
parent2f7026a014b970b927a12661ee9debe5ddb9458f (diff)
downloadgcc-4831bc8477cc012c0be6c8da357537016877cd6a.zip
gcc-4831bc8477cc012c0be6c8da357537016877cd6a.tar.gz
gcc-4831bc8477cc012c0be6c8da357537016877cd6a.tar.bz2
c-common.c (scanf_flag_specs): Add flags ' and I.
* c-common.c (scanf_flag_specs): Add flags ' and I. (strftime_flag_pairs): Disallow any pair of the _, - and 0 flags, or the ^ and # flags together. (scan_char_table): Handle the ' and I flags. (format_types): Add ' and I flags for scanf. testsuite: * gcc.dg/c99-scanf-2.c, gcc.dg/format-ext-2.c: Test ' and I scanf flags. * gcc.dg/format-ext-3.c: Test mutually exclusive pairs of strftime flags. From-SVN: r36842
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/c-common.c39
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/c99-scanf-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/format-ext-2.c40
-rw-r--r--gcc/testsuite/gcc.dg/format-ext-3.c6
6 files changed, 84 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9f7f5a0..80a0937 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2000-10-12 Joseph S. Myers <jsm28@cam.ac.uk>
+ * c-common.c (scanf_flag_specs): Add flags ' and I.
+ (strftime_flag_pairs): Disallow any pair of the _, - and 0 flags,
+ or the ^ and # flags together.
+ (scan_char_table): Handle the ' and I flags.
+ (format_types): Add ' and I flags for scanf.
+
+2000-10-12 Joseph S. Myers <jsm28@cam.ac.uk>
+
* c-common.c (print_char_table): Use the unpromoted type for
lengths "h" and "hh" with conversions dioxXu.
(check_format_types): Apply the default argument promotions where
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 0e77cdd..07384f8 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1507,10 +1507,12 @@ static const format_flag_pair printf_flag_pairs[] =
static const format_flag_spec scanf_flag_specs[] =
{
- { '*', 0, N_("assignment suppression"), N_("assignment suppression"), STD_C89 },
- { 'a', 0, N_("`a' flag"), N_("the `a' scanf flag"), STD_EXT },
- { 'w', 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
- { 'L', 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
+ { '*', 0, N_("assignment suppression"), N_("assignment suppression"), STD_C89 },
+ { 'a', 0, N_("`a' flag"), N_("the `a' scanf flag"), STD_EXT },
+ { 'w', 0, N_("field width"), N_("field width in scanf format"), STD_C89 },
+ { 'L', 0, N_("length modifier"), N_("length modifier in scanf format"), STD_C89 },
+ { '\'', 0, N_("`'' flag"), N_("the `'' scanf flag"), STD_EXT },
+ { 'I', 0, N_("`I' flag"), N_("the `I' scanf flag"), STD_EXT },
{ 0, 0, NULL, NULL, 0 }
};
@@ -1540,6 +1542,10 @@ static const format_flag_spec strftime_flag_specs[] =
static const format_flag_pair strftime_flag_pairs[] =
{
{ 'E', 'O', 0, 0 },
+ { '_', '-', 0, 0 },
+ { '_', '0', 0, 0 },
+ { '-', '0', 0, 0 },
+ { '^', '#', 0, 0 },
{ 0, 0, 0, 0 }
};
@@ -1626,19 +1632,20 @@ static const format_char_info print_char_table[] =
static const format_char_info scan_char_table[] =
{
/* C89 conversion specifiers. */
- { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "*w", "W" },
- { "ouxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T99_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W" },
- { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w", "W" },
- { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW" },
- { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW" },
- { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[" },
- { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W" },
- { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
+ { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "*w'I", "W" },
+ { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T99_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w'I", "W" },
+ { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T99_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "*w", "W" },
+ { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W" },
+ { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "cW" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW" },
+ { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "cW[" },
+ { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W" },
+ { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T99_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
/* C99 conversion specifiers. */
- { "FaA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "*w", "W" },
+ { "FaA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "*w'", "W" },
/* X/Open conversion specifiers. */
- { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W" },
- { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W" },
+ { "C", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W" },
+ { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*aw", "W" },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL }
};
@@ -1678,7 +1685,7 @@ static const format_kind_info format_types[] =
FMT_FLAG_ARG_CONVERT, 'w', 'p', 0, 'L',
&integer_type_node, &integer_type_node
},
- { "scanf", scanf_length_specs, scan_char_table, "*", NULL,
+ { "scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
scanf_flag_specs, scanf_flag_pairs,
FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE, 'w', 0, '*', 'L',
NULL, NULL
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c240085..5081eed 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2000-10-12 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * gcc.dg/c99-scanf-2.c, gcc.dg/format-ext-2.c: Test ' and I
+ scanf flags.
+ * gcc.dg/format-ext-3.c: Test mutually exclusive pairs of strftime
+ flags.
+
2000-10-11 Joseph S. Myers <jsm28@cam.ac.uk>
* gcc.dg/sequence-pt-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/c99-scanf-2.c b/gcc/testsuite/gcc.dg/c99-scanf-2.c
index c4184c1..a740a60 100644
--- a/gcc/testsuite/gcc.dg/c99-scanf-2.c
+++ b/gcc/testsuite/gcc.dg/c99-scanf-2.c
@@ -22,6 +22,7 @@ foo (int *ip, long long int *llp, wchar_t *ls)
scanf ("%S", ls); /* { dg-warning "C" "scanf %S" } */
/* The use of operand number $ formats is an X/Open extension. */
scanf ("%1$d", ip); /* { dg-warning "C" "scanf $ format" } */
- /* glibc also supports flags ' and I on scanf formats, but GCC
- doesn't yet. */
+ /* glibc also supports flags ' and I on scanf formats as an extension. */
+ scanf ("%'d", ip); /* { dg-warning "C" "scanf ' flag" } */
+ scanf ("%Id", ip); /* { dg-warning "C" "scanf I flag" } */
}
diff --git a/gcc/testsuite/gcc.dg/format-ext-2.c b/gcc/testsuite/gcc.dg/format-ext-2.c
index f325a6d..68c1b03 100644
--- a/gcc/testsuite/gcc.dg/format-ext-2.c
+++ b/gcc/testsuite/gcc.dg/format-ext-2.c
@@ -15,7 +15,8 @@ extern int scanf (const char *, ...);
void
foo (quad_t *qp, u_quad_t *uqp, quad_t *qn, long long int *llp,
- unsigned long long int *ullp, float *fp, char *s, void **pp, wchar_t *ls)
+ unsigned long long int *ullp, float *fp, char *s, void **pp, wchar_t *ls,
+ int *ip, unsigned int *up)
{
/* As an extension, GCC allows the BSD length "q" for integer formats.
This is largely obsoleted in C99 by %j, %ll and SCNd64.
@@ -40,6 +41,39 @@ foo (quad_t *qp, u_quad_t *uqp, quad_t *qn, long long int *llp,
This should be considered deprecated.
*/
scanf ("%Ld%Li%Lo%Lu%Lx%LX", llp, llp, ullp, ullp, ullp, ullp);
- /* glibc also supports flags ' and I on scanf formats, but GCC
- doesn't yet. */
+ /* glibc also supports flags ' and I on scanf formats. The ' flag applies
+ to all formats scanning decimal values; the I flag only to decimal integer
+ formats.
+ */
+ scanf ("%'d%'i%'u%'a%'A%'e%'E%'f%'F%'g%'G", ip, ip, up, fp, fp, fp, fp,
+ fp, fp, fp, fp);
+ scanf ("%'o", up); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'x", up); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'X", up); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'n", ip); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'s", s); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'[abc]", s); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'c", s); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'p", pp); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'C", ls); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%'S", ls); /* { dg-warning "flag" "bad use of ' flag" } */
+ scanf ("%Id%Ii%Iu", ip, ip, up);
+ scanf ("%Ia", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%IA", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%Ie", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%IE", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%If", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%IF", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%Ig", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%IG", fp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%Io", up); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%Ix", up); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%IX", up); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%In", ip); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%Is", s); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%I[abc]", s); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%Ic", s); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%Ip", pp); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%IC", ls); /* { dg-warning "flag" "bad use of I flag" } */
+ scanf ("%IS", ls); /* { dg-warning "flag" "bad use of I flag" } */
}
diff --git a/gcc/testsuite/gcc.dg/format-ext-3.c b/gcc/testsuite/gcc.dg/format-ext-3.c
index 26d1324..ea9f2e0 100644
--- a/gcc/testsuite/gcc.dg/format-ext-3.c
+++ b/gcc/testsuite/gcc.dg/format-ext-3.c
@@ -211,4 +211,10 @@ foo (char *s, size_t m, const struct tm *tp)
*/
strftime (s, m, "%OC%Og%OG%Oj%OY%Oz%Ok%Ol%Os", tp); /* { dg-warning "only last 2" "2-digit year" } */
strftime (s, m, "%OP", tp); /* { dg-warning "flag|modifier" "bad %OP" } */
+ /* The "-", "_" and "0" flags are mutually exclusive. */
+ strftime (s, m, "%-_5C", tp); /* { dg-warning "flag" "bad %-_" } */
+ strftime (s, m, "%-05C", tp); /* { dg-warning "flag" "bad %-0" } */
+ strftime (s, m, "%_05C", tp); /* { dg-warning "flag" "bad %_0" } */
+ /* The "#" and "^" flags are mutually exclusive. */
+ strftime (s, m, "%^#a", tp); /* { dg-warning "flag" "bad %^#" } */
}