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