mirror of
https://frontier.innolan.net/rainlance/amiga-tz.git
synced 2025-11-22 09:13:55 +00:00
234 lines
7.3 KiB
Plaintext
234 lines
7.3 KiB
Plaintext
%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",
|