1*404b540aSrobert
2*404b540aSrobert /*
3*404b540aSrobert
4*404b540aSrobert Test to see if a particular fix should be applied to a header file.
5*404b540aSrobert
6*404b540aSrobert Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
7*404b540aSrobert
8*404b540aSrobert = = = = = = = = = = = = = = = = = = = = = = = = =
9*404b540aSrobert
10*404b540aSrobert NOTE TO DEVELOPERS
11*404b540aSrobert
12*404b540aSrobert The routines you write here must work closely with fixincl.c.
13*404b540aSrobert
14*404b540aSrobert Here are the rules:
15*404b540aSrobert
16*404b540aSrobert 1. Every test procedure name must be suffixed with "_test".
17*404b540aSrobert These routines will be referenced from inclhack.def, sans the suffix.
18*404b540aSrobert
19*404b540aSrobert 2. Use the "TEST_FOR_FIX_PROC_HEAD()" macro _with_ the "_test" suffix
20*404b540aSrobert (I cannot use the ## magic from ANSI C) for defining your entry point.
21*404b540aSrobert
22*404b540aSrobert 3. Put your test name into the FIX_TEST_TABLE
23*404b540aSrobert
24*404b540aSrobert 4. Do not write anything to stdout. It may be closed.
25*404b540aSrobert
26*404b540aSrobert 5. Write to stderr only in the event of a reportable error
27*404b540aSrobert In such an event, call "exit(1)".
28*404b540aSrobert
29*404b540aSrobert = = = = = = = = = = = = = = = = = = = = = = = = =
30*404b540aSrobert
31*404b540aSrobert This file is part of GCC.
32*404b540aSrobert
33*404b540aSrobert GCC is free software; you can redistribute it and/or modify
34*404b540aSrobert it under the terms of the GNU General Public License as published by
35*404b540aSrobert the Free Software Foundation; either version 2, or (at your option)
36*404b540aSrobert any later version.
37*404b540aSrobert
38*404b540aSrobert GCC is distributed in the hope that it will be useful,
39*404b540aSrobert but WITHOUT ANY WARRANTY; without even the implied warranty of
40*404b540aSrobert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41*404b540aSrobert GNU General Public License for more details.
42*404b540aSrobert
43*404b540aSrobert You should have received a copy of the GNU General Public License
44*404b540aSrobert along with GCC; see the file COPYING. If not, write to
45*404b540aSrobert the Free Software Foundation, 51 Franklin Street, Fifth Floor,
46*404b540aSrobert Boston, MA 02110-1301, USA. */
47*404b540aSrobert
48*404b540aSrobert #include "fixlib.h"
49*404b540aSrobert
50*404b540aSrobert #define _ENV_(v,m,n,t) extern tCC* v;
51*404b540aSrobert ENV_TABLE
52*404b540aSrobert #undef _ENV_
53*404b540aSrobert
54*404b540aSrobert typedef apply_fix_p_t t_test_proc ( tCC* file, tCC* text );
55*404b540aSrobert
56*404b540aSrobert typedef struct {
57*404b540aSrobert tCC* test_name;
58*404b540aSrobert t_test_proc* test_proc;
59*404b540aSrobert } test_entry_t;
60*404b540aSrobert
61*404b540aSrobert #define FIX_TEST_TABLE \
62*404b540aSrobert _FT_( "machine_name", machine_name_test ) \
63*404b540aSrobert _FT_( "stdc_0_in_system_headers", stdc_0_in_system_headers_test )
64*404b540aSrobert
65*404b540aSrobert #define TEST_FOR_FIX_PROC_HEAD( test ) \
66*404b540aSrobert static apply_fix_p_t test ( tCC* fname ATTRIBUTE_UNUSED, \
67*404b540aSrobert tCC* text ATTRIBUTE_UNUSED )
68*404b540aSrobert
TEST_FOR_FIX_PROC_HEAD(machine_name_test)69*404b540aSrobert TEST_FOR_FIX_PROC_HEAD( machine_name_test )
70*404b540aSrobert {
71*404b540aSrobert regex_t *label_re, *name_re;
72*404b540aSrobert regmatch_t match[2];
73*404b540aSrobert tCC *base, *limit;
74*404b540aSrobert IGNORE_ARG(fname);
75*404b540aSrobert
76*404b540aSrobert if (!mn_get_regexps (&label_re, &name_re, "machine_name_test"))
77*404b540aSrobert return SKIP_FIX;
78*404b540aSrobert
79*404b540aSrobert for (base = text;
80*404b540aSrobert xregexec (label_re, base, 2, match, 0) == 0;
81*404b540aSrobert base = limit)
82*404b540aSrobert {
83*404b540aSrobert base += match[0].rm_eo;
84*404b540aSrobert /* We're looking at an #if or #ifdef. Scan forward for the
85*404b540aSrobert next non-escaped newline. */
86*404b540aSrobert limit = base;
87*404b540aSrobert do
88*404b540aSrobert {
89*404b540aSrobert limit++;
90*404b540aSrobert limit = strchr (limit, '\n');
91*404b540aSrobert if (!limit)
92*404b540aSrobert return SKIP_FIX;
93*404b540aSrobert }
94*404b540aSrobert while (limit[-1] == '\\');
95*404b540aSrobert
96*404b540aSrobert /* If the 'name_pat' matches in between base and limit, we have
97*404b540aSrobert a bogon. It is not worth the hassle of excluding comments,
98*404b540aSrobert because comments on #if/#ifdef/#ifndef lines are rare,
99*404b540aSrobert and strings on such lines are illegal.
100*404b540aSrobert
101*404b540aSrobert REG_NOTBOL means 'base' is not at the beginning of a line, which
102*404b540aSrobert shouldn't matter since the name_re has no ^ anchor, but let's
103*404b540aSrobert be accurate anyway. */
104*404b540aSrobert
105*404b540aSrobert if (xregexec (name_re, base, 1, match, REG_NOTBOL))
106*404b540aSrobert return SKIP_FIX; /* No match in file - no fix needed */
107*404b540aSrobert
108*404b540aSrobert /* Match; is it on the line? */
109*404b540aSrobert if (match[0].rm_eo <= limit - base)
110*404b540aSrobert return APPLY_FIX; /* Yup */
111*404b540aSrobert
112*404b540aSrobert /* Otherwise, keep looking... */
113*404b540aSrobert }
114*404b540aSrobert return SKIP_FIX;
115*404b540aSrobert }
116*404b540aSrobert
117*404b540aSrobert
TEST_FOR_FIX_PROC_HEAD(stdc_0_in_system_headers_test)118*404b540aSrobert TEST_FOR_FIX_PROC_HEAD( stdc_0_in_system_headers_test )
119*404b540aSrobert {
120*404b540aSrobert #ifdef STDC_0_IN_SYSTEM_HEADERS
121*404b540aSrobert return (pz_machine == NULL) ? APPLY_FIX : SKIP_FIX;
122*404b540aSrobert #else
123*404b540aSrobert return APPLY_FIX;
124*404b540aSrobert #endif
125*404b540aSrobert }
126*404b540aSrobert
127*404b540aSrobert
128*404b540aSrobert /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
129*404b540aSrobert
130*404b540aSrobert test for fix selector
131*404b540aSrobert
132*404b540aSrobert THIS IS THE ONLY EXPORTED ROUTINE
133*404b540aSrobert
134*404b540aSrobert */
135*404b540aSrobert apply_fix_p_t
run_test(tCC * tname,tCC * fname,tCC * text)136*404b540aSrobert run_test( tCC* tname, tCC* fname, tCC* text )
137*404b540aSrobert {
138*404b540aSrobert #define _FT_(n,p) { n, p },
139*404b540aSrobert static test_entry_t test_table[] = { FIX_TEST_TABLE { NULL, NULL }};
140*404b540aSrobert #undef _FT_
141*404b540aSrobert #define TEST_TABLE_CT (ARRAY_SIZE (test_table)-1)
142*404b540aSrobert
143*404b540aSrobert int ct = TEST_TABLE_CT;
144*404b540aSrobert test_entry_t* pte = test_table;
145*404b540aSrobert
146*404b540aSrobert do
147*404b540aSrobert {
148*404b540aSrobert if (strcmp( pte->test_name, tname ) == 0)
149*404b540aSrobert return (*pte->test_proc)( fname, text );
150*404b540aSrobert pte++;
151*404b540aSrobert } while (--ct > 0);
152*404b540aSrobert fprintf( stderr, "fixincludes error: the `%s' fix test is unknown\n",
153*404b540aSrobert tname );
154*404b540aSrobert exit( 3 );
155*404b540aSrobert }
156