| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- %W%
- Here are changes to GNU's gcc-2.7.2.1 "c-common.c" file that allow strftime
- formats to be checked against what GNU's glibc-1.09.1 "strftime" accepts.
- Formats are also checked for specifications that may or must print only the
- last two digits of years.
- --Arthur David Olson, 1996-09-08
- *** 1.1/c-common.c Sun Sep 8 16:18:09 1996
- --- 1/c-common.c Sun Sep 8 16:18:09 1996
- ***************
- *** 556,561 ****
- --- 556,566 ----
- || !strcmp (IDENTIFIER_POINTER (format_type),
- "__scanf__")))
- is_scan = 1;
- + else if (TREE_CODE (format_type) == IDENTIFIER_NODE
- + && (!strcmp (IDENTIFIER_POINTER (format_type), "strftime")
- + || !strcmp (IDENTIFIER_POINTER (format_type),
- + "__strftime__")))
- + is_scan = 2;
- else
- {
- error ("unrecognized format specifier for `%s'");
- ***************
- *** 725,730 ****
- --- 730,749 ----
- { NULL }
- };
-
- + /*
- + ** Only format characters recognized by glibc 2.0's strftime (as of 1996-08-19) handled.
- + ** XPG4 'E' and 'O' modifier stuff is not handled since glibc strftime does not.
- + ** "2" is used to for formats which MUST do years as only two digits;
- + ** "3" is used for formats which MAY do years as only two digits (depending on locale).
- + */
- +
- + static format_char_info time_char_table[] = {
- + { "Dy", 0, NULL, NULL, NULL, NULL, NULL, "-_2" },
- + { "xc", 0, NULL, NULL, NULL, NULL, NULL, "-_3" },
- + { "aAbhBdeHIkljMmnpRrsSTtUVWwXYzZ", 0, NULL, NULL, NULL, NULL, NULL, "-_" },
- + { NULL }
- + };
- +
- typedef struct function_format_info {
- struct function_format_info *next; /* next structure on the list */
- tree name; /* identifier such as "printf" */
- ***************
- *** 757,771 ****
- record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 1, 0);
- record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 2, 0);
- record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 2, 0);
- }
-
- /* Record information for argument format checking. FUNCTION_IDENT is
- the identifier node for the name of the function to check (its decl
- ! need not exist yet). IS_SCAN is true for scanf-type format checking;
- ! false indicates printf-style format checking. FORMAT_NUM is the number
- of the argument which is the format control string (starting from 1).
- FIRST_ARG_NUM is the number of the first actual argument to check
- ! against teh format string, or zero if no checking is not be done
- (e.g. for varargs such as vfprintf). */
-
- void
- --- 776,792 ----
- record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 1, 0);
- record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 2, 0);
- record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 2, 0);
- + record_function_format (get_identifier ("strftime"), NULL_TREE, 2, 3, 0);
- }
-
- /* Record information for argument format checking. FUNCTION_IDENT is
- the identifier node for the name of the function to check (its decl
- ! need not exist yet).
- ! IS_SCAN is 1 for scanf-type format checking; 2 indicates strftime-style format checking;
- ! 0 indicates printf-style format checking. FORMAT_NUM is the number
- of the argument which is the format control string (starting from 1).
- FIRST_ARG_NUM is the number of the first actual argument to check
- ! against the format string, or zero if no checking is not be done
- (e.g. for varargs such as vfprintf). */
-
- void
- ***************
- *** 928,934 ****
- }
- flag_chars[0] = 0;
- suppressed = wide = precise = FALSE;
- ! if (info->is_scan)
- {
- suppressed = *format_chars == '*';
- if (suppressed)
- --- 949,956 ----
- }
- flag_chars[0] = 0;
- suppressed = wide = precise = FALSE;
- ! aflag = 0;
- ! if (info->is_scan == 1)
- {
- suppressed = *format_chars == '*';
- if (suppressed)
- ***************
- *** 936,942 ****
- while (isdigit (*format_chars))
- ++format_chars;
- }
- ! else
- {
- /* See if we have a number followed by a dollar sign. If we do,
- it is an operand number, so set PARAMS to that operand. */
- --- 958,964 ----
- while (isdigit (*format_chars))
- ++format_chars;
- }
- ! else if (info->is_scan == 0)
- {
- /* See if we have a number followed by a dollar sign. If we do,
- it is an operand number, so set PARAMS to that operand. */
- ***************
- *** 966,972 ****
- }
- }
-
- ! while (*format_chars != 0 && index (" +#0-", *format_chars) != 0)
- {
- if (index (flag_chars, *format_chars) != 0)
- {
- --- 988,994 ----
- }
- }
-
- ! while (*format_chars != 0 && index (" +#0-_", *format_chars) != 0)
- {
- if (index (flag_chars, *format_chars) != 0)
- {
- ***************
- *** 1067,1072 ****
- --- 1089,1096 ----
- }
- }
- }
- + if (info->is_scan != 2)
- + {
- if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'q' ||
- *format_chars == 'L')
- length_char = *format_chars++;
- ***************
- *** 1080,1085 ****
- --- 1104,1110 ----
- aflag = 1;
- format_chars++;
- }
- + }
- if (suppressed && length_char != 0)
- {
- sprintf (message,
- ***************
- *** 1094,1100 ****
- continue;
- }
- format_chars++;
- ! fci = info->is_scan ? scan_char_table : print_char_table;
- while (fci->format_chars != 0
- && index (fci->format_chars, format_char) == 0)
- ++fci;
- --- 1119,1130 ----
- continue;
- }
- format_chars++;
- ! if (info->is_scan == 0)
- ! fci = print_char_table;
- ! else if (info->is_scan == 1)
- ! fci = scan_char_table;
- ! else
- ! fci = time_char_table;
- while (fci->format_chars != 0
- && index (fci->format_chars, format_char) == 0)
- ++fci;
- ***************
- *** 1117,1122 ****
- --- 1147,1164 ----
- format_char);
- warning (message);
- }
- + if (index (fci->flag_chars, '2') != 0)
- + {
- + sprintf (message, "`%c' format only yields last two digits of years",
- + format_char);
- + warning (message);
- + }
- + if (index (fci->flag_chars, '3') != 0)
- + {
- + sprintf (message, "`%c' format may only yield last two digits of years in some locales",
- + format_char);
- + warning (message);
- + }
- if (precise && index (fci->flag_chars, 'p') == 0)
- {
- sprintf (message, "precision used with `%c' format",
- ***************
- *** 1129,1135 ****
- format_char);
- warning (message);
- }
- ! if (info->is_scan && format_char == '[')
- {
- /* Skip over scan set, in case it happens to have '%' in it. */
- if (*format_chars == '^')
- --- 1171,1177 ----
- format_char);
- warning (message);
- }
- ! if (info->is_scan == 1 && format_char == '[')
- {
- /* Skip over scan set, in case it happens to have '%' in it. */
- if (*format_chars == '^')
- ***************
- *** 1182,1188 ****
- case 'q': wanted_type = fci->qlen ? *(fci->qlen) : 0; break;
- case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
- }
- ! if (wanted_type == 0)
- {
- sprintf (message,
- "use of `%c' length character with `%c' type character",
- --- 1224,1230 ----
- case 'q': wanted_type = fci->qlen ? *(fci->qlen) : 0; break;
- case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
- }
- ! if (info->is_scan != 2 && wanted_type == 0)
- {
- sprintf (message,
- "use of `%c' length character with `%c' type character",
|