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

📄 cccp.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
      deps_output (in_fname, 0);      deps_output (" ", 0);    }  }  file_size_and_mode (f, &st_mode, &st_size);  fp->fname = in_fname;  fp->lineno = 1;  /* JF all this is mine about reading pipes and ttys */  if (!S_ISREG (st_mode)) {    /* Read input from a file that is not a normal disk file.       We cannot preallocate a buffer with the correct size,       so we must read in the file a piece at the time and make it bigger.  */    int size;    int bsize;    int cnt;    U_CHAR *bufp;    bsize = 2000;    size = 0;    fp->buf = (U_CHAR *) xmalloc (bsize + 2);    bufp = fp->buf;    for (;;) {      cnt = read (f, bufp, bsize - size);      if (cnt < 0) goto perror;	/* error! */      if (cnt == 0) break;	/* End of file */      size += cnt;      bufp += cnt;      if (bsize == size) {	/* Buffer is full! */        bsize *= 2;        fp->buf = (U_CHAR *) xrealloc (fp->buf, bsize + 2);	bufp = fp->buf + size;	/* May have moved */      }    }    fp->length = size;  } else {    /* Read a file whose size we can determine in advance.       For the sake of VMS, st_size is just an upper bound.  */    long i;    fp->length = 0;    fp->buf = (U_CHAR *) xmalloc (st_size + 2);    while (st_size > 0) {      i = read (f, fp->buf + fp->length, st_size);      if (i <= 0) {        if (i == 0) break;	goto perror;      }      fp->length += i;      st_size -= i;    }  }  fp->bufp = fp->buf;  fp->if_stack = if_stack;  /* Make sure data ends with a newline.  And put a null after it.  */  if (fp->length > 0 && fp->buf[fp->length-1] != '\n')    fp->buf[fp->length++] = '\n';  fp->buf[fp->length] = '\0';    /* Unless inhibited, convert trigraphs in the input.  */  if (!no_trigraphs)    trigraph_pcp (fp);  /* Now that we know the input file is valid, open the output.  */  if (!out_fname || !strcmp (out_fname, ""))    out_fname = "stdout";  else if (! freopen (out_fname, "w", stdout))    pfatal_with_name (out_fname);  output_line_command (fp, &outbuf, 0, same_file);  /* Scan the input, processing macros and directives.  */  rescan (&outbuf, 0);  /* Now we have processed the entire input     Write whichever kind of output has been requested.  */  if (dump_macros)    dump_all_macros ();  else if (! inhibit_output && deps_stream != stdout) {    if (write (fileno (stdout), outbuf.buf, outbuf.bufp - outbuf.buf) < 0)      fatal ("I/O error on output");  }  if (print_deps) {    fputs (deps_buffer, deps_stream);    putc ('\n', deps_stream);    if (deps_stream != stdout) {      fclose (deps_stream);      if (ferror (deps_stream))	fatal ("I/O error on output");    }  }  if (ferror (stdout))    fatal ("I/O error on output");  if (errors)    exit (FATAL_EXIT_CODE);  exit (SUCCESS_EXIT_CODE); perror:  pfatal_with_name (in_fname);}/* Pre-C-Preprocessor to translate ANSI trigraph idiocy in BUF   before main CCCP processing.  Name `pcp' is also in honor of the   drugs the trigraph designers must have been on.   Using an extra pass through the buffer takes a little extra time,   but is infinitely less hairy than trying to handle ??/" inside   strings, etc. everywhere, and also makes sure that trigraphs are   only translated in the top level of processing. */trigraph_pcp (buf)     FILE_BUF *buf;{  register U_CHAR c, *fptr, *bptr, *sptr;  int len;  fptr = bptr = sptr = buf->buf;  while ((sptr = (U_CHAR *) index (sptr, '?')) != NULL) {    if (*++sptr != '?')      continue;    switch (*++sptr) {      case '=':      c = '#';      break;    case '(':      c = '[';      break;    case '/':      c = '\\';      break;    case ')':      c = ']';      break;    case '\'':      c = '^';      break;    case '<':      c = '{';      break;    case '!':      c = '|';      break;    case '>':      c = '}';      break;    case '-':      c  = '~';      break;    case '?':      sptr--;      continue;    default:      continue;    }    len = sptr - fptr - 2;    if (bptr != fptr && len > 0)      bcopy (fptr, bptr, len);	/* BSD doc says bcopy () works right				   for overlapping strings.  In ANSI				   C, this will be memmove (). */    bptr += len;    *bptr++ = c;    fptr = ++sptr;  }  len = buf->length - (fptr - buf->buf);  if (bptr != fptr && len > 0)    bcopy (fptr, bptr, len);  buf->length -= fptr - bptr;  buf->buf[buf->length] = '\0';  if (warn_trigraphs && fptr != bptr)    warning ("%d trigraph(s) encountered", (fptr - bptr) / 2);}/* Move all backslash-newline pairs out of embarrassing places.   Exchange all such pairs following BP   with any potentially-embarrasing characters that follow them.   Potentially-embarrassing characters are / and *   (because a backslash-newline inside a comment delimiter   would cause it not to be recognized).  */newline_fix (bp)     U_CHAR *bp;{  register U_CHAR *p = bp;  register int count = 0;  /* First count the backslash-newline pairs here.  */  while (*p++ == '\\' && *p++ == '\n')    count++;  p = bp + count * 2;  /* Exit if what follows the backslash-newlines is not embarrassing.  */  if (count == 0 || (*p != '/' && *p != '*'))    return;  /* Copy all potentially embarrassing characters     that follow the backslash-newline pairs     down to where the pairs originally started.  */  while (*p == '*' || *p == '/')    *bp++ = *p++;  /* Now write the same number of pairs after the embarrassing chars.  */  while (count-- > 0) {    *bp++ = '\\';    *bp++ = '\n';  }}/* Like newline_fix but for use within a directive-name.   Move any backslash-newlines up past any following symbol constituents.  */name_newline_fix (bp)     U_CHAR *bp;{  register U_CHAR *p = bp;  register int count = 0;  /* First count the backslash-newline pairs here.  */  while (*p++ == '\\' && *p++ == '\n')    count++;  p = bp + count * 2;  /* What follows the backslash-newlines is not embarrassing.  */  if (count == 0 || !is_idchar[*p])    return;  /* Copy all potentially embarrassing characters     that follow the backslash-newline pairs     down to where the pairs originally started.  */  while (is_idchar[*p])    *bp++ = *p++;  /* Now write the same number of pairs after the embarrassing chars.  */  while (count-- > 0) {    *bp++ = '\\';    *bp++ = '\n';  }}/* * The main loop of the program. * * Read characters from the input stack, transferring them to the * output buffer OP. * * Macros are expanded and push levels on the input stack. * At the end of such a level it is popped off and we keep reading. * At the end of any other kind of level, we return. * #-directives are handled, except within macros. * * If OUTPUT_MARKS is nonzero, keep Newline markers found in the input * and insert them when appropriate.  This is set while scanning macro * arguments before substitution.  It is zero when scanning for final output. *   There are three types of Newline markers: *   * Newline -  follows a macro name that was not expanded *     because it appeared inside an expansion of the same macro. *     This marker prevents future expansion of that identifier. *     When the input is rescanned into the final output, these are deleted. *     These are also deleted by ## concatenation. *   * Newline Space (or Newline and any other whitespace character) *     stands for a place that tokens must be separated or whitespace *     is otherwise desirable, but where the ANSI standard specifies there *     is no whitespace.  This marker turns into a Space (or whichever other *     whitespace char appears in the marker) in the final output, *     but it turns into nothing in an argument that is stringified with #. *     Such stringified arguments are the only place where the ANSI standard *     specifies with precision that whitespace may not appear. * * During this function, IP->bufp is kept cached in IBP for speed of access. * Likewise, OP->bufp is kept in OBP.  Before calling a subroutine * IBP, IP and OBP must be copied back to memory.  IP and IBP are * copied back with the RECACHE macro.  OBP must be copied back from OP->bufp * explicitly, and before RECACHE, since RECACHE uses OBP. */rescan (op, output_marks)     FILE_BUF *op;     int output_marks;{  /* Character being scanned in main loop.  */  register U_CHAR c;  /* Length of pending accumulated identifier.  */  register int ident_length = 0;  /* Hash code of pending accumulated identifier.  */  register int hash = 0;  /* Current input level (&instack[indepth]).  */  FILE_BUF *ip;  /* Pointer for scanning input.  */  register U_CHAR *ibp;  /* Pointer to end of input.  End of scan is controlled by LIMIT.  */  register U_CHAR *limit;  /* Pointer for storing output.  */  register U_CHAR *obp;  /* REDO_CHAR is nonzero if we are processing an identifier     after backing up over the terminating character.     Sometimes we process an identifier without backing up over     the terminating character, if the terminating character     is not special.  Backing up is done so that the terminating character     will be dispatched on again once the identifier is dealt with.  */  int redo_char = 0;  /* 1 if within an identifier inside of which a concatenation     marker (Newline -) has been seen.  */  int concatenated = 0;  /* While scanning a comment or a string constant,     this records the line it started on, for error messages.  */  int start_line;  /* Record position of last `real' newline.  */  U_CHAR *beg_of_line;/* Pop the innermost input stack level, assuming it is a macro expansion.  */#define POPMACRO \do { ip->macro->type = T_MACRO;		\     if (ip->free_ptr) free (ip->free_ptr);	\     --indepth; } while (0)/* Reload `rescan's local variables that describe the current   level of the input stack.  */#define RECACHE  \do { ip = &instack[indepth];		\     ibp = ip->bufp;			\     limit = ip->buf + ip->length;	\     op->bufp = obp;			\     check_expand (op, limit - ibp);	\     beg_of_line = 0;			\     obp = op->bufp; } while (0)  if (no_output && instack[indepth].fname != 0)    skip_if_group (&instack[indepth], 1);  obp = op->bufp;  RECACHE;  beg_of_line = ibp;  /* Our caller must always put a null after the end of     the input at each input stack level.  */  if (*limit != 0)    abort ();  while (1) {    c = *ibp++;    *obp++ = c;    switch (c) {    case '\\':      if (ibp >= limit)	break;      if (*ibp == '\n') {	/* Always merge lines ending with backslash-newline,	   even in middle of identifier.  */	++ibp;	++ip->lineno;	--obp;		/* remove backslash from obuf */	break;      }      /* Otherwise, backslash suppresses specialness of following char,	 so copy it here to prevent the switch from seeing it.	 But first get any pending identifier processed.  */      if (ident_length > 0)	goto specialchar;      *obp++ = *ibp++;      break;    case '#':      /* If this is expanding a macro definition, don't recognize	 preprocessor directives.  */      if (ip->macro != 0)	goto randomchar;      if (ident_length)	goto specialchar;      /* # keyword: a # must be first nonblank char on the line */      if (beg_of_line == 0)	goto randomchar;      {	U_CHAR *bp;	/* Scan from start of line, skipping whitespace, comments	   and backslash-newlines, and see if we reach this #.	   If not, this # is not special.  */	bp = beg_of_line;	while (1) {	  if (is_hor_space[*bp])	    bp++;	  else if (*bp == '\\' && bp[1] == '\n')	    bp += 2;	  else if (*bp == '/' && (newline_fix (bp + 1), bp[1]) == '*') {	    bp += 2;	    while (!(*bp == '*' && (newline_fix (bp + 1), bp[1]) == '/'))	      bp++;	    bp += 1;	  }	  else if (cplusplus && *bp == '/' && (newline_fix (bp + 1), bp[1]) == '/') {	    bp += 2;	    while (*bp++ != '\n') ;	  }	  else break;	}	if (bp + 1 != ibp)	  goto randomchar;      }      /* This # can start a directive.  */      --obp;		/* Don't copy the '#' */      ip->bufp = ibp;      op->bufp = obp;      if (! handle_directive (ip, op)) {#ifdef USE_C_ALLOCA	alloca (0);#endif	/* Not a known directive: treat it as ordinary text.	   IP, OP, IBP, etc. have not been changed.  */	if (no_output && instack[indepth].fname) {	  /* If not generating expanded output,	     what we do with ordinary text is skip it.	     Discard everything until next # directive.  */	  skip_if_group (&instack[indepth], 1);	  RECACHE;	  beg_of_line = ibp;	  break;	}	++obp;		/* Copy the '#' after all */	goto randomchar;      }#ifdef USE_C_ALLOCA      alloca (0);#endif      /* A # directive has been successfully processed.  */      /* If not generating expanded output, ignore everything until	 next # directive.  */      if (no_output && instack[indepth].fname)	skip_if_group (&instack[indepth], 1);      obp = op->bufp;      RECACHE;      beg_of_line = ibp;      break;    case '\"':			/* skip quoted string */    case '\'':      /* A single quoted string is treated like a double -- some	 programs (e.g., troff) are perverse this way */      if (ident_length)	goto specialchar;      start_line = ip->lineno;      /* Skip ahead to a matching quote.  */      while (1) {	if (ibp >= limit) {	  if (traditional) {	    if (ip->macro != 0) {	      /* try harder: this string crosses a macro expansion boundary */	      POPMACRO;	      RECACHE;	      continue;	    }	  } else	    error_with_line (line_for_error (start_line),

⌨️ 快捷键说明

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