⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 g++.c

📁 GUN开源阻止下的编译器GCC
💻 C
字号:
/* G++ preliminary semantic processing for the compiler driver.   Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.   Contributed by Brendan Kehoe (brendan@cygnus.com).This file is part of GNU CC.GNU CC 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 2, or (at your option)any later version.GNU CC 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 GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* This program is a wrapper to the main `gcc' driver.  For GNU C++,   we need to do two special things: a) append `-lg++' in situations   where it's appropriate, to link in libg++, and b) add `-xc++'..`-xnone'   around file arguments named `foo.c' or `foo.i'.  So, we do all of   this semantic processing then just exec gcc with the new argument   list.   We used to do all of this in a small shell script, but many users   found the performance of this as a shell script to be unacceptable.   In situations where your PATH has a lot of NFS-mounted directories,   using a script that runs sed and other things would be a nasty   performance hit.  With this program, we never search the PATH at all.  */#include "config.h"#ifdef __STDC__#include <stdarg.h>#else#include <varargs.h>#endif#include <stdio.h>#include <sys/types.h>#if !defined(_WIN32)#include <sys/file.h>   /* May get R_OK, etc. on some systems.  */#else#include <process.h>#endif#include <errno.h>/* Defined to the name of the compiler; if using a cross compiler, the   Makefile should compile this file with the proper name   (e.g., "i386-aout-gcc").  */#ifndef GCC_NAME#define GCC_NAME "gcc"#endif/* This bit is set if we saw a `-xfoo' language specification.  */#define LANGSPEC	(1<<1)/* This bit is set if they did `-lm' or `-lmath'.  */#define MATHLIB		(1<<2)#ifndef MATH_LIBRARY#define MATH_LIBRARY "-lm"#endif/* On MSDOS, write temp files in current dir   because there's no place else we can expect to use.  */#ifdef __MSDOS__#ifndef P_tmpdir#define P_tmpdir "."#endif#ifndef R_OK#define R_OK 4#define W_OK 2#define X_OK 1#endif#endif#ifndef VPROTO#ifdef __STDC__#define PVPROTO(ARGS)		ARGS#define VPROTO(ARGS)		ARGS#define VA_START(va_list,var)	va_start(va_list,var)#else#define PVPROTO(ARGS)		()#define VPROTO(ARGS)		(va_alist) va_dcl#define VA_START(va_list,var)	va_start(va_list)#endif#endif#ifndef errnoextern int errno;#endifextern int sys_nerr;#ifndef HAVE_STRERROR#if defined(bsd4_4)extern const char *const sys_errlist[];#elseextern char *sys_errlist[];#endif#elseextern char *strerror();#endif/* Name with which this program was invoked.  */static char *programname;char *my_strerror(e)     int e;{#ifdef HAVE_STRERROR  return strerror(e);#else  static char buffer[30];  if (!e)    return "";  if (e > 0 && e < sys_nerr)    return sys_errlist[e];  sprintf (buffer, "Unknown error %d", e);  return buffer;#endif}#ifdef HAVE_VPRINTF/* Output an error message and exit */static voidfatal VPROTO((char *format, ...)){#ifndef __STDC__  char *format;#endif  va_list ap;  VA_START (ap, format);#ifndef __STDC__  format = va_arg (ap, char*);#endif  fprintf (stderr, "%s: ", programname);  vfprintf (stderr, format, ap);  va_end (ap);  fprintf (stderr, "\n");#if 0  /* XXX Not needed for g++ driver.  */  delete_temp_files ();#endif  exit (1);}static voiderror VPROTO((char *format, ...)){#ifndef __STDC__  char *format;#endif  va_list ap;  VA_START (ap, format);#ifndef __STDC__  format = va_arg (ap, char*);#endif  fprintf (stderr, "%s: ", programname);  vfprintf (stderr, format, ap);  va_end (ap);  fprintf (stderr, "\n");}#else /* not HAVE_VPRINTF */static voiderror (msg, arg1, arg2)     char *msg, *arg1, *arg2;{  fprintf (stderr, "%s: ", programname);  fprintf (stderr, msg, arg1, arg2);  fprintf (stderr, "\n");}static voidfatal (msg, arg1, arg2)     char *msg, *arg1, *arg2;{  error (msg, arg1, arg2);#if 0  /* XXX Not needed for g++ driver.  */  delete_temp_files ();#endif  exit (1);}#endif /* not HAVE_VPRINTF *//* More 'friendly' abort that prints the line and file.   config.h can #define abort fancy_abort if you like that sort of thing.  */voidfancy_abort (){  fatal ("Internal g++ abort.");}char *xmalloc (size)     unsigned size;{  register char *value = (char *) malloc (size);  if (value == 0)    fatal ("virtual memory exhausted");  return value;}/* Return a newly-allocated string whose contents concatenate those   of s1, s2, s3.  */static char *concat (s1, s2, s3)     char *s1, *s2, *s3;{  int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);  char *result = xmalloc (len1 + len2 + len3 + 1);  strcpy (result, s1);  strcpy (result + len1, s2);  strcpy (result + len1 + len2, s3);  *(result + len1 + len2 + len3) = 0;  return result;}static voidpfatal_with_name (name)     char *name;{  fatal (concat ("%s: ", my_strerror (errno), ""), name);}#ifdef __MSDOS__/* This is the common prefix we use to make temp file names.  */char *temp_filename;/* Length of the prefix.  */int temp_filename_length;/* Compute a string to use as the base of all temporary file names.  */static char *choose_temp_base_try (try, base)char *try;char *base;{  char *rv;  if (base)    rv = base;  else if (try == (char *)0)    rv = 0;  else if (access (try, R_OK | W_OK) != 0)    rv = 0;  else    rv = try;  return rv;}static voidchoose_temp_base (){  char *base = 0;  int len;  base = choose_temp_base_try (getenv ("TMPDIR"), base);  base = choose_temp_base_try (getenv ("TMP"), base);  base = choose_temp_base_try (getenv ("TEMP"), base);#ifdef P_tmpdir  base = choose_temp_base_try (P_tmpdir, base);#endif  base = choose_temp_base_try ("/usr/tmp", base);  base = choose_temp_base_try ("/tmp", base);  /* If all else fails, use the current directory! */    if (base == (char *)0)    base = "./";  len = strlen (base);  temp_filename = xmalloc (len + sizeof("/ccXXXXXX"));  strcpy (temp_filename, base);  if (len > 0 && temp_filename[len-1] != '/')    temp_filename[len++] = '/';  strcpy (temp_filename + len, "ccXXXXXX");  mktemp (temp_filename);  temp_filename_length = strlen (temp_filename);  if (temp_filename_length == 0)    abort ();}static voidperror_exec (name)     char *name;{  char *s;  if (errno < sys_nerr)    s = concat ("installation problem, cannot exec %s: ",		my_strerror( errno ), "");  else    s = "installation problem, cannot exec %s";  error (s, name);}/* This is almost exactly what's in gcc.c:pexecute for MSDOS.  */voidrun_dos (program, argv)     char *program;     char *argv[];{  char *scmd, *rf;  FILE *argfile;  int i;  choose_temp_base (); /* not in gcc.c */  scmd = (char *) malloc (strlen (program) + strlen (temp_filename) + 10);  rf = scmd + strlen (program) + 6;  sprintf (scmd, "%s.exe @%s.gp", program, temp_filename);  argfile = fopen (rf, "w");  if (argfile == 0)    pfatal_with_name (rf);  for (i=1; argv[i]; i++)    {      char *cp;      for (cp = argv[i]; *cp; cp++)	{	  if (*cp == '"' || *cp == '\'' || *cp == '\\' || isspace (*cp))	    fputc ('\\', argfile);	  fputc (*cp, argfile);	}      fputc ('\n', argfile);    }  fclose (argfile);  i = system (scmd);  remove (rf);    if (i == -1)    perror_exec (program);}#endif /* __MSDOS__ */intmain (argc, argv)     int argc;     char **argv;{  register int i, j = 0;  register char *p;  int verbose = 0;  /* This will be 0 if we encounter a situation where we should not     link in libstdc++, or 2 if we should link in libg++ as well.  */  int library = 1;  /* Used to track options that take arguments, so we don't go wrapping     those with -xc++/-xnone.  */  char *quote = NULL;  /* The new argument list will be contained in this.  */  char **arglist;  /* The name of the compiler we will want to run---by default, it     will be the definition of `GCC_NAME', e.g., `gcc'.  */  char *gcc = GCC_NAME;  /* Non-zero if we saw a `-xfoo' language specification on the     command line.  Used to avoid adding our own -xc++ if the user     already gave a language for the file.  */  int saw_speclang = 0;  /* Non-zero if we saw `-lm' or `-lmath' on the command line.  */  char *saw_math = 0;  /* The number of arguments being added to what's in argv, other than     libraries.  We use this to track the number of times we've inserted     -xc++/-xnone.  */  int added = 0;  /* An array used to flag each argument that needs a bit set for     LANGSPEC or MATHLIB.  */  int *args;  p = argv[0] + strlen (argv[0]);  /* If we're called as g++ (or i386-aout-g++), link in libg++ as well.  */  if (strcmp (p - 3, "g++") == 0)    {      library = 2;    }  while (p != argv[0] && p[-1] != '/')    --p;  programname = p;  if (argc == 1)    fatal ("No input files specified.\n");#ifndef __MSDOS__  /* We do a little magic to find out where the main gcc executable     is.  If they ran us as /usr/local/bin/g++, then we will look     for /usr/local/bin/gcc; similarly, if they just ran us as `g++',     we'll just look for `gcc'.  */  if (p != argv[0])    {      *--p = '\0';      gcc = (char *) malloc ((strlen (argv[0]) + 1 + strlen (GCC_NAME) + 1)			     * sizeof (char));      sprintf (gcc, "%s/%s", argv[0], GCC_NAME);    }#endif  args = (int *) malloc (argc * sizeof (int));  bzero ((char *) args, argc * sizeof (int));  for (i = 1; i < argc; i++)    {      /* If the previous option took an argument, we swallow it here.  */      if (quote)	{	  quote = NULL;	  continue;	}      if (argv[i][0] == '\0' || argv[i][1] == '\0')	continue;      if (argv[i][0] == '-')	{	  if (library != 0 && strcmp (argv[i], "-nostdlib") == 0)	    {	      library = 0;	    }	  else if (strcmp (argv[i], "-lm") == 0		   || strcmp (argv[i], "-lmath") == 0)	    args[i] |= MATHLIB;	  else if (strcmp (argv[i], "-v") == 0)	    {	      verbose = 1;	      if (argc == 2)		{		  /* If they only gave us `-v', don't try to link		     in libg++.  */ 		  library = 0;		}	    }	  else if (strncmp (argv[i], "-x", 2) == 0)	    saw_speclang = 1;	  else if (((argv[i][2] == '\0'		     && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)		    || strcmp (argv[i], "-Tdata") == 0))	    quote = argv[i];	  else if (library != 0 && ((argv[i][2] == '\0'		     && (char *) strchr ("cSEM", argv[i][1]) != NULL)		    || strcmp (argv[i], "-MM") == 0))	    {	      /* Don't specify libraries if we won't link, since that would		 cause a warning.  */	      library = 0;	    }	  else	    /* Pass other options through.  */	    continue;	}      else	{	  int len; 	  if (saw_speclang)	    {	      saw_speclang = 0;	      continue;	    }	  /* If the filename ends in .c or .i, put options around it.	     But not if a specified -x option is currently active.  */	  len = strlen (argv[i]);	  if (len > 2	      && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')	      && argv[i][len - 2] == '.')	    {	      args[i] |= LANGSPEC;	      added += 2;	    }	}    }  if (quote)    fatal ("argument to `%s' missing\n", quote);  if (added || library)    {      arglist = (char **) malloc ((argc + added + 4) * sizeof (char *));      for (i = 1, j = 1; i < argc; i++, j++)	{	  arglist[j] = argv[i];	  /* Make sure -lg++ is before the math library, since libg++	     itself uses those math routines.  */	  if (!saw_math && (args[i] & MATHLIB) && library)	    {	      --j;	      saw_math = argv[i];	    }	  /* Wrap foo.c and foo.i files in a language specification to	     force the gcc compiler driver to run cc1plus on them.  */	  if (args[i] & LANGSPEC)	    {	      int len = strlen (argv[i]);	      if (argv[i][len - 1] == 'i')		arglist[j++] = "-xc++-cpp-output";	      else		arglist[j++] = "-xc++";	      arglist[j++] = argv[i];	      arglist[j] = "-xnone";	    }	}      /* Add `-lg++' if we haven't already done so.  */      if (library == 2)	arglist[j++] = "-lg++";      if (library)	arglist[j++] = "-lstdc++";      if (saw_math)	arglist[j++] = saw_math;      else if (library)	arglist[j++] = MATH_LIBRARY;      arglist[j] = NULL;    }  else    /* No need to copy 'em all.  */    arglist = argv;  arglist[0] = gcc;  if (verbose)    {      if (j == 0)	j = argc;      for (i = 0; i < j; i++)	fprintf (stderr, " %s", arglist[i]);      fprintf (stderr, "\n");    }#if !defined(OS2) && !defined (_WIN32)#ifdef __MSDOS__  run_dos (gcc, arglist);#else /* !__MSDOS__ */  if (execvp (gcc, arglist) < 0)    pfatal_with_name (gcc);#endif /* __MSDOS__ */#else /* OS2 or _WIN32 */  if (spawnvp (1, gcc, arglist) < 0)    pfatal_with_name (gcc);#endif  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -