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

📄 gcc.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
intdo_spec (spec)     char *spec;{  int value;  clear_args ();  arg_going = 0;  delete_this_arg = 0;  this_is_output_file = 0;  this_is_library_file = 0;  value = do_spec_1 (spec, 0);  /* Force out any unfinished command.     If -pipe, this forces out the last command if it ended in `|'.  */  if (value == 0)    {      if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))	argbuf_index--;      if (argbuf_index > 0)	value = execute ();    }  return value;}/* Process the sub-spec SPEC as a portion of a larger spec.   This is like processing a whole spec except that we do   not initialize at the beginning and we do not supply a   newline by default at the end.   INSWITCH nonzero means don't process %-sequences in SPEC;   in this case, % is treated as an ordinary character.   This is used while substituting switches.   INSWITCH nonzero also causes SPC not to terminate an argument.   Value is zero unless a line was finished   and the command on that line reported an error.  */intdo_spec_1 (spec, inswitch)     char *spec;     int inswitch;{  register char *p = spec;  register int c;  char *string;  while (c = *p++)    /* If substituting a switch, treat all chars like letters.       Otherwise, NL, SPC, TAB and % are special.  */    switch (inswitch ? 'a' : c)      {      case '\n':	/* End of line: finish any pending argument,	   then run the pending command if one has been started.  */	if (arg_going)	  {	    obstack_1grow (&obstack, 0);	    string = obstack_finish (&obstack);	    if (this_is_library_file)	      string = find_file (string);	    store_arg (string, delete_this_arg, this_is_output_file);	    if (this_is_output_file)	      outfiles[input_file_number] = string;	  }	arg_going = 0;	if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))	  {	    int i;	    for (i = 0; i < n_switches; i++)	      if (!strcmp (switches[i].part1, "pipe"))		break;	    /* A `|' before the newline means use a pipe here,	       but only if -pipe was specified.	       Otherwise, execute now and don't pass the `|' as an arg.  */	    if (i < n_switches)	      {		switches[i].valid = 1;		break;	      }	    else	      argbuf_index--;	  }	if (argbuf_index > 0)	  {	    int value = execute ();	    if (value)	      return value;	  }	/* Reinitialize for a new command, and for a new argument.  */	clear_args ();	arg_going = 0;	delete_this_arg = 0;	this_is_output_file = 0;	this_is_library_file = 0;	break;      case '|':	/* End any pending argument.  */	if (arg_going)	  {	    obstack_1grow (&obstack, 0);	    string = obstack_finish (&obstack);	    if (this_is_library_file)	      string = find_file (string);	    store_arg (string, delete_this_arg, this_is_output_file);	    if (this_is_output_file)	      outfiles[input_file_number] = string;	  }	/* Use pipe */	obstack_1grow (&obstack, c);	arg_going = 1;	break;      case '\t':      case ' ':	/* Space or tab ends an argument if one is pending.  */	if (arg_going)	  {	    obstack_1grow (&obstack, 0);	    string = obstack_finish (&obstack);	    if (this_is_library_file)	      string = find_file (string);	    store_arg (string, delete_this_arg, this_is_output_file);	    if (this_is_output_file)	      outfiles[input_file_number] = string;	  }	/* Reinitialize for a new argument.  */	arg_going = 0;	delete_this_arg = 0;	this_is_output_file = 0;	this_is_library_file = 0;	break;      case '%':	switch (c = *p++)	  {	  case 0:	    fatal ("Invalid specification!  Bug in cc.");	  case 'b':	    obstack_grow (&obstack, input_basename, basename_length);	    arg_going = 1;	    break;	  case 'd':	    delete_this_arg = 2;	    break;	  case 'e':	    /* {...:%efoo} means report an error with `foo' as error message	       and don't execute any more commands for this file.  */	    {	      char *q = p;	      char *buf;	      while (*p != 0 && *p != '\n') p++;	      buf = (char *) alloca (p - q + 1);	      strncpy (buf, q, p - q);	      buf[p - q] = 0;	      error ("%s", buf);	      return -1;	    }	    break;	  case 'g':	    obstack_grow (&obstack, temp_filename, temp_filename_length);	    delete_this_arg = 1;	    arg_going = 1;	    break;	  case 'i':	    obstack_grow (&obstack, input_filename, input_filename_length);	    arg_going = 1;	    break;	  case 'o':	    {	      register int f;	      for (f = 0; f < n_infiles; f++)		store_arg (outfiles[f], 0, 0);	    }	    break;	  case 's':	    this_is_library_file = 1;	    break;	  case 'W':	    {	      int index = argbuf_index;	      /* Handle the {...} following the %W.  */	      if (*p != '{')		abort ();	      p = handle_braces (p + 1);	      if (p == 0)		return -1;	      /* If any args were output, mark the last one for deletion		 on failure.  */	      if (argbuf_index != index)		record_temp_file (argbuf[argbuf_index - 1], 0, 1);	      break;	    }	  case 'w':	    this_is_output_file = 1;	    break;	  case '{':	    p = handle_braces (p);	    if (p == 0)	      return -1;	    break;	  case '%':	    obstack_1grow (&obstack, '%');	    break;/*** The rest just process a certain constant string as a spec.  */	  case '1':	    do_spec_1 (CC1_SPEC, 0);	    break;	  case 'a':	    do_spec_1 (ASM_SPEC, 0);	    break;	  case 'c':	    do_spec_1 (SIGNED_CHAR_SPEC, 0);	    break;	  case 'C':	    do_spec_1 (CPP_SPEC, 0);	    break;	  case 'l':	    do_spec_1 (LINK_SPEC, 0);	    break;	  case 'L':	    do_spec_1 (LIB_SPEC, 0);	    break;	  case 'G':	    do_spec_1 (LIBG_SPEC, 0);	    break;	  case 'p':	    do_spec_1 (CPP_PREDEFINES, 0);	    break;	  case 'P':	    {	      char *x = (char *) alloca (strlen (CPP_PREDEFINES) * 2 + 1);	      char *buf = x;	      char *y = CPP_PREDEFINES;	      /* Copy all of CPP_PREDEFINES into BUF,		 but put __ after every -D and at the end of each arg,  */	      while (1)		{		  if (! strncmp (y, "-D", 2))		    {		      *x++ = '-';		      *x++ = 'D';		      *x++ = '_';		      *x++ = '_';		      y += 2;		    }		  else if (*y == ' ' || *y == 0)		    {		      *x++ = '_';		      *x++ = '_';		      if (*y == 0)			break;		      else			*x++ = *y++;		    }		  else		    *x++ = *y++;		}	      *x = 0;	      do_spec_1 (buf, 0);	    }	    break;	  case 'S':	    do_spec_1 (STARTFILE_SPEC, 0);	    break;	  case 'E':	    do_spec_1 (ENDFILE_SPEC, 0);	    break;	  default:	    abort ();	  }	break;      default:	/* Ordinary character: put it into the current argument.  */	obstack_1grow (&obstack, c);	arg_going = 1;      }  return 0;		/* End of string */}/* Return 0 if we call do_spec_1 and that returns -1.  */char *handle_braces (p)     register char *p;{  register char *q;  char *filter;  int pipe = 0;  int negate = 0;  if (*p == '|')    /* A `|' after the open-brace means,       if the test fails, output a single minus sign rather than nothing.       This is used in %{|!pipe:...}.  */    pipe = 1, ++p;  if (*p == '!')    /* A `!' after the open-brace negates the condition:       succeed if the specified switch is not present.  */    negate = 1, ++p;  filter = p;  while (*p != ':' && *p != '}') p++;  if (*p != '}')    {      register int count = 1;      q = p + 1;      while (count > 0)	{	  if (*q == '{')	    count++;	  else if (*q == '}')	    count--;	  else if (*q == 0)	    abort ();	  q++;	}    }  else    q = p + 1;  if (p[-1] == '*' && p[0] == '}')    {      /* Substitute all matching switches as separate args.  */      register int i;      --p;      for (i = 0; i < n_switches; i++)	if (!strncmp (switches[i].part1, filter, p - filter))	  give_switch (i);    }  else    {      /* Test for presence of the specified switch.  */      register int i;      int present = 0;      /* If name specified ends in *, as in {x*:...},	 check for presence of any switch name starting with x.  */      if (p[-1] == '*')	{	  for (i = 0; i < n_switches; i++)	    {	      if (!strncmp (switches[i].part1, filter, p - filter - 1))		{		  switches[i].valid = 1;		  present = 1;		}	    }	}      /* Otherwise, check for presence of exact name specified.  */      else	{	  for (i = 0; i < n_switches; i++)	    {	      if (!strncmp (switches[i].part1, filter, p - filter)		  && switches[i].part1[p - filter] == 0)		{		  switches[i].valid = 1;		  present = 1;		  break;		}	    }	}      /* If it is as desired (present for %{s...}, absent for %{-s...})	 then substitute either the switch or the specified	 conditional text.  */      if (present != negate)	{	  if (*p == '}')	    {	      give_switch (i);	    }	  else	    {	      if (do_spec_1 (save_string (p + 1, q - p - 2), 0) < 0)		return 0;	    }	}      else if (pipe)	{	  /* Here if a %{|...} conditional fails: output a minus sign,	     which means "standard output" or "standard input".  */	  do_spec_1 ("-", 0);	}    }  return q;}/* Pass a switch to the current accumulating command   in the same form that we received it.   SWITCHNUM identifies the switch; it is an index into   the vector of switches gcc received, which is `switches'.   This cannot fail since it never finishes a command line.  */give_switch (switchnum)     int switchnum;{  do_spec_1 ("-", 0);  do_spec_1 (switches[switchnum].part1, 1);  do_spec_1 (" ", 0);  if (switches[switchnum].part2 != 0)    {      do_spec_1 (switches[switchnum].part2, 1);      do_spec_1 (" ", 0);    }  switches[switchnum].valid = 1;}/* Search for a file named NAME trying various prefixes including the   user's -B prefix and some standard ones.   Return the absolute pathname found.  If nothing is found, return NAME.  */char *find_file (name)     char *name;{  int size;  char *temp;  int win = 0;  /* Compute maximum size of NAME plus any prefix we will try.  */  size = strlen (standard_exec_prefix);  if (user_exec_prefix != 0 && strlen (user_exec_prefix) > size)    size = strlen (user_exec_prefix);  if (env_exec_prefix != 0 && strlen (env_exec_prefix) > size)    size = strlen (env_exec_prefix);  if (strlen (standard_exec_prefix) > size)    size = strlen (standard_exec_prefix);  if (strlen (standard_exec_prefix_1) > size)    size = strlen (standard_exec_prefix_1);  if (strlen (standard_startfile_prefix) > size)    size = strlen (standard_startfile_prefix);  if (strlen (standard_startfile_prefix_1) > size)    size = strlen (standard_startfile_prefix_1);  if (strlen (standard_startfile_prefix_2) > size)    size = strlen (standard_startfile_prefix_2);  if (machine_suffix)    size += strlen (machine_suffix) + 1;  size += strlen (name) + 1;  temp = (char *) alloca (size);  if (user_exec_prefix)    {      if (machine_suffix)	{	  strcpy (temp, user_exec_prefix);	  strcat (temp, machine_suffix);	  strcat (temp, name);	  win = (access (temp, R_OK) == 0);	}      if (!win)	{	  strcpy (temp, user_exec_prefix);	  strcat (temp, name);	  win = (access (temp, R_OK) == 0);	}    }  if (!win && env_exec_prefix)    {      if (machine_suffix)	{	  strcpy (temp, env_exec_prefix);	  strcat (temp, machine_suffix);	  strcat (temp, name);	  win = (access (temp, R_OK) == 0);	}      if (!win)	{	  strcpy (temp, env_exec_prefix);	  strcat (temp, name);	  win = (access (temp, R_OK) == 0);	}    }  if (!win)    {      if (machine_suffix)	{	  strcpy (temp, standard_exec_prefix);	  strcat (temp, machine_suffix);	  strcat (temp, name);	  win = (access (temp, R_OK) == 0);	}      if (!win)	{	  strcpy (temp, standard_exec_prefix);	  strcat (temp, name);	  win = (access (temp, R_OK) == 0);	}    }  if (!win)    {

⌨️ 快捷键说明

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