4 Test to see if a particular fix should be applied to a header file.
6 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
8 = = = = = = = = = = = = = = = = = = = = = = = = =
12 The routines you write here must work closely with both the fixincl.c
13 and the test_need.c program.
17 1. Every test procedure name must be suffixed with "_test".
18 These routines will be referenced from inclhack.def, sans the suffix.
20 2. Use the "TEST_FOR_FIX_PROC_HEAD()" macro _with_ the "_test" suffix
21 (I cannot use the ## magic from ANSI C) for defining your entry point.
23 3. Put your test name into the FIX_TEST_TABLE
25 4. Do not write anything to stdout. It may be closed.
27 5. Write to stderr only in the event of a reportable error
28 In such an event, call "exit(1)".
30 = = = = = = = = = = = = = = = = = = = = = = = = =
32 This file is part of GNU CC.
34 GNU CC is free software; you can redistribute it and/or modify
35 it under the terms of the GNU General Public License as published by
36 the Free Software Foundation; either version 2, or (at your option)
39 GNU CC is distributed in the hope that it will be useful,
40 but WITHOUT ANY WARRANTY; without even the implied warranty of
41 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42 GNU General Public License for more details.
44 You should have received a copy of the GNU General Public License
45 along with GNU CC; see the file COPYING. If not, write to
46 the Free Software Foundation, 59 Temple Place - Suite 330,
47 Boston, MA 02111-1307, USA. */
51 typedef int apply_fix_p_t; /* Apply Fix Predicate Type */
56 #define SHOULD_APPLY(afp) ((afp) == APPLY_FIX)
57 apply_fix_p_t run_test();
60 const char* test_name;
61 apply_fix_p_t (*test_proc)();
64 #define FIX_TEST_TABLE \
65 _FT_( "double_slash", double_slash_test ) \
66 _FT_( "else_endif_label", else_endif_label_test )
69 #define TEST_FOR_FIX_PROC_HEAD( test ) \
70 static apply_fix_p_t test ( fname, text ) \
75 * Skip over a quoted string. Single quote strings may
76 * contain multiple characters if the first character is
77 * a backslash. Especially a backslash followed by octal digits.
78 * We are not doing a correctness syntax check here.
91 text++; /* skip over whatever character follows */
110 is_cxx_header (fname, text)
114 /* First, check to see if the file is in a C++ directory */
115 if (strstr( fname, "CC/" ) != NULL)
117 if (strstr( fname, "xx/" ) != NULL)
119 if (strstr( fname, "++" ) != NULL)
121 /* Or it might contain the phrase 'extern "C++"' */
122 if (strstr( text, "extern \"C++\"" ) != NULL)
129 TEST_FOR_FIX_PROC_HEAD( double_slash_test )
131 if (is_cxx_header (fname, text) == SKIP_FIX)
134 /* Now look for the comment markers in the text */
141 switch (*text) /* do not advance `text' here */
145 We found a "//" pair in open text.
146 The fix must be applied
151 /* We found a C-style comment. Skip forward to the end */
152 text = strstr( text+1, "*/" );
153 if (text == (char*)NULL)
164 text = skip_quote( ch, text );
173 TEST_FOR_FIX_PROC_HEAD( else_endif_label_test )
175 static int compiled = 0;
176 static const char label_pat[] = "^[ \t]*#[ \t]*(else|endif)";
177 static regex_t label_re;
180 const char* pz_next = (char*)NULL;
182 const char *all_text = text;
185 This routine may be run many times within a single execution.
186 Do the compile once only in that case. In the standalone case,
187 we waste 10 bytes of memory and a test, branch and increment delay. */
191 re_set_syntax (RE_SYNTAX_EGREP);
192 (void)re_compile_pattern (label_pat, sizeof (label_pat)-1,
196 for (;;) /* entire file */
199 See if we need to advance to the next candidate directive
200 If the scanning pointer passes over the end of the directive,
201 then the directive is inside a comment */
204 if (regexec (&label_re, text, 2, match, 0) != 0)
206 pz_next = text + match[0].rm_eo;
210 IF the scan pointer has not reached the directive end, ... */
214 Advance the scanning pointer. If we are at the start
215 of a quoted string or a comment, then skip the entire unit */
225 text = strstr( text+1, "*/" );
226 if (text == (char*)NULL)
235 text = skip_quote( ch, text );
239 } /* if (still shy of directive end) */
242 The scanning pointer (text) has reached the end of the current
243 directive under test, then check for bogons here */
244 for (;;) /* bogon check */
246 char ch = *(pz_next++);
252 It is clean. No bogons on this directive */
254 pz_next = (char*)NULL; /* force a new regex search */
264 Skip escaped newlines. Otherwise, we have a bogon */
265 if (*pz_next != '\n')
273 Skip comments. Otherwise, we have a bogon */
276 pz_next = strstr( pz_next+1, "*/" );
277 if (pz_next == (char*)NULL)
282 else if (*pz_next == '/'
283 && is_cxx_header( fname, all_text ) == SKIP_FIX)
285 pz_next = strchr( pz_next+1, '\n' );
286 if (pz_next == (char*)NULL)
299 } /* for (bogon check loop) */
300 } /* for (entire file) loop */
305 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
307 test for fix selector
309 THIS IS THE ONLY EXPORTED ROUTINE
313 run_test( tname, fname, text )
318 #define _FT_(n,p) { n, p },
319 static test_entry_t test_table[] = { FIX_TEST_TABLE { NULL, NULL }};
321 #define TEST_TABLE_CT ((sizeof(test_table)/sizeof(test_table[0]))-1)
323 int ct = TEST_TABLE_CT;
324 test_entry_t* pte = test_table;
328 if (strcmp( pte->test_name, tname ) == 0)
329 return (*pte->test_proc)( fname, text );
332 fprintf( stderr, "fixincludes error: the `%s' fix test is unknown\n",
337 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
341 This file is both included in fixincl.c and compiled as a separate
342 program for use by the inclhack.sh script.
353 char* fname = *++argv;
354 char* tname = *++argv;
359 return run_test( "No test name provided", NULL, NULL, 0 );
364 buf = load_file_data (fopen (fname, "r"));
366 return run_test( tname, fname, buf );