📄 cpplib.c
字号:
long *linep; long *colp;{ while (buf < limit) { U_CHAR ch = *buf++; if (ch == '\n') (*linep)++, (*colp) = 1; else (*colp)++; }}/* Move line_base forward, updating lineno and colno. */static voidupdate_position (pbuf) register cpp_buffer *pbuf;{ unsigned char *old_pos = pbuf->buf + pbuf->line_base; unsigned char *new_pos = pbuf->cur; register struct parse_marker *mark; for (mark = pbuf->marks; mark != NULL; mark = mark->next) { if (pbuf->buf + mark->position < new_pos) new_pos = pbuf->buf + mark->position; } pbuf->line_base += new_pos - old_pos; adjust_position (old_pos, new_pos, &pbuf->lineno, &pbuf->colno);}voidcpp_buf_line_and_col (pbuf, linep, colp) register cpp_buffer *pbuf; long *linep, *colp;{ long dummy; if (colp == NULL) colp = &dummy; if (pbuf) { *linep = pbuf->lineno; *colp = pbuf->colno; adjust_position (pbuf->buf + pbuf->line_base, pbuf->cur, linep, colp); } else { *linep = 0; *colp = 0; }}/* Return the cpp_buffer that corresponds to a file (not a macro). */cpp_buffer*cpp_file_buffer (pfile) cpp_reader *pfile;{ cpp_buffer *ip = CPP_BUFFER (pfile); for ( ; ip != CPP_NULL_BUFFER (pfile); ip = CPP_PREV_BUFFER (ip)) if (ip->fname != NULL) return ip; return NULL;}static longcount_newlines (buf, limit) register U_CHAR *buf; register U_CHAR *limit;{ register long count = 0; while (buf < limit) { U_CHAR ch = *buf++; if (ch == '\n') count++; } return count;}/* * write out a #line command, for instance, after an #include file. * If CONDITIONAL is nonzero, we can omit the #line if it would * appear to be a no-op, and we can output a few newlines instead * if we want to increase the line number by a small amount. * FILE_CHANGE says whether we are entering a file, leaving, or neither. */static voidoutput_line_command (pfile, conditional, file_change) cpp_reader *pfile; int conditional; enum file_change_code file_change;{ int len; char *line_cmd_buf, *line_end; long line, col; cpp_buffer *ip = CPP_BUFFER (pfile); if (ip->fname == NULL || CPP_OPTIONS (pfile)->no_output) { return; } update_position (ip); line = CPP_BUFFER (pfile)->lineno; col = CPP_BUFFER (pfile)->colno; adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col); if (CPP_OPTIONS (pfile)->no_line_commands) return; if (conditional) { if (line == pfile->lineno) return; /* If the inherited line number is a little too small, output some newlines instead of a #line command. */ if (line > pfile->lineno && line < pfile->lineno + 8) { CPP_RESERVE (pfile, 20); while (line > pfile->lineno) { CPP_PUTC_Q (pfile, '\n'); pfile->lineno++; } return; } }#if 0 /* Don't output a line number of 0 if we can help it. */ if (ip->lineno == 0 && ip->bufp - ip->buf < ip->length && *ip->bufp == '\n') { ip->lineno++; ip->bufp++; }#endif CPP_RESERVE (pfile, 4 * strlen (ip->nominal_fname) + 50); {#ifdef OUTPUT_LINE_COMMANDS static char sharp_line[] = "#line ";#else static char sharp_line[] = "# ";#endif CPP_PUTS_Q (pfile, sharp_line, sizeof(sharp_line)-1); } sprintf (CPP_PWRITTEN (pfile), "%d ", line); CPP_ADJUST_WRITTEN (pfile, strlen (CPP_PWRITTEN (pfile))); quote_string (pfile, ip->nominal_fname); if (file_change != same_file) { CPP_PUTC_Q (pfile, ' '); CPP_PUTC_Q (pfile, file_change == enter_file ? '1' : '2'); } /* Tell cc1 if following text comes from a system header file. */ if (ip->system_header_p) { CPP_PUTC_Q (pfile, ' '); CPP_PUTC_Q (pfile, '3'); }#ifndef NO_IMPLICIT_EXTERN_C /* Tell cc1plus if following text should be treated as C. */ if (ip->system_header_p == 2 && CPP_OPTIONS (pfile)->cplusplus) { CPP_PUTC_Q (pfile, ' '); CPP_PUTC_Q (pfile, '4'); }#endif CPP_PUTC_Q (pfile, '\n'); pfile->lineno = line;}/* * Parse a macro argument and append the info on PFILE's token_buffer. * REST_ARGS means to absorb the rest of the args. * Return nonzero to indicate a syntax error. */static enum cpp_tokenmacarg (pfile, rest_args) cpp_reader *pfile; int rest_args;{ int paren = 0; enum cpp_token token; long arg_start = CPP_WRITTEN (pfile); char save_put_out_comments = CPP_OPTIONS (pfile)->put_out_comments; CPP_OPTIONS (pfile)->put_out_comments = 0; /* Try to parse as much of the argument as exists at this input stack level. */ pfile->no_macro_expand++; for (;;) { token = cpp_get_token (pfile); switch (token) { case CPP_EOF: goto done; case CPP_POP: /* If we've hit end of file, it's an error (reported by caller). Ditto if it's the end of cpp_expand_to_buffer text. If we've hit end of macro, just continue. */ if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile))) goto done; break; case CPP_LPAREN: paren++; break; case CPP_RPAREN: if (--paren < 0) goto found; break; case CPP_COMMA: /* if we've returned to lowest level and we aren't absorbing all args */ if (paren == 0 && rest_args == 0) goto found; break; found: /* Remove ',' or ')' from argument buffer. */ CPP_ADJUST_WRITTEN (pfile, -1); goto done; default: ; } } done: CPP_OPTIONS (pfile)->put_out_comments = save_put_out_comments; pfile->no_macro_expand--; return token;}/* Turn newlines to spaces in the string of length LENGTH at START, except inside of string constants. The string is copied into itself with its beginning staying fixed. */static intchange_newlines (start, length) U_CHAR *start; int length;{ register U_CHAR *ibp; register U_CHAR *obp; register U_CHAR *limit; register int c; ibp = start; limit = start + length; obp = start; while (ibp < limit) { *obp++ = c = *ibp++; switch (c) { case '\'': case '\"': /* Notice and skip strings, so that we don't delete newlines in them. */ { int quotec = c; while (ibp < limit) { *obp++ = c = *ibp++; if (c == quotec) break; if (c == '\n' && quotec == '\'') break; } } break; } } return obp - start;}static struct tm *timestamp (pfile) cpp_reader *pfile;{ if (!pfile->timebuf) { time_t t = time ((time_t *)0); pfile->timebuf = localtime (&t); } return pfile->timebuf;}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. */static voidspecial_symbol (hp, pfile) HASHNODE *hp; cpp_reader *pfile;{ char *buf; int i, len; int true_indepth; cpp_buffer *ip = NULL; struct tm *timebuf; int paren = 0; /* For special `defined' keyword */#if 0 if (pcp_outfile && pcp_inside_if && hp->type != T_SPEC_DEFINED && hp->type != T_CONST) cpp_error (pfile, "Predefined macro `%s' used inside `#if' during precompilation", hp->name);#endif for (ip = CPP_BUFFER (pfile); ; ip = CPP_PREV_BUFFER (ip)) { if (ip == NULL) { cpp_error (pfile, "cccp error: not in any file?!"); return; /* the show must go on */ } if (ip->fname != NULL) break; } switch (hp->type) { case T_FILE: case T_BASE_FILE: { char *string; if (hp->type == T_BASE_FILE) { while (CPP_PREV_BUFFER (ip)) ip = CPP_PREV_BUFFER (ip); } string = ip->nominal_fname; if (!string) string = ""; CPP_RESERVE (pfile, 3 + 4 * strlen (string)); quote_string (pfile, string); return; } case T_INCLUDE_LEVEL: true_indepth = 0; for (ip = CPP_BUFFER (pfile); ip != NULL; ip = CPP_PREV_BUFFER (ip)) if (ip->fname != NULL) true_indepth++; buf = (char *) alloca (8); /* Eight 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;#ifndef NO_BUILTIN_SIZE_TYPE case T_SIZE_TYPE: buf = SIZE_TYPE; break;#endif#ifndef NO_BUILTIN_PTRDIFF_TYPE case T_PTRDIFF_TYPE: buf = PTRDIFF_TYPE; break;#endif case T_WCHAR_TYPE: buf = CPP_WCHAR_TYPE (pfile); break; case T_USER_LABEL_PREFIX_TYPE: buf = USER_LABEL_PREFIX; break; case T_REGISTER_PREFIX_TYPE: buf = REGISTER_PREFIX; break; case T_CONST: buf = (char *) alloca (4 * sizeof (int)); sprintf (buf, "%d", hp->value.ival);#if 0 if (pcp_inside_if && pcp_outfile) /* Output a precondition for this macro use */ fprintf (pcp_outfile, "#define %s %d\n", hp->name, hp->value.ival);#endif break; case T_SPECLINE: { long line = ip->lineno; long col = ip->colno; adjust_position (CPP_LINE_BASE (ip), ip->cur, &line, &col); buf = (char *) alloca (10); sprintf (buf, "%d", line); } break; case T_DATE: case T_TIME: buf = (char *) alloca (20); timebuf = timestamp (pfile); if (hp->type == T_DATE) sprintf (buf, "\"%s %2d %4d\"", monthnames[timebuf->tm_mon], timebuf->tm_mday, timebuf->tm_year + 1900); else sprintf (buf, "\"%02d:%02d:%02d\"", timebuf->tm_hour, timebuf->tm_min, timebuf->tm_sec); break; case T_SPEC_DEFINED: buf = " 0 "; /* Assume symbol is not defined */ ip = CPP_BUFFER (pfile); SKIP_WHITE_SPACE (ip->cur); if (*ip->cur == '(') { paren++; ip->cur++; /* Skip over the paren */ SKIP_WHITE_SPACE (ip->cur); } if (!is_idstart[*ip->cur]) goto oops; if (hp = cpp_lookup (pfile, ip->cur, -1, -1)) {#if 0 if (pcp_outfile && pcp_inside_if && (hp->type == T_CONST || (hp->type == T_MACRO && hp->value.defn->predefined))) /* Output a precondition for this macro use. */ fprintf (pcp_outfile, "#define %s\n", hp->name);#endif buf = " 1 "; }#if 0 else if (pcp_outfile && pcp_inside_if) { /* Output a precondition for this macro use */ U_CHAR *cp = ip->bufp; fprintf (pcp_outfile, "#undef "); while (is_idchar[*cp]) /* Ick! */ fputc (*cp++, pcp_outfile); putc ('\n', pcp_outfile); }#endif while (is_idchar[*ip->cur]) ++ip->cur; SKIP_WHITE_SPACE (ip->cur); if (paren) { if (*ip->cur != ')') goto oops; ++ip->cur; } break; oops: cpp_error (pfile, "`defined' without an identifier"); break; default: cpp_error (pfile, "cccp error: invalid special hash type"); /* time for gdb */ abort (); } len = strlen (buf); CPP_RESERVE (pfile, len + 1); CPP_PUTS_Q (pfile, buf, len); CPP_NUL_TERMINATE_Q (pfile); return;}/* Initialize the built-in macros. */static voidinitialize_builtins (pfile) cpp_reader *pfile;{ install ("__LINE__", -1, T_SPECLINE, 0, 0, -1); install ("__DATE__", -1, T_DATE, 0, 0, -1); install ("__FILE__", -1, T_FILE, 0, 0, -1); install ("__BASE_FILE__", -1, T_BASE_FILE, 0, 0, -1); install ("__INCLUDE_LEVEL__", -1, T_INCLUDE_LEVEL, 0, 0, -1); install ("__VERSION__", -1, T_VERSION, 0, 0, -1);#ifndef NO_BUILTIN_SIZE_TYPE install ("__SIZE_TYPE__", -1, T_SIZE_TYPE, 0, 0, -1);#endif#ifndef NO_BUILTIN_PTRDIFF_TYPE install ("__PTRDIFF_TYPE__ ", -1, T_PTRDIFF_TYPE, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -