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

📄 cccp.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			     "unterminated string or character constant");	  break;	}	*obp++ = *ibp;	switch (*ibp++) {	case '\n':	  ++ip->lineno;	  ++op->lineno;	  /* Traditionally, end of line ends a string constant with no error.	     So exit the loop and record the new line.  */	  if (traditional) {	    beg_of_line = ibp;	    goto while2end;	  }	  if (pedantic || c == '\'') {	    error_with_line (line_for_error (start_line),			     "unterminated string or character constant");	    goto while2end;	  }	  break;	case '\\':	  if (ibp >= limit)	    break;	  if (*ibp == '\n') {	    /* Backslash newline is replaced by nothing at all,	       but keep the line counts correct.  */	    --obp;	    ++ibp;	    ++ip->lineno;	  } else {	    /* ANSI stupidly requires that in \\ the second \	       is *not* prevented from combining with a newline.  */	    while (*ibp == '\\' && ibp[1] == '\n') {	      ibp += 2;	      ++ip->lineno;	    }	    *obp++ = *ibp++;	  }	  break;	case '\"':	case '\'':	  if (ibp[-1] == c)	    goto while2end;	  break;	}      }    while2end:      break;    case '/':      if (*ibp == '\\' && ibp[1] == '\n')	newline_fix (ibp);      /* Don't look for comments inside a macro definition.  */      if (ip->macro != 0)	goto randomchar;      /* A comment constitutes white space, so it can terminate an identifier.	 Process the identifier, if any.  */      if (ident_length)	goto specialchar;      if (cplusplus && *ibp == '/') {	/* C++ style comment... */	start_line = ip->lineno;	--ibp;			/* Back over the slash */	--obp;	/* Comments are equivalent to spaces. */	if (! put_out_comments)	  *obp++ = ' ';	else {	  /* must fake up a comment here */	  *obp++ = '/';	  *obp++ = '/';	}	{	  U_CHAR *before_bp = ibp+2;	  while (ibp < limit) {	    if (*ibp == '\\' && ibp[1] == '\n') {	      ip->lineno++;	      ibp += 2;	    } else if (*ibp++ == '\n') {	      ibp--;	      if (put_out_comments) {		bcopy (before_bp, obp, ibp - before_bp);		obp += ibp - before_bp;	      }	      break;	    }	  }	  break;	}      }      if (*ibp != '*')	goto randomchar;      /* We have a comment.  Skip it, optionally copying it to output.  */      start_line = ip->lineno;      ++ibp;			/* Skip the star. */      /* Comments are equivalent to spaces.	 Note that we already output the slash; we might not want it.	 For -traditional, a comment is equivalent to nothing.  */      if (! put_out_comments) {	if (traditional)	  obp--;	else	  obp[-1] = ' ';      }      else	*obp++ = '*';      {	U_CHAR *before_bp = ibp;	while (ibp < limit) {	  switch (*ibp++) {	  case '/':	    if (warn_comments && ibp < limit && *ibp == '*')	      warning("`/*' within comment");	    break;	  case '*':	    if (*ibp == '\\' && ibp[1] == '\n')	      newline_fix (ibp);	    if (ibp >= limit || *ibp == '/')	      goto comment_end;	    break;	  case '\n':	    ++ip->lineno;	    /* Copy the newline into the output buffer, in order to	       avoid the pain of a #line every time a multiline comment	       is seen.  */	    if (!put_out_comments)	      *obp++ = '\n';	    ++op->lineno;	  }	}      comment_end:	if (ibp >= limit)	  error_with_line (line_for_error (start_line),			   "unterminated comment");	else {	  ibp++;	  if (put_out_comments) {	    bcopy (before_bp, obp, ibp - before_bp);	    obp += ibp - before_bp;	  }	}      }      break;    case '$':      if (!dollars_in_ident)	goto randomchar;      goto letter;    case '0': case '1': case '2': case '3': case '4':    case '5': case '6': case '7': case '8': case '9':      /* If digit is not part of identifier, it starts a number,	 which means that following letters are not an identifier.	 "0x5" does not refer to an identifier "x5".	 So copy all alphanumerics that follow without accumulating	 as an identifier.  Periods also, for sake of "3.e7".  */      if (ident_length == 0) {	while (ibp < limit) {	  while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {	    ++ip->lineno;	    ibp += 2;	  }	  c = *ibp++;	  if (!isalnum (c) && c != '.' && c != '_') {	    --ibp;	    break;	  }	  *obp++ = c;	  /* A sign can be part of a preprocessing number	     if it follows an e.  */	  if (c == 'e' || c == 'E') {	    while (ibp < limit && ibp[0] == '\\' && ibp[1] == '\n') {	      ++ip->lineno;	      ibp += 2;	    }	    if (ibp < limit && (*ibp == '+' || *ibp == '-')) {	      *obp++ = *ibp++;	      /* But traditional C does not let the token go past the sign.  */	      if (traditional)		break;	    }	  }	}	break;      }      /* fall through */    case '_':    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':    case 's': case 't': case 'u': case 'v': case 'w': case 'x':    case 'y': case 'z':    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':    case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':    case 'Y': case 'Z':    letter:      ident_length++;      /* Compute step of hash function, to avoid a proc call on every token */      hash = HASHSTEP (hash, c);      break;    case '\n':      /* If reprocessing a macro expansion, newline is a special marker.  */      if (ip->macro != 0) {	/* Newline White is a "funny space" to separate tokens that are	   supposed to be separate but without space between.	   Here White means any horizontal whitespace character.	   Newline - marks a recursive macro use that is not	   supposed to be expandable.  */	if (*ibp == '-') {	  /* Newline - inhibits expansion of preceding token.	     If expanding a macro arg, we keep the newline -.	     In final output, it is deleted.  */	  if (! concatenated) {	    ident_length = 0;	    hash = 0;	  }	  ibp++;	  if (!output_marks) {	    obp--;	  } else {	    /* If expanding a macro arg, keep the newline -.  */	    *obp++ = '-';	  }	} else if (is_space[*ibp]) {	  /* Newline Space does not prevent expansion of preceding token	     so expand the preceding token and then come back.  */	  if (ident_length > 0)	    goto specialchar;	  /* If generating final output, newline space makes a space.  */	  if (!output_marks) {	    obp[-1] = *ibp++;	    /* And Newline Newline makes a newline, so count it.  */	    if (obp[-1] == '\n')	      op->lineno++;	  } else {	    /* If expanding a macro arg, keep the newline space.	       If the arg gets stringified, newline space makes nothing.  */	    *obp++ = *ibp++;	  }	} else abort ();	/* Newline followed by something random?  */	break;      }      /* If there is a pending identifier, handle it and come back here.  */      if (ident_length > 0)	goto specialchar;      beg_of_line = ibp;      /* Update the line counts and output a #line if necessary.  */      ++ip->lineno;      ++op->lineno;      if (ip->lineno != op->lineno) {	op->bufp = obp;	output_line_command (ip, op, 1, same_file);	check_expand (op, ip->length - (ip->bufp - ip->buf));	obp = op->bufp;      }      break;      /* Come here either after (1) a null character that is part of the input	 or (2) at the end of the input, because there is a null there.  */    case 0:      if (ibp <= limit)	/* Our input really contains a null character.  */	goto randomchar;      /* At end of a macro-expansion level, pop it and read next level.  */      if (ip->macro != 0) {	obp--;	ibp--;	/* If traditional, and we have an identifier that ends here,	   process it now, so we get the right error for recursion.  */	if (traditional && ident_length	    && ! is_idchar[*instack[indepth - 1].bufp]) {	  redo_char = 1;	  goto randomchar;	}	POPMACRO;	RECACHE;	break;      }      /* If we don't have a pending identifier,	 return at end of input.  */      if (ident_length == 0) {	obp--;	ibp--;	op->bufp = obp;	ip->bufp = ibp;	goto ending;      }      /* If we do have a pending identifier, just consider this null	 a special character and arrange to dispatch on it again.	 The second time, IDENT_LENGTH will be zero so we will return.  */      /* Fall through */specialchar:      /* Handle the case of a character such as /, ', " or null	 seen following an identifier.  Back over it so that	 after the identifier is processed the special char	 will be dispatched on again.  */      ibp--;      obp--;      redo_char = 1;    default:randomchar:      if (ident_length > 0) {	register HASHNODE *hp;	/* We have just seen an identifier end.  If it's a macro, expand it.	   IDENT_LENGTH is the length of the identifier	   and HASH is its hash code.	   The identifier has already been copied to the output,	   so if it is a macro we must remove it.	   If REDO_CHAR is 0, the char that terminated the identifier	   has been skipped in the output and the input.	   OBP-IDENT_LENGTH-1 points to the identifier.	   If the identifier is a macro, we must back over the terminator.	   If REDO_CHAR is 1, the terminating char has already been	   backed over.  OBP-IDENT_LENGTH points to the identifier.  */	for (hp = hashtab[MAKE_POS (hash) % HASHSIZE]; hp != NULL;	     hp = hp->next) {	  if (hp->length == ident_length) {	    U_CHAR *obufp_before_macroname;	    int op_lineno_before_macroname;	    register int i = ident_length;	    register U_CHAR *p = hp->name;	    register U_CHAR *q = obp - i;	    int disabled;	    if (! redo_char)	      q--;	    do {		/* All this to avoid a strncmp () */	      if (*p++ != *q++)		goto hashcollision;	    } while (--i);	    /* We found a use of a macro name.	       see if the context shows it is a macro call.  */	    /* Back up over terminating character if not already done.  */	    if (! redo_char) {	      ibp--;	      obp--;	    }	    obufp_before_macroname = obp - ident_length;	    op_lineno_before_macroname = op->lineno;	    /* Record whether the macro is disabled.  */	    disabled = hp->type == T_DISABLED;	    /* This looks like a macro ref, but if the macro was disabled,	       just copy its name and put in a marker if requested.  */	    if (disabled) {#if 0	      /* This error check caught useful cases such as		 #define foo(x,y) bar(x(y,0), y)		 foo(foo, baz)  */	      if (traditional)		error ("recursive use of macro `%s'", hp->name);#endif	      if (output_marks) {		check_expand (op, limit - ibp + 2);		*obp++ = '\n';		*obp++ = '-';	      }	      break;	    }	    /* If macro wants an arglist, verify that a '(' follows.	       first skip all whitespace, copying it to the output	       after the macro name.  Then, if there is no '(',	       decide this is not a macro call and leave things that way.  */	    if ((hp->type == T_MACRO || hp->type == T_DISABLED)		&& hp->value.defn->nargs >= 0)	      {		while (1) {		  /* Scan forward over whitespace, copying it to the output.  */		  if (ibp == limit && ip->macro != 0) {		    POPMACRO;		    RECACHE;		  }		  /* A comment: copy it unchanged or discard it.  */		  else if (*ibp == '/' && ibp+1 != limit && ibp[1] == '*') {		    if (put_out_comments) {		      *obp++ = '/';		      *obp++ = '*';		    } else if (! traditional) {		      *obp++ = ' ';		    }		    ibp += 2;		    while (ibp + 1 != limit			   && !(ibp[0] == '*' && ibp[1] == '/')) {		      /* We need not worry about newline-marks,			 since they are never found in comments.  */		      if (*ibp == '\n') {			/* Newline in a file.  Count it.  */			++ip->lineno;			++op->lineno;		      }		      if (put_out_comments)			*obp++ = *ibp++;		      else			ibp++;		    }		    ibp += 2;		    if (put_out_comments) {		      *obp++ = '*';		      *obp++ = '/';		    }		  }		  else if (is_space[*ibp]) {		    *obp++ = *ibp++;		    if (ibp[-1] == '\n') {		      if (ip->macro == 0) {			/* Newline in a file.  Count it.  */			++ip->lineno;			++op->lineno;		      } else if (!output_marks) {			/* A newline mark, and we don't want marks			   in the output.  If it is newline-hyphen,			   discard it entirely.  Otherwise, it is			   newline-whitechar, so keep the whitechar.  */			obp--;			if (*ibp == '-')			  ibp++;			else {			  if (*ibp == '\n')			    ++op->lineno;			  *obp++ = *ibp++;			}		      } else {			/* A newline mark; copy both chars to the output.  */			*obp++ = *ibp++;		      }		    }		  }		  else break;		}		if (*ibp != '(')		  break;	      }	    /* This is now known to be a macro call.	       Discard the macro name from the output,	       along with any following whitespace just copied.  */	    obp = obufp_before_macroname;	    op->lineno = op_lineno_before_macroname;	    /* Expand the macro, reading arguments as needed,	       and push the expansion on the input stack.  */	    ip->bufp = ibp;	    op->bufp = obp;

⌨️ 快捷键说明

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