4 Test to see if a particular fix should be applied to a header file.
6 Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
8 = = = = = = = = = = = = = = = = = = = = = = = = =
12 The routines you write here must work closely with fixincl.c.
16 1. Every test procedure name must be suffixed with "_fix".
17 These routines will be referenced from inclhack.def, sans the suffix.
19 2. Use the "FIX_PROC_HEAD()" macro _with_ the "_fix" suffix
20 (I cannot use the ## magic from ANSI C) for defining your entry point.
22 3. Put your test name into the FIXUP_TABLE
24 4. Do not read anything from stdin. It is closed.
26 5. Write to stderr only in the event of a reportable error
27 In such an event, call "exit(1)".
29 6. You have access to the fixDescList entry for the fix in question.
30 This may be useful, for example, if there are pre-compiled
31 selection expressions stored there.
33 For example, you may do this if you know that the first
34 test contains a useful regex. This is okay because, remember,
35 this code perforce works closely with the inclhack.def fixes!!
37 tFixDesc* pMyDesc = fixDescList + MY_FIX_NAME_FIXIDX;
38 tTestDesc* pTestList = pMyDesc->p_test_desc;
40 regexec (pTestList->p_test_regex, ...)
42 = = = = = = = = = = = = = = = = = = = = = = = = =
44 This file is part of GNU CC.
46 GNU CC is free software; you can redistribute it and/or modify
47 it under the terms of the GNU General Public License as published by
48 the Free Software Foundation; either version 2, or (at your option)
51 GNU CC is distributed in the hope that it will be useful,
52 but WITHOUT ANY WARRANTY; without even the implied warranty of
53 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54 GNU General Public License for more details.
56 You should have received a copy of the GNU General Public License
57 along with GNU CC; see the file COPYING. If not, write to
58 the Free Software Foundation, 59 Temple Place - Suite 330,
59 Boston, MA 02111-1307, USA. */
69 _FT_( "format", format_fix ) \
70 _FT_( "char_macro_use", char_macro_use_fix ) \
71 _FT_( "char_macro_def", char_macro_def_fix ) \
72 _FT_( "machine_name", machine_name_fix )
75 #define FIX_PROC_HEAD( fix ) \
76 static void fix ( filname, text, p_fixd ) \
77 const char* filname; \
83 * Skip over a quoted string. Single quote strings may
84 * contain multiple characters if the first character is
85 * a backslash. Especially a backslash followed by octal digits.
86 * We are not doing a correctness syntax check here.
89 print_quote( q, text )
106 fputc( *(text++), stdout );
125 format_write (format, text, av)
134 for (p = 0; *p; p++) {
145 } else if (c < '0' || c > '9') {
150 str = text + av[c].rm_so;
151 len = av[c].rm_eo - av[c].rm_so;
152 fwrite(str, len, 1, stdout);
156 FIX_PROC_HEAD( format_fix )
158 tSCC zBad[] = "fixincl error: `%s' needs %s c_fix_arg\n";
159 tCC* pz_pat = p_fixd->patch_args[2];
160 tCC* pz_fmt = p_fixd->patch_args[1];
166 * We must have a format
168 if (pz_fmt == (tCC*)NULL) {
169 fprintf( stderr, zBad, p_fixd->fix_name, "replacement-format" );
174 * IF we don't have a search text, then go find the first
175 * regular expression among the tests.
177 if (pz_pat == (tCC*)NULL) {
178 tTestDesc* pTD = p_fixd->p_test_desc;
179 int ct = p_fixd->test_ct;
182 fprintf( stderr, zBad, p_fixd->fix_name, "search-text" );
186 if (pTD->type == TT_EGREP) {
187 pz_pat = pTD->pz_test_text;
196 * Replace every copy of the text we find
198 compile_re (pz_pat, &re, 1, "format search-text", "format_fix" );
199 while (regexec (&re, text, 10, rm, 0) == 0)
204 fwrite( text, rm[0].rm_so, 1, stdout );
205 format_write( pz_fmt, text, rm );
210 * Dump out the rest of the file
212 fputs (text, stdout);
215 /* Scan the input file for all occurrences of text like this:
217 #define TIOCCONS _IO(T, 12)
219 and change them to read like this:
221 #define TIOCCONS _IO('T', 12)
223 which is the required syntax per the C standard. (The definition of
224 _IO also has to be tweaked - see below.) 'IO' is actually whatever you
225 provide in the STR argument. */
227 FIX_PROC_HEAD( char_macro_use_fix )
229 /* This regexp looks for a traditional-syntax #define (# in column 1)
230 of an object-like macro. */
231 static const char pat[] =
232 "^#[ \t]*define[ \t]+[_A-Za-z][_A-Za-z0-9]*[ \t]+";
236 const char *p, *limit;
237 const char *str = p_fixd->patch_args[0];
242 fprintf (stderr, "%s needs macro-name-string argument",
248 compile_re (pat, &re, 1, "macro pattern", "fix_char_macro_uses");
251 regexec (&re, p, 1, rm, 0) == 0;
254 /* p + rm[0].rm_eo is the first character of the macro replacement.
255 Find the end of the macro replacement, and the STR we were
256 sent to look for within the replacement. */
261 limit = strchr (limit + 1, '\n');
265 while (limit[-1] == '\\');
269 if (*p == str[0] && !strncmp (p+1, str+1, len-1))
272 while (++p < limit - len);
273 /* Hit end of line. */
277 /* Found STR on this line. If the macro needs fixing,
278 the next few chars will be whitespace or uppercase,
279 then an open paren, then a single letter. */
280 while ((isspace (*p) || isupper (*p)) && p < limit) p++;
285 if (isalnum (p[1]) || p[1] == '_')
288 /* Splat all preceding text into the output buffer,
289 quote the character at p, then proceed. */
290 fwrite (text, 1, p - text, stdout);
297 fputs (text, stdout);
300 /* Scan the input file for all occurrences of text like this:
302 #define _IO(x, y) ('x'<<16+y)
304 and change them to read like this:
306 #define _IO(x, y) (x<<16+y)
308 which is the required syntax per the C standard. (The uses of _IO
309 also have to be tweaked - see above.) 'IO' is actually whatever
310 you provide in the STR argument. */
311 FIX_PROC_HEAD( char_macro_def_fix )
313 /* This regexp looks for any traditional-syntax #define (# in column 1). */
314 static const char pat[] =
315 "^#[ \t]*define[ \t]+";
319 const char *p, *limit;
320 const char *str = p_fixd->patch_args[0];
326 fprintf (stderr, "%s needs macro-name-string argument",
331 compile_re (pat, &re, 1, "macro pattern", "fix_char_macro_defines");
334 regexec (&re, p, 1, rm, 0) == 0;
337 /* p + rm[0].rm_eo is the first character of the macro name.
338 Find the end of the macro replacement, and the STR we were
339 sent to look for within the name. */
344 limit = strchr (limit + 1, '\n');
348 while (limit[-1] == '\\');
352 if (*p == str[0] && !strncmp (p+1, str+1, len-1))
356 while (isalpha (*p) || isalnum (*p) || *p == '_');
357 /* Hit end of macro name without finding the string. */
361 /* Found STR in this macro name. If the macro needs fixing,
362 there may be a few uppercase letters, then there will be an
363 open paren with _no_ intervening whitespace, and then a
365 while (isupper (*p) && p < limit) p++;
370 if (isalnum (p[1]) || p[1] == '_')
373 /* The character at P is the one to look for in the following
380 if (p[-1] == '\'' && p[0] == arg && p[1] == '\'')
382 /* Remove the quotes from this use of ARG. */
384 fwrite (text, 1, p - text, stdout);
394 fputs (text, stdout);
397 /* Fix for machine name #ifdefs that are not in the namespace reserved
398 by the C standard. They won't be defined if compiling with -ansi,
399 and the headers will break. We go to some trouble to only change
400 #ifdefs where the macro is defined by GCC in non-ansi mode; this
401 minimizes the number of headers touched. */
403 #define SCRATCHSZ 64 /* hopefully long enough */
405 FIX_PROC_HEAD( machine_name_fix )
408 fputs( "The target machine has no needed machine name fixes\n", stderr );
411 const char *line, *base, *limit, *p, *q;
412 regex_t *label_re, *name_re;
413 char scratch[SCRATCHSZ];
416 mn_get_regexps (&label_re, &name_re, "machine_name_fix");
422 regexec (label_re, base, 2, match, 0) == 0;
425 base += match[0].rm_eo;
426 /* We're looking at an #if or #ifdef. Scan forward for the
427 next non-escaped newline. */
432 limit = strchr (limit, '\n');
436 while (limit[-1] == '\\');
438 /* If the 'name_pat' matches in between base and limit, we have
439 a bogon. It is not worth the hassle of excluding comments
440 because comments on #if/#ifdef lines are rare, and strings on
441 such lines are illegal.
443 REG_NOTBOL means 'base' is not at the beginning of a line, which
444 shouldn't matter since the name_re has no ^ anchor, but let's
445 be accurate anyway. */
453 if (regexec (name_re, base, 1, match, REG_NOTBOL))
454 goto done; /* No remaining match in this file */
456 /* Match; is it on the line? */
457 if (match[0].rm_eo > limit - base)
460 p = base + match[0].rm_so;
461 base += match[0].rm_eo;
463 /* One more test: if on the same line we have the same string
464 with the appropriate underscores, then leave it alone.
465 We want exactly two leading and trailing underscores. */
468 len = base - p - ((*base == '_') ? 2 : 1);
473 len = base - p - ((*base == '_') ? 1 : 0);
476 if (len + 4 > SCRATCHSZ)
478 memcpy (&scratch[2], q, len);
480 scratch[len++] = '_';
481 scratch[len++] = '_';
483 for (q = line; q <= limit - len; q++)
484 if (*q == '_' && !strncmp (q, scratch, len))
487 fwrite (text, 1, p - text, stdout);
488 fwrite (scratch, 1, len, stdout);
495 fputs (text, stdout);
499 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
501 test for fix selector
503 THIS IS THE ONLY EXPORTED ROUTINE
507 apply_fix( p_fixd, filname )
511 #define _FT_(n,p) { n, p },
512 static fix_entry_t fix_table[] = { FIXUP_TABLE { NULL, NULL }};
514 #define FIX_TABLE_CT ((sizeof(fix_table)/sizeof(fix_table[0]))-1)
516 tCC* fixname = p_fixd->patch_args[0];
518 int ct = FIX_TABLE_CT;
519 fix_entry_t* pfe = fix_table;
523 if (strcmp (pfe->fix_name, fixname) == 0)
527 fprintf (stderr, "fixincludes error: the `%s' fix is unknown\n",
534 buf = load_file_data (stdin);
535 (*pfe->fix_proc)( filname, buf, p_fixd );