418 lines · 10.4 KB · C
RawDownload
 /* Install modified versions of certain ANSI-incompatible system header   files which are fixed to work correctly with ANSI C and placed in a   directory that GCC will search.    Copyright (C) 1999, 2000, 2001, 2004, 2009 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 3, or (at your option)any later version. GCC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details. You should have received a copy of the GNU General Public Licensealong with GCC; see the file COPYING3.  If not see<http://www.gnu.org/licenses/>.  */ #include "fixlib.h" /* * * * * * * * * * * * *    load_file_data loads all the contents of a file into malloc-ed memory.   Its argument is the file pointer of the file to read in; the returned   result is the NUL terminated contents of the file.  The file   is presumed to be an ASCII text file containing no NULs.  */ char *load_file_data (FILE* fp){  char *pz_data = (char*)NULL;  int    space_left = -1;  /* allow for terminating NUL */  size_t space_used = 0;   if (fp == (FILE*)NULL)    return pz_data;   do    {      size_t  size_read;       if (space_left < 1024)        {          space_left += 4096;	  pz_data = XRESIZEVEC (char, pz_data, space_left + space_used + 1 );        }      size_read = fread (pz_data + space_used, 1, space_left, fp);       if (size_read == 0)        {          if (feof (fp))            break;           if (ferror (fp))            {              int err = errno;              if (err != EISDIR)                fprintf (stderr, "error %d (%s) reading input\n", err,                         xstrerror (err));              free ((void *) pz_data);              return (char *) NULL;            }        }       space_left -= size_read;      space_used += size_read;    } while (! feof (fp));   pz_data = XRESIZEVEC (char, pz_data, space_used+1 );  pz_data[ space_used ] = NUL;   return pz_data;} #ifdef IS_CXX_HEADER_NEEDEDt_boolis_cxx_header (tCC* fname, tCC* text){  /*  First, check to see if the file is in a C++ directory */  for (;;)    {      switch (*(fname++))        {        case 'C': /* check for "CC/" */          if ((fname[0] == 'C') && (fname[1] == '/'))            return BOOL_TRUE;          break;         case 'x': /* check for "xx/" */          if ((fname[0] == 'x') && (fname[1] == '/'))            return BOOL_TRUE;          break;         case '+': /* check for "++" */          if (fname[0] == '+')            return BOOL_TRUE;          break;         case NUL:          goto not_cxx_name;        }    } not_cxx_name:;   /* Or it might contain one of several phrases which indicate C++ code.     Currently recognized are:     extern "C++"     -*- (Mode: )? C++ -*-   (emacs mode marker)     template <   */    {      tSCC cxxpat[] = "\extern[ \t]*\"C\\+\\+\"|\-\\*-[ \t]*([mM]ode:[ \t]*)?[cC]\\+\\+[; \t]*-\\*-|\template[ \t]*<|\^[ \t]*class[ \t]|\(public|private|protected):|\^[ \t]*#[ \t]*pragma[ \t]+(interface|implementation)\";      static regex_t cxxre;      static int compiled;       if (!compiled)	compile_re (cxxpat, &cxxre, 0, "contents check", "is_cxx_header");       if (xregexec (&cxxre, text, 0, 0, 0) == 0)	return BOOL_TRUE;    }		     return BOOL_FALSE;}#endif /* CXX_TYPE_NEEDED */ #ifdef SKIP_QUOTE_NEEDED/* *  Skip over a quoted string.  Single quote strings may *  contain multiple characters if the first character is *  a backslash.  Especially a backslash followed by octal digits. *  We are not doing a correctness syntax check here. */tCC*skip_quote(char q, char* text ){  for (;;)    {      char ch = *(text++);      switch (ch)        {        case '\\':          text++; /* skip over whatever character follows */          break;         case '"':        case '\'':          if (ch != q)            break;          /*FALLTHROUGH*/         case '\n':        case NUL:          goto skip_done;        }    } skip_done:;   return text;}#endif /* SKIP_QUOTE_NEEDED */ /* * * * * * * * * * * * *    Compile one regular expression pattern for later use.  PAT contains   the pattern, RE points to a regex_t structure (which should have   been bzeroed).  MATCH is 1 if we need to know where the regex   matched, 0 if not. If xregcomp fails, prints an error message and   aborts; E1 and E2 are strings to shove into the error message.    The patterns we search for are all egrep patterns.   REG_EXTENDED|REG_NEWLINE produces identical regex syntax/semantics   to egrep (verified from 4.4BSD Programmer's Reference Manual).  */voidcompile_re( tCC* pat, regex_t* re, int match, tCC* e1, tCC* e2 ){  tSCC z_bad_comp[] = "fixincl ERROR:  cannot compile %s regex for %s\n\\texpr = `%s'\n\terror %s\n";  int flags, err;   flags = (match ? REG_EXTENDED|REG_NEWLINE	   : REG_EXTENDED|REG_NEWLINE|REG_NOSUB);  err = xregcomp (re, pat, flags);   if (err)    {      char rerrbuf[1024];      regerror (err, re, rerrbuf, 1024);      fprintf (stderr, z_bad_comp, e1, e2, pat, rerrbuf);      exit (EXIT_FAILURE);    }} /* * * * * * * * * * * * *    Helper routine and data for the machine_name test and fix.  */ tSCC mn_label_pat[] = "^[ \t]*#[ \t]*(if|ifdef|ifndef)[ \t]+";static regex_t mn_label_re;static regex_t mn_name_re; static int mn_compiled = 0; t_boolmn_get_regexps(regex_t** label_re, regex_t** name_re, tCC* who ){  if (! pz_mn_name_pat)    return BOOL_FALSE;   if (! mn_compiled)    {      compile_re (mn_label_pat, &mn_label_re, 1, "label pattern", who);      compile_re (pz_mn_name_pat, &mn_name_re, 1, "name pattern", who);      mn_compiled++;    }  *label_re = &mn_label_re;  *name_re = &mn_name_re;  return BOOL_TRUE;}  #ifdef SEPARATE_FIX_PROC char*make_raw_shell_str( char* pz_d, tCC* pz_s, size_t smax ){  tSCC zQ[] = "'\\''";  size_t     dtaSize;  char*      pz_d_start = pz_d;   smax--; /* adjust for trailing NUL */   dtaSize = strlen( pz_s ) + 3;   {    const char* pz = pz_s - 1;     for (;;) {      pz = strchr( pz+1, '\'' );      if (pz == (char*)NULL)        break;      dtaSize += sizeof( zQ )-1;    }  }  if (dtaSize > smax)    return (char*)NULL;   *(pz_d++) = '\'';   for (;;) {    if ((size_t) (pz_d - pz_d_start) >= smax)      return (char*)NULL;    switch (*(pz_d++) = *(pz_s++)) {    case NUL:      goto loopDone;     case '\'':      if ((size_t) (pz_d - pz_d_start) >= smax - sizeof( zQ )-1)	return (char*)NULL;      strcpy( pz_d-1, zQ );      pz_d += sizeof( zQ )-2;    }  } loopDone:;  pz_d[-1] = '\'';  *pz_d    = NUL;   return pz_d;} #endif #if defined(__MINGW32__)voidfix_path_separators (char* p){    while (p != NULL)      {        p = strchr (p, '\\');        if (p != NULL)          {            *p = '/';            ++p;          }      }} /* Count number of needle character ocurrences in str */static intcount_occurrences_of_char (char* str, char needle){  int cnt = 0;   while (str)    {       str = strchr (str, needle);       if (str)         {           ++str;           ++cnt;         }    }   return cnt;} /* On Mingw32, system function will just start cmd by default.   Call system function, but prepend ${CONFIG_SHELL} or ${SHELL} -c to the command,   replace newlines with '$'\n'', enclose command with double quotes   and escape special characters which were originally enclosed in single quotes. */intsystem_with_shell (char* s){  static const char z_shell_start_args[] = " -c \"";  static const char z_shell_end_args[] = "\"";  static const char z_shell_newline[] = "'$'\\n''";   /* Use configured shell if present */  char *env_shell = getenv ("CONFIG_SHELL");  int newline_cnt = count_occurrences_of_char (s, '\n');  int escapes_cnt  = count_occurrences_of_char( s, '\\')                      + count_occurrences_of_char (s, '"')                      + count_occurrences_of_char (s, '`');  char *long_cmd;  char *cmd_endp;  int sys_result;  char *s_scan;  int in_quotes;   if (env_shell == NULL)    env_shell = getenv ("SHELL");   /* If neither CONFIGURED_SHELL nor SHELL is set, just call standard system function */  if (env_shell == NULL)    return system (s);   /* Allocate enough memory to fit newly created command string */  long_cmd = XNEWVEC (char, strlen (env_shell)                      + strlen (z_shell_start_args)                      + strlen (s)                      + newline_cnt * (strlen (z_shell_newline) - 1)                      + escapes_cnt                      + strlen (z_shell_end_args)                      + 1);   /* Start with ${SHELL} */  strcpy (long_cmd, env_shell);  cmd_endp = long_cmd + strlen (long_cmd);   /* Opening quote */  strcpy (cmd_endp, z_shell_start_args);  cmd_endp += strlen (z_shell_start_args);   /* Replace newlines and escape special chars */  in_quotes = 0;  for (s_scan = s; *s_scan; ++s_scan)    {      switch (*s_scan)        {          case '\n':            if (in_quotes)              {                /* Replace newline inside quotes with '$'\n'' */                strcpy (cmd_endp, z_shell_newline);                cmd_endp += strlen (z_shell_newline);              }            else              {                /* Replace newlines outside quotes with ; and merge subsequent newlines */                *(cmd_endp++) = ';';                *(cmd_endp++) = ' ';                while (*(s_scan + 1) == '\n' || *(s_scan + 1) == ' ' || *(s_scan + 1) == '\t')                  ++s_scan;              }            break;          case '\'':            /* Escape single quote and toggle in_quotes flag */            in_quotes = !in_quotes;            *(cmd_endp++) = *s_scan;            break;          case '\\':          case '`':            /* Escape backslash and backtick inside quotes */            if (in_quotes)               *(cmd_endp++) = '\\';            *(cmd_endp++) = *s_scan;            break;          case '"':            /* Escape double quotes always */            *(cmd_endp++) = '\\';            *(cmd_endp++) = *s_scan;            break;          default:            *(cmd_endp++) = *s_scan;        }    }   /* Closing quote */  strcpy (cmd_endp, z_shell_end_args);   sys_result = system (long_cmd);   free (long_cmd);   return sys_result;} #endif /* defined(__MINGW32__) */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t