gccdiffs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. %W%
  2. Here are changes to GNU's gcc-2.7.2.1 "c-common.c" file that allow strftime
  3. formats to be checked against what GNU's glibc-1.09.1 "strftime" accepts.
  4. Formats are also checked for specifications that may or must print only the
  5. last two digits of years.
  6. --Arthur David Olson, 1996-09-08
  7. *** 1.1/c-common.c Sun Sep 8 16:18:09 1996
  8. --- 1/c-common.c Sun Sep 8 16:18:09 1996
  9. ***************
  10. *** 556,561 ****
  11. --- 556,566 ----
  12. || !strcmp (IDENTIFIER_POINTER (format_type),
  13. "__scanf__")))
  14. is_scan = 1;
  15. + else if (TREE_CODE (format_type) == IDENTIFIER_NODE
  16. + && (!strcmp (IDENTIFIER_POINTER (format_type), "strftime")
  17. + || !strcmp (IDENTIFIER_POINTER (format_type),
  18. + "__strftime__")))
  19. + is_scan = 2;
  20. else
  21. {
  22. error ("unrecognized format specifier for `%s'");
  23. ***************
  24. *** 725,730 ****
  25. --- 730,749 ----
  26. { NULL }
  27. };
  28. + /*
  29. + ** Only format characters recognized by glibc 2.0's strftime (as of 1996-08-19) handled.
  30. + ** XPG4 'E' and 'O' modifier stuff is not handled since glibc strftime does not.
  31. + ** "2" is used to for formats which MUST do years as only two digits;
  32. + ** "3" is used for formats which MAY do years as only two digits (depending on locale).
  33. + */
  34. +
  35. + static format_char_info time_char_table[] = {
  36. + { "Dy", 0, NULL, NULL, NULL, NULL, NULL, "-_2" },
  37. + { "xc", 0, NULL, NULL, NULL, NULL, NULL, "-_3" },
  38. + { "aAbhBdeHIkljMmnpRrsSTtUVWwXYzZ", 0, NULL, NULL, NULL, NULL, NULL, "-_" },
  39. + { NULL }
  40. + };
  41. +
  42. typedef struct function_format_info {
  43. struct function_format_info *next; /* next structure on the list */
  44. tree name; /* identifier such as "printf" */
  45. ***************
  46. *** 757,771 ****
  47. record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 1, 0);
  48. record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 2, 0);
  49. record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 2, 0);
  50. }
  51. /* Record information for argument format checking. FUNCTION_IDENT is
  52. the identifier node for the name of the function to check (its decl
  53. ! need not exist yet). IS_SCAN is true for scanf-type format checking;
  54. ! false indicates printf-style format checking. FORMAT_NUM is the number
  55. of the argument which is the format control string (starting from 1).
  56. FIRST_ARG_NUM is the number of the first actual argument to check
  57. ! against teh format string, or zero if no checking is not be done
  58. (e.g. for varargs such as vfprintf). */
  59. void
  60. --- 776,792 ----
  61. record_function_format (get_identifier ("vprintf"), NULL_TREE, 0, 1, 0);
  62. record_function_format (get_identifier ("vfprintf"), NULL_TREE, 0, 2, 0);
  63. record_function_format (get_identifier ("vsprintf"), NULL_TREE, 0, 2, 0);
  64. + record_function_format (get_identifier ("strftime"), NULL_TREE, 2, 3, 0);
  65. }
  66. /* Record information for argument format checking. FUNCTION_IDENT is
  67. the identifier node for the name of the function to check (its decl
  68. ! need not exist yet).
  69. ! IS_SCAN is 1 for scanf-type format checking; 2 indicates strftime-style format checking;
  70. ! 0 indicates printf-style format checking. FORMAT_NUM is the number
  71. of the argument which is the format control string (starting from 1).
  72. FIRST_ARG_NUM is the number of the first actual argument to check
  73. ! against the format string, or zero if no checking is not be done
  74. (e.g. for varargs such as vfprintf). */
  75. void
  76. ***************
  77. *** 928,934 ****
  78. }
  79. flag_chars[0] = 0;
  80. suppressed = wide = precise = FALSE;
  81. ! if (info->is_scan)
  82. {
  83. suppressed = *format_chars == '*';
  84. if (suppressed)
  85. --- 949,956 ----
  86. }
  87. flag_chars[0] = 0;
  88. suppressed = wide = precise = FALSE;
  89. ! aflag = 0;
  90. ! if (info->is_scan == 1)
  91. {
  92. suppressed = *format_chars == '*';
  93. if (suppressed)
  94. ***************
  95. *** 936,942 ****
  96. while (isdigit (*format_chars))
  97. ++format_chars;
  98. }
  99. ! else
  100. {
  101. /* See if we have a number followed by a dollar sign. If we do,
  102. it is an operand number, so set PARAMS to that operand. */
  103. --- 958,964 ----
  104. while (isdigit (*format_chars))
  105. ++format_chars;
  106. }
  107. ! else if (info->is_scan == 0)
  108. {
  109. /* See if we have a number followed by a dollar sign. If we do,
  110. it is an operand number, so set PARAMS to that operand. */
  111. ***************
  112. *** 966,972 ****
  113. }
  114. }
  115. ! while (*format_chars != 0 && index (" +#0-", *format_chars) != 0)
  116. {
  117. if (index (flag_chars, *format_chars) != 0)
  118. {
  119. --- 988,994 ----
  120. }
  121. }
  122. ! while (*format_chars != 0 && index (" +#0-_", *format_chars) != 0)
  123. {
  124. if (index (flag_chars, *format_chars) != 0)
  125. {
  126. ***************
  127. *** 1067,1072 ****
  128. --- 1089,1096 ----
  129. }
  130. }
  131. }
  132. + if (info->is_scan != 2)
  133. + {
  134. if (*format_chars == 'h' || *format_chars == 'l' || *format_chars == 'q' ||
  135. *format_chars == 'L')
  136. length_char = *format_chars++;
  137. ***************
  138. *** 1080,1085 ****
  139. --- 1104,1110 ----
  140. aflag = 1;
  141. format_chars++;
  142. }
  143. + }
  144. if (suppressed && length_char != 0)
  145. {
  146. sprintf (message,
  147. ***************
  148. *** 1094,1100 ****
  149. continue;
  150. }
  151. format_chars++;
  152. ! fci = info->is_scan ? scan_char_table : print_char_table;
  153. while (fci->format_chars != 0
  154. && index (fci->format_chars, format_char) == 0)
  155. ++fci;
  156. --- 1119,1130 ----
  157. continue;
  158. }
  159. format_chars++;
  160. ! if (info->is_scan == 0)
  161. ! fci = print_char_table;
  162. ! else if (info->is_scan == 1)
  163. ! fci = scan_char_table;
  164. ! else
  165. ! fci = time_char_table;
  166. while (fci->format_chars != 0
  167. && index (fci->format_chars, format_char) == 0)
  168. ++fci;
  169. ***************
  170. *** 1117,1122 ****
  171. --- 1147,1164 ----
  172. format_char);
  173. warning (message);
  174. }
  175. + if (index (fci->flag_chars, '2') != 0)
  176. + {
  177. + sprintf (message, "`%c' format only yields last two digits of years",
  178. + format_char);
  179. + warning (message);
  180. + }
  181. + if (index (fci->flag_chars, '3') != 0)
  182. + {
  183. + sprintf (message, "`%c' format may only yield last two digits of years in some locales",
  184. + format_char);
  185. + warning (message);
  186. + }
  187. if (precise && index (fci->flag_chars, 'p') == 0)
  188. {
  189. sprintf (message, "precision used with `%c' format",
  190. ***************
  191. *** 1129,1135 ****
  192. format_char);
  193. warning (message);
  194. }
  195. ! if (info->is_scan && format_char == '[')
  196. {
  197. /* Skip over scan set, in case it happens to have '%' in it. */
  198. if (*format_chars == '^')
  199. --- 1171,1177 ----
  200. format_char);
  201. warning (message);
  202. }
  203. ! if (info->is_scan == 1 && format_char == '[')
  204. {
  205. /* Skip over scan set, in case it happens to have '%' in it. */
  206. if (*format_chars == '^')
  207. ***************
  208. *** 1182,1188 ****
  209. case 'q': wanted_type = fci->qlen ? *(fci->qlen) : 0; break;
  210. case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
  211. }
  212. ! if (wanted_type == 0)
  213. {
  214. sprintf (message,
  215. "use of `%c' length character with `%c' type character",
  216. --- 1224,1230 ----
  217. case 'q': wanted_type = fci->qlen ? *(fci->qlen) : 0; break;
  218. case 'L': wanted_type = fci->bigllen ? *(fci->bigllen) : 0; break;
  219. }
  220. ! if (info->is_scan != 2 && wanted_type == 0)
  221. {
  222. sprintf (message,
  223. "use of `%c' length character with `%c' type character",