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

📄 cccp.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    macroexpand (hp, op);	    /* Reexamine input stack, since macroexpand has pushed	       a new level on it.  */	    obp = op->bufp;	    RECACHE;	    break;	  }hashcollision:	       ;	}			/* End hash-table-search loop */	ident_length = hash = 0; /* Stop collecting identifier */	redo_char = 0;	concatenated = 0;      }				/* End if (ident_length > 0) */    }				/* End switch */  }				/* End per-char loop */  /* Come here to return -- but first give an error message     if there was an unterminated successful conditional.  */ ending:  if (if_stack != ip->if_stack) {    char *str;    switch (if_stack->type) {    case T_IF:      str = "if";      break;    case T_IFDEF:      str = "ifdef";      break;    case T_IFNDEF:      str = "ifndef";      break;    case T_ELSE:      str = "else";      break;    case T_ELIF:      str = "elif";      break;    }    error_with_line (line_for_error (if_stack->lineno),		     "unterminated #%s conditional", str);  }  if_stack = ip->if_stack;}/* * Rescan a string into a temporary buffer and return the result * as a FILE_BUF.  Note this function returns a struct, not a pointer. * * OUTPUT_MARKS nonzero means keep Newline markers found in the input * and insert such markers when appropriate.  See `rescan' for details. * OUTPUT_MARKS is 1 for macroexpanding a macro argument separately * before substitution; it is 0 for other uses. */FILE_BUFexpand_to_temp_buffer (buf, limit, output_marks)     U_CHAR *buf, *limit;     int output_marks;{  register FILE_BUF *ip;  FILE_BUF obuf;  int length = limit - buf;  U_CHAR *buf1;  int odepth = indepth;  if (length < 0)    abort ();  /* Set up the input on the input stack.  */  buf1 = (U_CHAR *) alloca (length + 1);  {    register U_CHAR *p1 = buf;    register U_CHAR *p2 = buf1;    while (p1 != limit)      *p2++ = *p1++;  }  buf1[length] = 0;  /* Set up to receive the output.  */  obuf.length = length * 2 + 100; /* Usually enough.  Why be stingy?  */  obuf.bufp = obuf.buf = (U_CHAR *) xmalloc (obuf.length);  obuf.fname = 0;  obuf.macro = 0;  obuf.free_ptr = 0;  CHECK_DEPTH ({return obuf;});  ++indepth;  ip = &instack[indepth];  ip->fname = 0;  ip->macro = 0;  ip->free_ptr = 0;  ip->length = length;  ip->buf = ip->bufp = buf1;  ip->if_stack = if_stack;  ip->lineno = obuf.lineno = 1;  /* Scan the input, create the output.  */  rescan (&obuf, output_marks);  /* Pop input stack to original state.  */  --indepth;  if (indepth != odepth)    abort ();  /* Record the output.  */  obuf.length = obuf.bufp - obuf.buf;  return obuf;}/* * Process a # directive.  Expects IP->bufp to point to the '#', as in * `#define foo bar'.  Passes to the command handler * (do_define, do_include, etc.): the addresses of the 1st and * last chars of the command (starting immediately after the # * keyword), plus op and the keyword table pointer.  If the command * contains comments it is copied into a temporary buffer sans comments * and the temporary buffer is passed to the command handler instead. * Likewise for backslash-newlines. * * Returns nonzero if this was a known # directive. * Otherwise, returns zero, without advancing the input pointer. */inthandle_directive (ip, op)     FILE_BUF *ip, *op;{  register U_CHAR *bp, *cp;  register struct directive *kt;  register int ident_length;  U_CHAR *resume_p;  /* Nonzero means we must copy the entire command     to get rid of comments or backslash-newlines.  */  int copy_command = 0;  U_CHAR *ident, *after_ident;  bp = ip->bufp;  /* Skip whitespace and \-newline.  */  while (1) {    if (is_hor_space[*bp])      bp++;    else if (*bp == '/' && (newline_fix (bp + 1), bp[1]) == '*') {      ip->bufp = bp;      skip_to_end_of_comment (ip, &ip->lineno);      bp = ip->bufp;    } else if (*bp == '\\' && bp[1] == '\n') {      bp += 2; ip->lineno++;    } else break;  }  /* Now find end of directive name.     If we encounter a backslash-newline, exchange it with any following     symbol-constituents so that we end up with a contiguous name.  */  cp = bp;  while (1) {    if (is_idchar[*cp])      cp++;    else {      if (*cp == '\\' && cp[1] == '\n')	name_newline_fix (cp);      if (is_idchar[*cp])	cp++;      else break;    }  }  ident_length = cp - bp;  ident = bp;  after_ident = cp;  /* A line of just `#' becomes blank.  */  if (ident_length == 0 && *after_ident == '\n') {    ip->bufp = after_ident;    return 1;  }  /*   * Decode the keyword and call the appropriate expansion   * routine, after moving the input pointer up to the next line.   */  for (kt = directive_table; kt->length > 0; kt++) {    if (kt->length == ident_length && !strncmp (kt->name, ident, ident_length)) {      register U_CHAR *buf;      register U_CHAR *limit = ip->buf + ip->length;      int unterminated = 0;      /* Nonzero means do not delete comments within the directive.	 #define needs this when -traditional.  */      int keep_comments = traditional && kt->traditional_comments;      /* Find the end of this command (first newline not backslashed	 and not in a string or comment).	 Set COPY_COMMAND if the command must be copied	 (it contains a backslash-newline or a comment).  */      buf = bp = after_ident;      while (bp < limit) {	register U_CHAR c = *bp++;	switch (c) {	case '\\':	  if (bp < limit) {	    if (*bp == '\n') {	      ip->lineno++;	      copy_command = 1;	    }	    bp++;	  }	  break;	case '\'':	case '\"':	  bp = skip_quoted_string (bp - 1, limit, ip->lineno, &ip->lineno, &copy_command, &unterminated);	  /* Don't bother calling the directive if we already got an error	     message due to unterminated string.  Skip everything and pretend	     we called the directive.  */	  if (unterminated) {	    if (traditional) {	      /* Traditional preprocessing permits unterminated strings.  */	      ip->bufp = bp;	      goto endloop1;	    }	    ip->bufp = bp;	    return 1;	  }	  break;	  /* <...> is special for #include.  */	case '<':	  if (!kt->angle_brackets)	    break;	  while (*bp && *bp != '>') bp++;	  break;	case '/':	  if (*bp == '\\' && bp[1] == '\n')	    newline_fix (bp);	  if (*bp == '*'	      || (cplusplus && *bp == '/')) {	    U_CHAR *obp = bp - 1;	    ip->bufp = bp + 1;	    skip_to_end_of_comment (ip, &ip->lineno);	    bp = ip->bufp;	    /* No need to copy the command because of a comment at the end;	       just don't include the comment in the directive.  */	    if (bp == limit || *bp == '\n') {	      bp = obp;	      goto endloop1;	    }	    /* Don't remove the comments if -traditional.  */	    if (! keep_comments)	      copy_command++;	  }	  break;	case '\n':	  --bp;		/* Point to the newline */	  ip->bufp = bp;	  goto endloop1;	}      }      ip->bufp = bp;    endloop1:      resume_p = ip->bufp;      /* BP is the end of the directive.	 RESUME_P is the next interesting data after the directive.	 A comment may come between.  */      if (copy_command) {	register U_CHAR *xp = buf;	/* Need to copy entire command into temp buffer before dispatching */	cp = (U_CHAR *) alloca (bp - buf + 5); /* room for cmd plus						  some slop */	buf = cp;	/* Copy to the new buffer, deleting comments	   and backslash-newlines (and whitespace surrounding the latter).  */	while (xp < bp) {	  register U_CHAR c = *xp++;	  *cp++ = c;	  switch (c) {	  case '\n':	    break;	    /* <...> is special for #include.  */	  case '<':	    if (!kt->angle_brackets)	      break;	    while (xp < bp && c != '>') {	      c = *xp++;	      if (c == '\\' && xp < bp && *xp == '\n')		xp++, ip->lineno++;	      else		*cp++ = c;	    }	    break;	  case '\\':	    if (*xp == '\n') {	      xp++;	      cp--;	      if (cp != buf && is_space[cp[-1]]) {		while (cp != buf && is_space[cp[-1]]) cp--;		cp++;		SKIP_WHITE_SPACE (xp);	      } else if (is_space[*xp]) {		*cp++ = *xp++;		SKIP_WHITE_SPACE (xp);	      }	    } else {	      *cp++ = *xp++;	    }	    break;	  case '\'':	  case '\"':	    {	      register U_CHAR *bp1		= skip_quoted_string (xp - 1, limit, ip->lineno, 0, 0, 0);	      while (xp != bp1)		*cp++ = *xp++;	    }	    break;	  case '/':	    if (*xp == '*'		|| (cplusplus && *xp == '/')) {	      ip->bufp = xp + 1;	      skip_to_end_of_comment (ip, 0);	      if (keep_comments)		while (xp != ip->bufp)		  *cp++ = *xp++;	      /* Delete or replace the slash.  */	      else if (traditional)		cp--;	      else		cp[-1] = ' ';	      xp = ip->bufp;	    }	  }	}	/* Null-terminate the copy.  */	*cp = 0;      }      else	cp = bp;      ip->bufp = resume_p;      /* Some directives should be written out for cc1 to process,	 just as if they were not defined.  */      if (kt->pass_thru) {        int len;	/* Output directive name.  */        check_expand (op, kt->length+1);        *op->bufp++ = '#';        bcopy (kt->name, op->bufp, kt->length);        op->bufp += kt->length;	/* Output arguments.  */        len = (cp - buf);        check_expand (op, len);        bcopy (buf, op->bufp, len);        op->bufp += len;      }      /* Call the appropriate command handler.  buf now points to	 either the appropriate place in the input buffer, or to	 the temp buffer if it was necessary to make one.  cp	 points to the first char after the contents of the (possibly	 copied) command, in either case. */      (*kt->func) (buf, cp, op, kt);      check_expand (op, ip->length - (ip->bufp - ip->buf));      return 1;    }  }  return 0;}static char *monthnames[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",			     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",			    };/* * expand things like __FILE__.  Place the expansion into the output * buffer *without* rescanning. */special_symbol (hp, op)     HASHNODE *hp;     FILE_BUF *op;{  char *buf;  time_t t;  int i, len;  int true_indepth;  FILE_BUF *ip = NULL;  static struct tm *timebuf = NULL;  struct tm *localtime ();  int paren = 0;		/* For special `defined' keyword */  for (i = indepth; i >= 0; i--)    if (instack[i].fname != NULL) {      ip = &instack[i];      break;    }  if (ip == NULL) {    error ("cccp error: not in any file?!");    return;			/* the show must go on */  }  switch (hp->type) {  case T_FILE:  case T_BASE_FILE:    {      char *string;      if (hp->type == T_FILE)	string = ip->fname;      else	string = instack[0].fname;      if (string)	{	  buf = (char *) alloca (3 + strlen (string));	  sprintf (buf, "\"%s\"", string);	}      else	buf = "\"\"";      break;    }  case T_INCLUDE_LEVEL:    true_indepth = 0;    for (i = indepth; i >= 0; i--)      if (instack[i].fname != NULL)        true_indepth++;    buf = (char *) alloca (8);	/* Eigth bytes ought to be more than enough */    sprintf (buf, "%d", true_indepth - 1);    break;  case T_VERSION:    buf = (char *) alloca (3 + strlen (version_string));    sprintf (buf, "\"%s\"", version_string);    break;  case T_CONST:    buf = (char *) alloca (4 * sizeof (int));    sprintf (buf, "%d", hp->value.ival);    break;  case T_SPECLINE:    buf = (char *) alloca (10);    sprintf (buf, "%d", ip->lineno);    break;  case T_DATE:  case T_TIME:    if (timebuf == NULL) {      t = time (0);      timebuf = localtime (&t);    }    buf = (char *) alloca (20);    if (hp->type == T_DATE)      sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf-

⌨️ 快捷键说明

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