]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/fixinc/fixtests.c
anon.java, [...]: New files.
[thirdparty/gcc.git] / gcc / fixinc / fixtests.c
CommitLineData
5abc1f74
BK
1
2/*
3
4 Test to see if a particular fix should be applied to a header file.
5
b51207a4 6 Copyright (C) 1997-1999, 2000 Free Software Foundation, Inc.
5abc1f74
BK
7
8= = = = = = = = = = = = = = = = = = = = = = = = =
9
10NOTE TO DEVELOPERS
11
12The routines you write here must work closely with both the fixincl.c
13and the test_need.c program.
14
15Here are the rules:
16
171. Every test procedure name must be suffixed with "_test".
18 These routines will be referenced from inclhack.def, sans the suffix.
19
202. 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.
22
233. Put your test name into the FIX_TEST_TABLE
24
254. Do not write anything to stdout. It may be closed.
26
275. Write to stderr only in the event of a reportable error
28 In such an event, call "exit(1)".
29
30= = = = = = = = = = = = = = = = = = = = = = = = =
31
32This file is part of GNU CC.
33
34GNU CC is free software; you can redistribute it and/or modify
35it under the terms of the GNU General Public License as published by
36the Free Software Foundation; either version 2, or (at your option)
37any later version.
38
39GNU CC is distributed in the hope that it will be useful,
40but WITHOUT ANY WARRANTY; without even the implied warranty of
41MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42GNU General Public License for more details.
43
44You should have received a copy of the GNU General Public License
45along with GNU CC; see the file COPYING. If not, write to
46the Free Software Foundation, 59 Temple Place - Suite 330,
47Boston, MA 02111-1307, USA. */
48
49#include "fixlib.h"
50
5abc1f74
BK
51#define SHOULD_APPLY(afp) ((afp) == APPLY_FIX)
52apply_fix_p_t run_test();
53
54typedef struct {
87ad679b 55 tCC* test_name;
5abc1f74
BK
56 apply_fix_p_t (*test_proc)();
57} test_entry_t;
58
59#define FIX_TEST_TABLE \
8f9ca912
BK
60 _FT_( "double_slash", double_slash_test ) \
61 _FT_( "else_endif_label", else_endif_label_test )
5abc1f74
BK
62
63
64#define TEST_FOR_FIX_PROC_HEAD( test ) \
65static apply_fix_p_t test ( fname, text ) \
87ad679b
BK
66 tCC* fname; \
67 tCC* text;
5abc1f74
BK
68
69/*
70 * Skip over a quoted string. Single quote strings may
71 * contain multiple characters if the first character is
72 * a backslash. Especially a backslash followed by octal digits.
73 * We are not doing a correctness syntax check here.
74 */
87ad679b 75tSCC*
5abc1f74
BK
76skip_quote( q, text )
77 char q;
78 char* text;
79{
80 for (;;)
81 {
82 char ch = *(text++);
83 switch (ch)
84 {
85 case '\\':
86 text++; /* skip over whatever character follows */
87 break;
88
89 case '"':
90 case '\'':
91 if (ch != q)
92 break;
93 /*FALLTHROUGH*/
94
95 case '\n':
96 case NUL:
97 goto skip_done;
98 }
99 } skip_done:;
100
101 return text;
102}
103
d7eb5a45
ZW
104
105TEST_FOR_FIX_PROC_HEAD( double_slash_test )
106{
87ad679b 107 if (is_cxx_header (fname, text))
d7eb5a45
ZW
108 return SKIP_FIX;
109
5abc1f74
BK
110 /* Now look for the comment markers in the text */
111 for (;;)
112 {
113 char ch = *(text++);
114 switch (ch)
115 {
116 case '/':
117 switch (*text) /* do not advance `text' here */
118 {
119 case '/':
120 /*
121 We found a "//" pair in open text.
122 The fix must be applied
123 */
124 return APPLY_FIX;
125
126 case '*':
127 /* We found a C-style comment. Skip forward to the end */
128 text = strstr( text+1, "*/" );
129 if (text == (char*)NULL)
130 goto test_done;
131 text += 2;
132 }
133 break;
134
135 case NUL:
136 goto test_done;
137
138 case '"':
139 case '\'':
140 text = skip_quote( ch, text );
141 }
142
143 } test_done:;
144
145 return SKIP_FIX;
146}
147
8f9ca912
BK
148
149TEST_FOR_FIX_PROC_HEAD( else_endif_label_test )
150{
151 static int compiled = 0;
87ad679b 152 tSCC label_pat[] = "^[ \t]*#[ \t]*(else|endif)";
8f9ca912
BK
153 static regex_t label_re;
154
155 char ch;
87ad679b 156 tCC* pz_next = (char*)NULL;
8f9ca912 157 regmatch_t match[2];
87ad679b 158 t_bool file_is_cxx = is_cxx_header( fname, text );
8f9ca912
BK
159
160 /*
161 This routine may be run many times within a single execution.
162 Do the compile once only in that case. In the standalone case,
163 we waste 10 bytes of memory and a test, branch and increment delay. */
164 if (! compiled)
165 {
166 compiled++;
b51207a4
ZW
167 compile_re (label_pat, &label_re, 1,
168 "label pattern", "else_endif_label_test");
8f9ca912
BK
169 }
170
171 for (;;) /* entire file */
172 {
173 /*
174 See if we need to advance to the next candidate directive
175 If the scanning pointer passes over the end of the directive,
176 then the directive is inside a comment */
177 if (pz_next < text)
178 {
179 if (regexec (&label_re, text, 2, match, 0) != 0)
180 break;
181 pz_next = text + match[0].rm_eo;
182 }
183
184 /*
185 IF the scan pointer has not reached the directive end, ... */
186 if (pz_next > text)
187 {
188 /*
189 Advance the scanning pointer. If we are at the start
190 of a quoted string or a comment, then skip the entire unit */
191 ch = *(text++);
192
193 switch (ch)
194 {
195 case '/':
196 /*
197 Skip comments */
198 if (*text == '*')
199 {
200 text = strstr( text+1, "*/" );
201 if (text == (char*)NULL)
202 return SKIP_FIX;
203 text += 2;
204 continue;
205 }
206 break;
207
208 case '"':
209 case '\'':
210 text = skip_quote( ch, text );
211 break;
212 } /* switch (ch) */
213 continue;
214 } /* if (still shy of directive end) */
215
216 /*
217 The scanning pointer (text) has reached the end of the current
218 directive under test, then check for bogons here */
219 for (;;) /* bogon check */
220 {
221 char ch = *(pz_next++);
222 if (isspace (ch))
223 {
224 if (ch == '\n')
225 {
226 /*
227 It is clean. No bogons on this directive */
228 text = pz_next;
229 pz_next = (char*)NULL; /* force a new regex search */
230 break;
231 }
232 continue;
233 }
234
235 switch (ch)
236 {
237 case '\\':
238 /*
239 Skip escaped newlines. Otherwise, we have a bogon */
240 if (*pz_next != '\n')
241 return APPLY_FIX;
242
243 pz_next++;
244 break;
245
246 case '/':
247 /*
248 Skip comments. Otherwise, we have a bogon */
87ad679b 249 switch (*pz_next)
8f9ca912 250 {
87ad679b
BK
251 case '/':
252 /* IF we found a "//" in a C header, THEN fix it. */
253 if (! file_is_cxx)
254 return APPLY_FIX;
255
256 /* C++ header. Skip to newline and continue. */
257 pz_next = strchr( pz_next+1, '\n' );
258 if (pz_next == (char*)NULL)
259 return SKIP_FIX;
260 pz_next++;
261 break;
262
263 case '*':
264 /* A comment for either C++ or C. Skip over it. */
8f9ca912
BK
265 pz_next = strstr( pz_next+1, "*/" );
266 if (pz_next == (char*)NULL)
267 return SKIP_FIX;
268 pz_next += 2;
269 break;
87ad679b
BK
270
271 default:
272 /* a '/' followed by other junk. */
273 return APPLY_FIX;
8f9ca912 274 }
87ad679b 275 break; /* a C or C++ comment */
8f9ca912
BK
276
277 default:
278 /*
279 GOTTA BE A BOGON */
280 return APPLY_FIX;
281 } /* switch (ch) */
282 } /* for (bogon check loop) */
283 } /* for (entire file) loop */
284
285 return SKIP_FIX;
286}
287
5abc1f74
BK
288/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
289
290 test for fix selector
291
292 THIS IS THE ONLY EXPORTED ROUTINE
293
294*/
295apply_fix_p_t
296run_test( tname, fname, text )
87ad679b
BK
297 tCC* tname;
298 tCC* fname;
299 tCC* text;
5abc1f74 300{
99d525c9 301#define _FT_(n,p) { n, p },
5abc1f74 302 static test_entry_t test_table[] = { FIX_TEST_TABLE { NULL, NULL }};
99d525c9
PDM
303#undef _FT_
304#define TEST_TABLE_CT ((sizeof(test_table)/sizeof(test_table[0]))-1)
5abc1f74
BK
305
306 int ct = TEST_TABLE_CT;
307 test_entry_t* pte = test_table;
308
309 do
310 {
311 if (strcmp( pte->test_name, tname ) == 0)
312 return (*pte->test_proc)( fname, text );
8f9ca912 313 pte++;
5abc1f74
BK
314 } while (--ct > 0);
315 fprintf( stderr, "fixincludes error: the `%s' fix test is unknown\n",
316 tname );
317 exit( 3 );
318}
319
320/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
321
322 MAIN ROUTINE
323
324 This file is both included in fixincl.c and compiled as a separate
325 program for use by the inclhack.sh script.
326
327*/
328
329#ifdef MAIN
330
331int
332main( argc, argv )
333 int argc;
334 char** argv;
335{
336 char* fname = *++argv;
337 char* tname = *++argv;
338 char* buf;
5abc1f74
BK
339
340 if (argc != 3)
341 return run_test( "No test name provided", NULL, NULL, 0 );
342
343 fclose( stdin );
344 fclose( stdout );
345
346 buf = load_file_data (fopen (fname, "r"));
347
348 return run_test( tname, fname, buf );
349}
350
351#endif