1*404b540aSrobert
2*404b540aSrobert /* Install modified versions of certain ANSI-incompatible system header
3*404b540aSrobert files which are fixed to work correctly with ANSI C and placed in a
4*404b540aSrobert directory that GCC will search.
5*404b540aSrobert
6*404b540aSrobert Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
7*404b540aSrobert
8*404b540aSrobert This file is part of GCC.
9*404b540aSrobert
10*404b540aSrobert GCC is free software; you can redistribute it and/or modify
11*404b540aSrobert it under the terms of the GNU General Public License as published by
12*404b540aSrobert the Free Software Foundation; either version 2, or (at your option)
13*404b540aSrobert any later version.
14*404b540aSrobert
15*404b540aSrobert GCC is distributed in the hope that it will be useful,
16*404b540aSrobert but WITHOUT ANY WARRANTY; without even the implied warranty of
17*404b540aSrobert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18*404b540aSrobert GNU General Public License for more details.
19*404b540aSrobert
20*404b540aSrobert You should have received a copy of the GNU General Public License
21*404b540aSrobert along with GCC; see the file COPYING. If not, write to
22*404b540aSrobert the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23*404b540aSrobert Boston, MA 02110-1301, USA. */
24*404b540aSrobert
25*404b540aSrobert #include "fixlib.h"
26*404b540aSrobert
27*404b540aSrobert /* * * * * * * * * * * * *
28*404b540aSrobert
29*404b540aSrobert load_file_data loads all the contents of a file into malloc-ed memory.
30*404b540aSrobert Its argument is the file pointer of the file to read in; the returned
31*404b540aSrobert result is the NUL terminated contents of the file. The file
32*404b540aSrobert is presumed to be an ASCII text file containing no NULs. */
33*404b540aSrobert
34*404b540aSrobert char *
load_file_data(FILE * fp)35*404b540aSrobert load_file_data (FILE* fp)
36*404b540aSrobert {
37*404b540aSrobert char *pz_data = (char*)NULL;
38*404b540aSrobert int space_left = -1; /* allow for terminating NUL */
39*404b540aSrobert size_t space_used = 0;
40*404b540aSrobert
41*404b540aSrobert if (fp == (FILE*)NULL)
42*404b540aSrobert return pz_data;
43*404b540aSrobert
44*404b540aSrobert do
45*404b540aSrobert {
46*404b540aSrobert size_t size_read;
47*404b540aSrobert
48*404b540aSrobert if (space_left < 1024)
49*404b540aSrobert {
50*404b540aSrobert space_left += 4096;
51*404b540aSrobert pz_data = XRESIZEVEC (char, pz_data, space_left + space_used + 1 );
52*404b540aSrobert }
53*404b540aSrobert size_read = fread (pz_data + space_used, 1, space_left, fp);
54*404b540aSrobert
55*404b540aSrobert if (size_read == 0)
56*404b540aSrobert {
57*404b540aSrobert if (feof (fp))
58*404b540aSrobert break;
59*404b540aSrobert
60*404b540aSrobert if (ferror (fp))
61*404b540aSrobert {
62*404b540aSrobert int err = errno;
63*404b540aSrobert if (err != EISDIR)
64*404b540aSrobert fprintf (stderr, "error %d (%s) reading input\n", err,
65*404b540aSrobert xstrerror (err));
66*404b540aSrobert free ((void *) pz_data);
67*404b540aSrobert return (char *) NULL;
68*404b540aSrobert }
69*404b540aSrobert }
70*404b540aSrobert
71*404b540aSrobert space_left -= size_read;
72*404b540aSrobert space_used += size_read;
73*404b540aSrobert } while (! feof (fp));
74*404b540aSrobert
75*404b540aSrobert pz_data = XRESIZEVEC (char, pz_data, space_used+1 );
76*404b540aSrobert pz_data[ space_used ] = NUL;
77*404b540aSrobert
78*404b540aSrobert return pz_data;
79*404b540aSrobert }
80*404b540aSrobert
81*404b540aSrobert #ifdef IS_CXX_HEADER_NEEDED
82*404b540aSrobert t_bool
is_cxx_header(tCC * fname,tCC * text)83*404b540aSrobert is_cxx_header (tCC* fname, tCC* text)
84*404b540aSrobert {
85*404b540aSrobert /* First, check to see if the file is in a C++ directory */
86*404b540aSrobert for (;;)
87*404b540aSrobert {
88*404b540aSrobert switch (*(fname++))
89*404b540aSrobert {
90*404b540aSrobert case 'C': /* check for "CC/" */
91*404b540aSrobert if ((fname[0] == 'C') && (fname[1] == '/'))
92*404b540aSrobert return BOOL_TRUE;
93*404b540aSrobert break;
94*404b540aSrobert
95*404b540aSrobert case 'x': /* check for "xx/" */
96*404b540aSrobert if ((fname[0] == 'x') && (fname[1] == '/'))
97*404b540aSrobert return BOOL_TRUE;
98*404b540aSrobert break;
99*404b540aSrobert
100*404b540aSrobert case '+': /* check for "++" */
101*404b540aSrobert if (fname[0] == '+')
102*404b540aSrobert return BOOL_TRUE;
103*404b540aSrobert break;
104*404b540aSrobert
105*404b540aSrobert case NUL:
106*404b540aSrobert goto not_cxx_name;
107*404b540aSrobert }
108*404b540aSrobert } not_cxx_name:;
109*404b540aSrobert
110*404b540aSrobert /* Or it might contain one of several phrases which indicate C++ code.
111*404b540aSrobert Currently recognized are:
112*404b540aSrobert extern "C++"
113*404b540aSrobert -*- (Mode: )? C++ -*- (emacs mode marker)
114*404b540aSrobert template <
115*404b540aSrobert */
116*404b540aSrobert {
117*404b540aSrobert tSCC cxxpat[] = "\
118*404b540aSrobert extern[ \t]*\"C\\+\\+\"|\
119*404b540aSrobert -\\*-[ \t]*([mM]ode:[ \t]*)?[cC]\\+\\+[; \t]*-\\*-|\
120*404b540aSrobert template[ \t]*<|\
121*404b540aSrobert ^[ \t]*class[ \t]|\
122*404b540aSrobert (public|private|protected):|\
123*404b540aSrobert ^[ \t]*#[ \t]*pragma[ \t]+(interface|implementation)\
124*404b540aSrobert ";
125*404b540aSrobert static regex_t cxxre;
126*404b540aSrobert static int compiled;
127*404b540aSrobert
128*404b540aSrobert if (!compiled)
129*404b540aSrobert compile_re (cxxpat, &cxxre, 0, "contents check", "is_cxx_header");
130*404b540aSrobert
131*404b540aSrobert if (xregexec (&cxxre, text, 0, 0, 0) == 0)
132*404b540aSrobert return BOOL_TRUE;
133*404b540aSrobert }
134*404b540aSrobert
135*404b540aSrobert return BOOL_FALSE;
136*404b540aSrobert }
137*404b540aSrobert #endif /* CXX_TYPE_NEEDED */
138*404b540aSrobert
139*404b540aSrobert #ifdef SKIP_QUOTE_NEEDED
140*404b540aSrobert /*
141*404b540aSrobert * Skip over a quoted string. Single quote strings may
142*404b540aSrobert * contain multiple characters if the first character is
143*404b540aSrobert * a backslash. Especially a backslash followed by octal digits.
144*404b540aSrobert * We are not doing a correctness syntax check here.
145*404b540aSrobert */
146*404b540aSrobert tCC*
skip_quote(char q,char * text)147*404b540aSrobert skip_quote(char q, char* text )
148*404b540aSrobert {
149*404b540aSrobert for (;;)
150*404b540aSrobert {
151*404b540aSrobert char ch = *(text++);
152*404b540aSrobert switch (ch)
153*404b540aSrobert {
154*404b540aSrobert case '\\':
155*404b540aSrobert text++; /* skip over whatever character follows */
156*404b540aSrobert break;
157*404b540aSrobert
158*404b540aSrobert case '"':
159*404b540aSrobert case '\'':
160*404b540aSrobert if (ch != q)
161*404b540aSrobert break;
162*404b540aSrobert /*FALLTHROUGH*/
163*404b540aSrobert
164*404b540aSrobert case '\n':
165*404b540aSrobert case NUL:
166*404b540aSrobert goto skip_done;
167*404b540aSrobert }
168*404b540aSrobert } skip_done:;
169*404b540aSrobert
170*404b540aSrobert return text;
171*404b540aSrobert }
172*404b540aSrobert #endif /* SKIP_QUOTE_NEEDED */
173*404b540aSrobert
174*404b540aSrobert /* * * * * * * * * * * * *
175*404b540aSrobert
176*404b540aSrobert Compile one regular expression pattern for later use. PAT contains
177*404b540aSrobert the pattern, RE points to a regex_t structure (which should have
178*404b540aSrobert been bzeroed). MATCH is 1 if we need to know where the regex
179*404b540aSrobert matched, 0 if not. If xregcomp fails, prints an error message and
180*404b540aSrobert aborts; E1 and E2 are strings to shove into the error message.
181*404b540aSrobert
182*404b540aSrobert The patterns we search for are all egrep patterns.
183*404b540aSrobert REG_EXTENDED|REG_NEWLINE produces identical regex syntax/semantics
184*404b540aSrobert to egrep (verified from 4.4BSD Programmer's Reference Manual). */
185*404b540aSrobert void
compile_re(tCC * pat,regex_t * re,int match,tCC * e1,tCC * e2)186*404b540aSrobert compile_re( tCC* pat, regex_t* re, int match, tCC* e1, tCC* e2 )
187*404b540aSrobert {
188*404b540aSrobert tSCC z_bad_comp[] = "fixincl ERROR: cannot compile %s regex for %s\n\
189*404b540aSrobert \texpr = `%s'\n\terror %s\n";
190*404b540aSrobert int flags, err;
191*404b540aSrobert
192*404b540aSrobert flags = (match ? REG_EXTENDED|REG_NEWLINE
193*404b540aSrobert : REG_EXTENDED|REG_NEWLINE|REG_NOSUB);
194*404b540aSrobert err = xregcomp (re, pat, flags);
195*404b540aSrobert
196*404b540aSrobert if (err)
197*404b540aSrobert {
198*404b540aSrobert char rerrbuf[1024];
199*404b540aSrobert regerror (err, re, rerrbuf, 1024);
200*404b540aSrobert fprintf (stderr, z_bad_comp, e1, e2, pat, rerrbuf);
201*404b540aSrobert exit (EXIT_FAILURE);
202*404b540aSrobert }
203*404b540aSrobert }
204*404b540aSrobert
205*404b540aSrobert /* * * * * * * * * * * * *
206*404b540aSrobert
207*404b540aSrobert Helper routine and data for the machine_name test and fix. */
208*404b540aSrobert
209*404b540aSrobert tSCC mn_label_pat[] = "^[ \t]*#[ \t]*(if|ifdef|ifndef)[ \t]+";
210*404b540aSrobert static regex_t mn_label_re;
211*404b540aSrobert static regex_t mn_name_re;
212*404b540aSrobert
213*404b540aSrobert static int mn_compiled = 0;
214*404b540aSrobert
215*404b540aSrobert t_bool
mn_get_regexps(regex_t ** label_re,regex_t ** name_re,tCC * who)216*404b540aSrobert mn_get_regexps(regex_t** label_re, regex_t** name_re, tCC* who )
217*404b540aSrobert {
218*404b540aSrobert if (! pz_mn_name_pat)
219*404b540aSrobert return BOOL_FALSE;
220*404b540aSrobert
221*404b540aSrobert if (! mn_compiled)
222*404b540aSrobert {
223*404b540aSrobert compile_re (mn_label_pat, &mn_label_re, 1, "label pattern", who);
224*404b540aSrobert compile_re (pz_mn_name_pat, &mn_name_re, 1, "name pattern", who);
225*404b540aSrobert mn_compiled++;
226*404b540aSrobert }
227*404b540aSrobert *label_re = &mn_label_re;
228*404b540aSrobert *name_re = &mn_name_re;
229*404b540aSrobert return BOOL_TRUE;
230*404b540aSrobert }
231*404b540aSrobert
232*404b540aSrobert
233*404b540aSrobert #ifdef SEPARATE_FIX_PROC
234*404b540aSrobert
235*404b540aSrobert char*
make_raw_shell_str(char * pz_d,tCC * pz_s,size_t smax)236*404b540aSrobert make_raw_shell_str( char* pz_d, tCC* pz_s, size_t smax )
237*404b540aSrobert {
238*404b540aSrobert tSCC zQ[] = "'\\''";
239*404b540aSrobert size_t dtaSize;
240*404b540aSrobert char* pz_d_start = pz_d;
241*404b540aSrobert
242*404b540aSrobert smax--; /* adjust for trailing NUL */
243*404b540aSrobert
244*404b540aSrobert dtaSize = strlen( pz_s ) + 3;
245*404b540aSrobert
246*404b540aSrobert {
247*404b540aSrobert const char* pz = pz_s - 1;
248*404b540aSrobert
249*404b540aSrobert for (;;) {
250*404b540aSrobert pz = strchr( pz+1, '\'' );
251*404b540aSrobert if (pz == (char*)NULL)
252*404b540aSrobert break;
253*404b540aSrobert dtaSize += sizeof( zQ )-1;
254*404b540aSrobert }
255*404b540aSrobert }
256*404b540aSrobert if (dtaSize > smax)
257*404b540aSrobert return (char*)NULL;
258*404b540aSrobert
259*404b540aSrobert *(pz_d++) = '\'';
260*404b540aSrobert
261*404b540aSrobert for (;;) {
262*404b540aSrobert if (pz_d - pz_d_start >= smax)
263*404b540aSrobert return (char*)NULL;
264*404b540aSrobert switch (*(pz_d++) = *(pz_s++)) {
265*404b540aSrobert case NUL:
266*404b540aSrobert goto loopDone;
267*404b540aSrobert
268*404b540aSrobert case '\'':
269*404b540aSrobert if (pz_d - pz_d_start >= smax - sizeof( zQ )-1)
270*404b540aSrobert return (char*)NULL;
271*404b540aSrobert strcpy( pz_d-1, zQ );
272*404b540aSrobert pz_d += sizeof( zQ )-2;
273*404b540aSrobert }
274*404b540aSrobert } loopDone:;
275*404b540aSrobert pz_d[-1] = '\'';
276*404b540aSrobert *pz_d = NUL;
277*404b540aSrobert
278*404b540aSrobert return pz_d;
279*404b540aSrobert }
280*404b540aSrobert
281*404b540aSrobert #endif
282