1 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 4 directory that GCC will search. 5 6 Copyright (C) 1999, 2000, 2001, 2004, 2009 Free Software Foundation, Inc. 7 8This file is part of GCC. 9 10GCC is free software; you can redistribute it and/or modify 11it under the terms of the GNU General Public License as published by 12the Free Software Foundation; either version 3, or (at your option) 13any later version. 14 15GCC is distributed in the hope that it will be useful, 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 21along with GCC; see the file COPYING3. If not see 22<http://www.gnu.org/licenses/>. */ 23 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 * 34load_file_data (FILE* fp) 35{ 36 char *pz_data = (char*)NULL; 37 int space_left = -1; /* allow for terminating NUL */ 38 size_t space_used = 0; 39 40 if (fp == (FILE*)NULL) 41 return pz_data; 42 43 do 44 { 45 size_t size_read; 46 47 if (space_left < 1024) 48 { 49 space_left += 4096; 50 pz_data = XRESIZEVEC (char, pz_data, space_left + space_used + 1 ); 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, 64 xstrerror (err)); 65 free ((void *) pz_data); 66 return (char *) NULL; 67 } 68 } 69 70 space_left -= size_read; 71 space_used += size_read; 72 } while (! feof (fp)); 73 74 pz_data = XRESIZEVEC (char, pz_data, space_used+1 ); 75 pz_data[ space_used ] = NUL; 76 77 return pz_data; 78} 79 80#ifdef IS_CXX_HEADER_NEEDED 81t_bool 82is_cxx_header (tCC* fname, tCC* text) 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 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 */ 115 { 116 tSCC cxxpat[] = "\ 117extern[ \t]*\"C\\+\\+\"|\ 118-\\*-[ \t]*([mM]ode:[ \t]*)?[cC]\\+\\+[; \t]*-\\*-|\ 119template[ \t]*<|\ 120^[ \t]*class[ \t]|\ 121(public|private|protected):|\ 122^[ \t]*#[ \t]*pragma[ \t]+(interface|implementation)\ 123"; 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 130 if (xregexec (&cxxre, text, 0, 0, 0) == 0) 131 return BOOL_TRUE; 132 } 133 134 return BOOL_FALSE; 135} 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* 146skip_quote(char q, char* text ) 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 */ 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 178 matched, 0 if not. If xregcomp fails, prints an error message and 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 185compile_re( tCC* pat, regex_t* re, int match, tCC* e1, tCC* e2 ) 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); 193 err = xregcomp (re, pat, flags); 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} 203 204/* * * * * * * * * * * * * 205 206 Helper routine and data for the machine_name test and fix. */ 207 208tSCC mn_label_pat[] = "^[ \t]*#[ \t]*(if|ifdef|ifndef)[ \t]+"; 209static regex_t mn_label_re; 210static regex_t mn_name_re; 211 212static int mn_compiled = 0; 213 214t_bool 215mn_get_regexps(regex_t** label_re, regex_t** name_re, tCC* who ) 216{ 217 if (! pz_mn_name_pat) 218 return BOOL_FALSE; 219 220 if (! mn_compiled) 221 { 222 compile_re (mn_label_pat, &mn_label_re, 1, "label pattern", who); 223 compile_re (pz_mn_name_pat, &mn_name_re, 1, "name pattern", who); 224 mn_compiled++; 225 } 226 *label_re = &mn_label_re; 227 *name_re = &mn_name_re; 228 return BOOL_TRUE; 229} 230 231 232#ifdef SEPARATE_FIX_PROC 233 234char* 235make_raw_shell_str( char* pz_d, tCC* pz_s, size_t smax ) 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 (;;) { 261 if ((size_t) (pz_d - pz_d_start) >= smax) 262 return (char*)NULL; 263 switch (*(pz_d++) = *(pz_s++)) { 264 case NUL: 265 goto loopDone; 266 267 case '\'': 268 if ((size_t) (pz_d - pz_d_start) >= smax - sizeof( zQ )-1) 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 281