1c3d31fe1Smrg
2c3d31fe1Smrg /* Install modified versions of certain ANSI-incompatible system header
3c3d31fe1Smrg files which are fixed to work correctly with ANSI C and placed in a
4c3d31fe1Smrg directory that GCC will search.
5c3d31fe1Smrg
6c3d31fe1Smrg Copyright (C) 1999, 2000, 2001, 2004, 2009 Free Software Foundation, Inc.
7c3d31fe1Smrg
8c3d31fe1Smrg This file is part of GCC.
9c3d31fe1Smrg
10c3d31fe1Smrg GCC is free software; you can redistribute it and/or modify
11c3d31fe1Smrg it under the terms of the GNU General Public License as published by
12c3d31fe1Smrg the Free Software Foundation; either version 3, or (at your option)
13c3d31fe1Smrg any later version.
14c3d31fe1Smrg
15c3d31fe1Smrg GCC is distributed in the hope that it will be useful,
16c3d31fe1Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
17c3d31fe1Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18c3d31fe1Smrg GNU General Public License for more details.
19c3d31fe1Smrg
20c3d31fe1Smrg You should have received a copy of the GNU General Public License
21c3d31fe1Smrg along with GCC; see the file COPYING3. If not see
22c3d31fe1Smrg <http://www.gnu.org/licenses/>. */
23c3d31fe1Smrg
24c3d31fe1Smrg #include "fixlib.h"
25c3d31fe1Smrg
26c3d31fe1Smrg /* * * * * * * * * * * * *
27c3d31fe1Smrg
28c3d31fe1Smrg load_file_data loads all the contents of a file into malloc-ed memory.
29c3d31fe1Smrg Its argument is the file pointer of the file to read in; the returned
30c3d31fe1Smrg result is the NUL terminated contents of the file. The file
31c3d31fe1Smrg is presumed to be an ASCII text file containing no NULs. */
32c3d31fe1Smrg
33c3d31fe1Smrg char *
load_file_data(FILE * fp)34c3d31fe1Smrg load_file_data (FILE* fp)
35c3d31fe1Smrg {
36c3d31fe1Smrg char *pz_data = (char*)NULL;
37c3d31fe1Smrg int space_left = -1; /* allow for terminating NUL */
38c3d31fe1Smrg size_t space_used = 0;
39c3d31fe1Smrg
40c3d31fe1Smrg if (fp == (FILE*)NULL)
41c3d31fe1Smrg return pz_data;
42c3d31fe1Smrg
43c3d31fe1Smrg do
44c3d31fe1Smrg {
45c3d31fe1Smrg size_t size_read;
46c3d31fe1Smrg
47c3d31fe1Smrg if (space_left < 1024)
48c3d31fe1Smrg {
49c3d31fe1Smrg space_left += 4096;
50c3d31fe1Smrg pz_data = XRESIZEVEC (char, pz_data, space_left + space_used + 1 );
51c3d31fe1Smrg }
52c3d31fe1Smrg size_read = fread (pz_data + space_used, 1, space_left, fp);
53c3d31fe1Smrg
54c3d31fe1Smrg if (size_read == 0)
55c3d31fe1Smrg {
56c3d31fe1Smrg if (feof (fp))
57c3d31fe1Smrg break;
58c3d31fe1Smrg
59c3d31fe1Smrg if (ferror (fp))
60c3d31fe1Smrg {
61c3d31fe1Smrg int err = errno;
62c3d31fe1Smrg if (err != EISDIR)
63c3d31fe1Smrg fprintf (stderr, "error %d (%s) reading input\n", err,
64c3d31fe1Smrg xstrerror (err));
65c3d31fe1Smrg free ((void *) pz_data);
66c3d31fe1Smrg return (char *) NULL;
67c3d31fe1Smrg }
68c3d31fe1Smrg }
69c3d31fe1Smrg
70c3d31fe1Smrg space_left -= size_read;
71c3d31fe1Smrg space_used += size_read;
72c3d31fe1Smrg } while (! feof (fp));
73c3d31fe1Smrg
74c3d31fe1Smrg pz_data = XRESIZEVEC (char, pz_data, space_used+1 );
75c3d31fe1Smrg pz_data[ space_used ] = NUL;
76c3d31fe1Smrg
77c3d31fe1Smrg return pz_data;
78c3d31fe1Smrg }
79c3d31fe1Smrg
80c3d31fe1Smrg #ifdef IS_CXX_HEADER_NEEDED
81c3d31fe1Smrg t_bool
is_cxx_header(tCC * fname,tCC * text)82c3d31fe1Smrg is_cxx_header (tCC* fname, tCC* text)
83c3d31fe1Smrg {
84c3d31fe1Smrg /* First, check to see if the file is in a C++ directory */
85c3d31fe1Smrg for (;;)
86c3d31fe1Smrg {
87c3d31fe1Smrg switch (*(fname++))
88c3d31fe1Smrg {
89c3d31fe1Smrg case 'C': /* check for "CC/" */
90c3d31fe1Smrg if ((fname[0] == 'C') && (fname[1] == '/'))
91c3d31fe1Smrg return BOOL_TRUE;
92c3d31fe1Smrg break;
93c3d31fe1Smrg
94c3d31fe1Smrg case 'x': /* check for "xx/" */
95c3d31fe1Smrg if ((fname[0] == 'x') && (fname[1] == '/'))
96c3d31fe1Smrg return BOOL_TRUE;
97c3d31fe1Smrg break;
98c3d31fe1Smrg
99c3d31fe1Smrg case '+': /* check for "++" */
100c3d31fe1Smrg if (fname[0] == '+')
101c3d31fe1Smrg return BOOL_TRUE;
102c3d31fe1Smrg break;
103c3d31fe1Smrg
104c3d31fe1Smrg case NUL:
105c3d31fe1Smrg goto not_cxx_name;
106c3d31fe1Smrg }
107c3d31fe1Smrg } not_cxx_name:;
108c3d31fe1Smrg
109c3d31fe1Smrg /* Or it might contain one of several phrases which indicate C++ code.
110c3d31fe1Smrg Currently recognized are:
111c3d31fe1Smrg extern "C++"
112c3d31fe1Smrg -*- (Mode: )? C++ -*- (emacs mode marker)
113c3d31fe1Smrg template <
114c3d31fe1Smrg */
115c3d31fe1Smrg {
116c3d31fe1Smrg tSCC cxxpat[] = "\
117c3d31fe1Smrg extern[ \t]*\"C\\+\\+\"|\
118c3d31fe1Smrg -\\*-[ \t]*([mM]ode:[ \t]*)?[cC]\\+\\+[; \t]*-\\*-|\
119c3d31fe1Smrg template[ \t]*<|\
120c3d31fe1Smrg ^[ \t]*class[ \t]|\
121c3d31fe1Smrg (public|private|protected):|\
122c3d31fe1Smrg ^[ \t]*#[ \t]*pragma[ \t]+(interface|implementation)\
123c3d31fe1Smrg ";
124c3d31fe1Smrg static regex_t cxxre;
125c3d31fe1Smrg static int compiled;
126c3d31fe1Smrg
127c3d31fe1Smrg if (!compiled)
128c3d31fe1Smrg compile_re (cxxpat, &cxxre, 0, "contents check", "is_cxx_header");
129c3d31fe1Smrg
130c3d31fe1Smrg if (xregexec (&cxxre, text, 0, 0, 0) == 0)
131c3d31fe1Smrg return BOOL_TRUE;
132c3d31fe1Smrg }
133c3d31fe1Smrg
134c3d31fe1Smrg return BOOL_FALSE;
135c3d31fe1Smrg }
136c3d31fe1Smrg #endif /* CXX_TYPE_NEEDED */
137c3d31fe1Smrg
138c3d31fe1Smrg #ifdef SKIP_QUOTE_NEEDED
139c3d31fe1Smrg /*
140c3d31fe1Smrg * Skip over a quoted string. Single quote strings may
141c3d31fe1Smrg * contain multiple characters if the first character is
142c3d31fe1Smrg * a backslash. Especially a backslash followed by octal digits.
143c3d31fe1Smrg * We are not doing a correctness syntax check here.
144c3d31fe1Smrg */
145c3d31fe1Smrg tCC*
skip_quote(char q,char * text)146c3d31fe1Smrg skip_quote(char q, char* text )
147c3d31fe1Smrg {
148c3d31fe1Smrg for (;;)
149c3d31fe1Smrg {
150c3d31fe1Smrg char ch = *(text++);
151c3d31fe1Smrg switch (ch)
152c3d31fe1Smrg {
153c3d31fe1Smrg case '\\':
154c3d31fe1Smrg text++; /* skip over whatever character follows */
155c3d31fe1Smrg break;
156c3d31fe1Smrg
157c3d31fe1Smrg case '"':
158c3d31fe1Smrg case '\'':
159c3d31fe1Smrg if (ch != q)
160c3d31fe1Smrg break;
161c3d31fe1Smrg /*FALLTHROUGH*/
162c3d31fe1Smrg
163c3d31fe1Smrg case '\n':
164c3d31fe1Smrg case NUL:
165c3d31fe1Smrg goto skip_done;
166c3d31fe1Smrg }
167c3d31fe1Smrg } skip_done:;
168c3d31fe1Smrg
169c3d31fe1Smrg return text;
170c3d31fe1Smrg }
171c3d31fe1Smrg #endif /* SKIP_QUOTE_NEEDED */
172c3d31fe1Smrg
173c3d31fe1Smrg /* * * * * * * * * * * * *
174c3d31fe1Smrg
175c3d31fe1Smrg Compile one regular expression pattern for later use. PAT contains
176c3d31fe1Smrg the pattern, RE points to a regex_t structure (which should have
177c3d31fe1Smrg been bzeroed). MATCH is 1 if we need to know where the regex
178c3d31fe1Smrg matched, 0 if not. If xregcomp fails, prints an error message and
179c3d31fe1Smrg aborts; E1 and E2 are strings to shove into the error message.
180c3d31fe1Smrg
181c3d31fe1Smrg The patterns we search for are all egrep patterns.
182c3d31fe1Smrg REG_EXTENDED|REG_NEWLINE produces identical regex syntax/semantics
183c3d31fe1Smrg to egrep (verified from 4.4BSD Programmer's Reference Manual). */
184c3d31fe1Smrg void
compile_re(tCC * pat,regex_t * re,int match,tCC * e1,tCC * e2)185c3d31fe1Smrg compile_re( tCC* pat, regex_t* re, int match, tCC* e1, tCC* e2 )
186c3d31fe1Smrg {
187c3d31fe1Smrg tSCC z_bad_comp[] = "fixincl ERROR: cannot compile %s regex for %s\n\
188c3d31fe1Smrg \texpr = `%s'\n\terror %s\n";
189c3d31fe1Smrg int flags, err;
190c3d31fe1Smrg
191c3d31fe1Smrg flags = (match ? REG_EXTENDED|REG_NEWLINE
192c3d31fe1Smrg : REG_EXTENDED|REG_NEWLINE|REG_NOSUB);
193c3d31fe1Smrg err = xregcomp (re, pat, flags);
194c3d31fe1Smrg
195c3d31fe1Smrg if (err)
196c3d31fe1Smrg {
197c3d31fe1Smrg char rerrbuf[1024];
198c3d31fe1Smrg regerror (err, re, rerrbuf, 1024);
199c3d31fe1Smrg fprintf (stderr, z_bad_comp, e1, e2, pat, rerrbuf);
200c3d31fe1Smrg exit (EXIT_FAILURE);
201c3d31fe1Smrg }
202c3d31fe1Smrg }
203c3d31fe1Smrg
204c3d31fe1Smrg /* * * * * * * * * * * * *
205c3d31fe1Smrg
206c3d31fe1Smrg Helper routine and data for the machine_name test and fix. */
207c3d31fe1Smrg
208c3d31fe1Smrg tSCC mn_label_pat[] = "^[ \t]*#[ \t]*(if|ifdef|ifndef)[ \t]+";
209c3d31fe1Smrg static regex_t mn_label_re;
210c3d31fe1Smrg static regex_t mn_name_re;
211c3d31fe1Smrg
212c3d31fe1Smrg static int mn_compiled = 0;
213c3d31fe1Smrg
214c3d31fe1Smrg t_bool
mn_get_regexps(regex_t ** label_re,regex_t ** name_re,tCC * who)215c3d31fe1Smrg mn_get_regexps(regex_t** label_re, regex_t** name_re, tCC* who )
216c3d31fe1Smrg {
217c3d31fe1Smrg if (! pz_mn_name_pat)
218c3d31fe1Smrg return BOOL_FALSE;
219c3d31fe1Smrg
220c3d31fe1Smrg if (! mn_compiled)
221c3d31fe1Smrg {
222c3d31fe1Smrg compile_re (mn_label_pat, &mn_label_re, 1, "label pattern", who);
223c3d31fe1Smrg compile_re (pz_mn_name_pat, &mn_name_re, 1, "name pattern", who);
224c3d31fe1Smrg mn_compiled++;
225c3d31fe1Smrg }
226c3d31fe1Smrg *label_re = &mn_label_re;
227c3d31fe1Smrg *name_re = &mn_name_re;
228c3d31fe1Smrg return BOOL_TRUE;
229c3d31fe1Smrg }
230c3d31fe1Smrg
231c3d31fe1Smrg
232c3d31fe1Smrg #ifdef SEPARATE_FIX_PROC
233c3d31fe1Smrg
234c3d31fe1Smrg char*
make_raw_shell_str(char * pz_d,tCC * pz_s,size_t smax)235c3d31fe1Smrg make_raw_shell_str( char* pz_d, tCC* pz_s, size_t smax )
236c3d31fe1Smrg {
237c3d31fe1Smrg tSCC zQ[] = "'\\''";
238c3d31fe1Smrg size_t dtaSize;
239c3d31fe1Smrg char* pz_d_start = pz_d;
240c3d31fe1Smrg
241c3d31fe1Smrg smax--; /* adjust for trailing NUL */
242c3d31fe1Smrg
243c3d31fe1Smrg dtaSize = strlen( pz_s ) + 3;
244c3d31fe1Smrg
245c3d31fe1Smrg {
246c3d31fe1Smrg const char* pz = pz_s - 1;
247c3d31fe1Smrg
248c3d31fe1Smrg for (;;) {
249c3d31fe1Smrg pz = strchr( pz+1, '\'' );
250c3d31fe1Smrg if (pz == (char*)NULL)
251c3d31fe1Smrg break;
252c3d31fe1Smrg dtaSize += sizeof( zQ )-1;
253c3d31fe1Smrg }
254c3d31fe1Smrg }
255c3d31fe1Smrg if (dtaSize > smax)
256c3d31fe1Smrg return (char*)NULL;
257c3d31fe1Smrg
258c3d31fe1Smrg *(pz_d++) = '\'';
259c3d31fe1Smrg
260c3d31fe1Smrg for (;;) {
261c3d31fe1Smrg if ((size_t) (pz_d - pz_d_start) >= smax)
262c3d31fe1Smrg return (char*)NULL;
263c3d31fe1Smrg switch (*(pz_d++) = *(pz_s++)) {
264c3d31fe1Smrg case NUL:
265c3d31fe1Smrg goto loopDone;
266c3d31fe1Smrg
267c3d31fe1Smrg case '\'':
268c3d31fe1Smrg if ((size_t) (pz_d - pz_d_start) >= smax - sizeof( zQ )-1)
269c3d31fe1Smrg return (char*)NULL;
270c3d31fe1Smrg strcpy( pz_d-1, zQ );
271c3d31fe1Smrg pz_d += sizeof( zQ )-2;
272c3d31fe1Smrg }
273c3d31fe1Smrg } loopDone:;
274c3d31fe1Smrg pz_d[-1] = '\'';
275c3d31fe1Smrg *pz_d = NUL;
276c3d31fe1Smrg
277c3d31fe1Smrg return pz_d;
278c3d31fe1Smrg }
279c3d31fe1Smrg
280c3d31fe1Smrg #endif
281*6a5c9aabSmrg
282*6a5c9aabSmrg #if defined(__MINGW32__)
283*6a5c9aabSmrg void
fix_path_separators(char * p)284*6a5c9aabSmrg fix_path_separators (char* p)
285*6a5c9aabSmrg {
286*6a5c9aabSmrg while (p != NULL)
287*6a5c9aabSmrg {
288*6a5c9aabSmrg p = strchr (p, '\\');
289*6a5c9aabSmrg if (p != NULL)
290*6a5c9aabSmrg {
291*6a5c9aabSmrg *p = '/';
292*6a5c9aabSmrg ++p;
293*6a5c9aabSmrg }
294*6a5c9aabSmrg }
295*6a5c9aabSmrg }
296*6a5c9aabSmrg
297*6a5c9aabSmrg /* Count number of needle character ocurrences in str */
298*6a5c9aabSmrg static int
count_occurrences_of_char(char * str,char needle)299*6a5c9aabSmrg count_occurrences_of_char (char* str, char needle)
300*6a5c9aabSmrg {
301*6a5c9aabSmrg int cnt = 0;
302*6a5c9aabSmrg
303*6a5c9aabSmrg while (str)
304*6a5c9aabSmrg {
305*6a5c9aabSmrg str = strchr (str, needle);
306*6a5c9aabSmrg if (str)
307*6a5c9aabSmrg {
308*6a5c9aabSmrg ++str;
309*6a5c9aabSmrg ++cnt;
310*6a5c9aabSmrg }
311*6a5c9aabSmrg }
312*6a5c9aabSmrg
313*6a5c9aabSmrg return cnt;
314*6a5c9aabSmrg }
315*6a5c9aabSmrg
316*6a5c9aabSmrg /* On Mingw32, system function will just start cmd by default.
317*6a5c9aabSmrg Call system function, but prepend ${CONFIG_SHELL} or ${SHELL} -c to the command,
318*6a5c9aabSmrg replace newlines with '$'\n'', enclose command with double quotes
319*6a5c9aabSmrg and escape special characters which were originally enclosed in single quotes.
320*6a5c9aabSmrg */
321*6a5c9aabSmrg int
system_with_shell(char * s)322*6a5c9aabSmrg system_with_shell (char* s)
323*6a5c9aabSmrg {
324*6a5c9aabSmrg static const char z_shell_start_args[] = " -c \"";
325*6a5c9aabSmrg static const char z_shell_end_args[] = "\"";
326*6a5c9aabSmrg static const char z_shell_newline[] = "'$'\\n''";
327*6a5c9aabSmrg
328*6a5c9aabSmrg /* Use configured shell if present */
329*6a5c9aabSmrg char *env_shell = getenv ("CONFIG_SHELL");
330*6a5c9aabSmrg int newline_cnt = count_occurrences_of_char (s, '\n');
331*6a5c9aabSmrg int escapes_cnt = count_occurrences_of_char( s, '\\')
332*6a5c9aabSmrg + count_occurrences_of_char (s, '"')
333*6a5c9aabSmrg + count_occurrences_of_char (s, '`');
334*6a5c9aabSmrg char *long_cmd;
335*6a5c9aabSmrg char *cmd_endp;
336*6a5c9aabSmrg int sys_result;
337*6a5c9aabSmrg char *s_scan;
338*6a5c9aabSmrg int in_quotes;
339*6a5c9aabSmrg
340*6a5c9aabSmrg if (env_shell == NULL)
341*6a5c9aabSmrg env_shell = getenv ("SHELL");
342*6a5c9aabSmrg
343*6a5c9aabSmrg /* If neither CONFIGURED_SHELL nor SHELL is set, just call standard system function */
344*6a5c9aabSmrg if (env_shell == NULL)
345*6a5c9aabSmrg return system (s);
346*6a5c9aabSmrg
347*6a5c9aabSmrg /* Allocate enough memory to fit newly created command string */
348*6a5c9aabSmrg long_cmd = XNEWVEC (char, strlen (env_shell)
349*6a5c9aabSmrg + strlen (z_shell_start_args)
350*6a5c9aabSmrg + strlen (s)
351*6a5c9aabSmrg + newline_cnt * (strlen (z_shell_newline) - 1)
352*6a5c9aabSmrg + escapes_cnt
353*6a5c9aabSmrg + strlen (z_shell_end_args)
354*6a5c9aabSmrg + 1);
355*6a5c9aabSmrg
356*6a5c9aabSmrg /* Start with ${SHELL} */
357*6a5c9aabSmrg strcpy (long_cmd, env_shell);
358*6a5c9aabSmrg cmd_endp = long_cmd + strlen (long_cmd);
359*6a5c9aabSmrg
360*6a5c9aabSmrg /* Opening quote */
361*6a5c9aabSmrg strcpy (cmd_endp, z_shell_start_args);
362*6a5c9aabSmrg cmd_endp += strlen (z_shell_start_args);
363*6a5c9aabSmrg
364*6a5c9aabSmrg /* Replace newlines and escape special chars */
365*6a5c9aabSmrg in_quotes = 0;
366*6a5c9aabSmrg for (s_scan = s; *s_scan; ++s_scan)
367*6a5c9aabSmrg {
368*6a5c9aabSmrg switch (*s_scan)
369*6a5c9aabSmrg {
370*6a5c9aabSmrg case '\n':
371*6a5c9aabSmrg if (in_quotes)
372*6a5c9aabSmrg {
373*6a5c9aabSmrg /* Replace newline inside quotes with '$'\n'' */
374*6a5c9aabSmrg strcpy (cmd_endp, z_shell_newline);
375*6a5c9aabSmrg cmd_endp += strlen (z_shell_newline);
376*6a5c9aabSmrg }
377*6a5c9aabSmrg else
378*6a5c9aabSmrg {
379*6a5c9aabSmrg /* Replace newlines outside quotes with ; and merge subsequent newlines */
380*6a5c9aabSmrg *(cmd_endp++) = ';';
381*6a5c9aabSmrg *(cmd_endp++) = ' ';
382*6a5c9aabSmrg while (*(s_scan + 1) == '\n' || *(s_scan + 1) == ' ' || *(s_scan + 1) == '\t')
383*6a5c9aabSmrg ++s_scan;
384*6a5c9aabSmrg }
385*6a5c9aabSmrg break;
386*6a5c9aabSmrg case '\'':
387*6a5c9aabSmrg /* Escape single quote and toggle in_quotes flag */
388*6a5c9aabSmrg in_quotes = !in_quotes;
389*6a5c9aabSmrg *(cmd_endp++) = *s_scan;
390*6a5c9aabSmrg break;
391*6a5c9aabSmrg case '\\':
392*6a5c9aabSmrg case '`':
393*6a5c9aabSmrg /* Escape backslash and backtick inside quotes */
394*6a5c9aabSmrg if (in_quotes)
395*6a5c9aabSmrg *(cmd_endp++) = '\\';
396*6a5c9aabSmrg *(cmd_endp++) = *s_scan;
397*6a5c9aabSmrg break;
398*6a5c9aabSmrg case '"':
399*6a5c9aabSmrg /* Escape double quotes always */
400*6a5c9aabSmrg *(cmd_endp++) = '\\';
401*6a5c9aabSmrg *(cmd_endp++) = *s_scan;
402*6a5c9aabSmrg break;
403*6a5c9aabSmrg default:
404*6a5c9aabSmrg *(cmd_endp++) = *s_scan;
405*6a5c9aabSmrg }
406*6a5c9aabSmrg }
407*6a5c9aabSmrg
408*6a5c9aabSmrg /* Closing quote */
409*6a5c9aabSmrg strcpy (cmd_endp, z_shell_end_args);
410*6a5c9aabSmrg
411*6a5c9aabSmrg sys_result = system (long_cmd);
412*6a5c9aabSmrg
413*6a5c9aabSmrg free (long_cmd);
414*6a5c9aabSmrg
415*6a5c9aabSmrg return sys_result;
416*6a5c9aabSmrg }
417*6a5c9aabSmrg
418*6a5c9aabSmrg #endif /* defined(__MINGW32__) */
419