📄 cpplib.c
字号:
if (isprint (c)) CPP_PUTC_Q (pfile, c); else { sprintf (CPP_PWRITTEN (pfile), "\\%03o", c); CPP_ADJUST_WRITTEN (pfile, 4); } break; case '\"': case '\\': CPP_PUTC_Q (pfile, '\\'); CPP_PUTC_Q (pfile, c); break; case '\0': CPP_PUTC_Q (pfile, '\"'); CPP_NUL_TERMINATE_Q (pfile); return; }}/* Make sure PFILE->token_buffer will hold at least N more chars. */voidcpp_grow_buffer (pfile, n) cpp_reader *pfile; long n;{ long old_written = CPP_WRITTEN (pfile); pfile->token_buffer_size = n + 2 * pfile->token_buffer_size; pfile->token_buffer = (U_CHAR*) xrealloc(pfile->token_buffer, pfile->token_buffer_size); CPP_SET_WRITTEN (pfile, old_written);}/* * process a given definition string, for initialization * If STR is just an identifier, define it with value 1. * If STR has anything after the identifier, then it should * be identifier=definition. */voidcpp_define (pfile, str) cpp_reader *pfile; U_CHAR *str;{ U_CHAR *buf, *p; buf = str; p = str; if (!is_idstart[*p]) { cpp_error (pfile, "malformed option `-D %s'", str); return; } while (is_idchar[*++p]) ; if (*p == 0) { buf = (U_CHAR *) alloca (p - buf + 4); strcpy ((char *)buf, str); strcat ((char *)buf, " 1"); } else if (*p != '=') { cpp_error (pfile, "malformed option `-D %s'", str); return; } else { U_CHAR *q; /* Copy the entire option so we can modify it. */ buf = (U_CHAR *) alloca (2 * strlen (str) + 1); strncpy (buf, str, p - str); /* Change the = to a space. */ buf[p - str] = ' '; /* Scan for any backslash-newline and remove it. */ p++; q = &buf[p - str]; while (*p) { if (*p == '\\' && p[1] == '\n') p += 2; else *q++ = *p++; } *q = 0; } do_define (pfile, NULL, buf, buf + strlen (buf));}/* Process the string STR as if it appeared as the body of a #assert. OPTION is the option name for which STR was the argument. */static voidmake_assertion (pfile, option, str) cpp_reader *pfile; char *option; U_CHAR *str;{ cpp_buffer *ip; struct directive *kt; U_CHAR *buf, *p, *q; /* Copy the entire option so we can modify it. */ buf = (U_CHAR *) alloca (strlen (str) + 1); strcpy ((char *) buf, str); /* Scan for any backslash-newline and remove it. */ p = q = buf; while (*p) {#if 0 if (*p == '\\' && p[1] == '\n') p += 2; else#endif *q++ = *p++; } *q = 0; p = buf; if (!is_idstart[*p]) { cpp_error (pfile, "malformed option `%s %s'", option, str); return; } while (is_idchar[*++p]) ; while (*p == ' ' || *p == '\t') p++; if (! (*p == 0 || *p == '(')) { cpp_error (pfile, "malformed option `%s %s'", option, str); return; } ip = cpp_push_buffer (pfile, buf, strlen (buf)); do_assert (pfile, NULL, NULL, NULL); cpp_pop_buffer (pfile);}/* Append a chain of `struct file_name_list's to the end of the main include chain. FIRST is the beginning of the chain to append, and LAST is the end. */static voidappend_include_chain (pfile, first, last) cpp_reader *pfile; struct file_name_list *first, *last;{ struct cpp_options *opts = CPP_OPTIONS (pfile); struct file_name_list *dir; if (!first || !last) return; if (opts->include == 0) opts->include = first; else opts->last_include->next = first; if (opts->first_bracket_include == 0) opts->first_bracket_include = first; for (dir = first; ; dir = dir->next) { int len = strlen (dir->fname) + INCLUDE_LEN_FUDGE; if (len > pfile->max_include_len) pfile->max_include_len = len; if (dir == last) break; } last->next = NULL; opts->last_include = last;}/* Add output to `deps_buffer' for the -M switch. STRING points to the text to be output. SPACER is ':' for targets, ' ' for dependencies, zero for text to be inserted literally. */static voiddeps_output (pfile, string, spacer) cpp_reader *pfile; char *string; int spacer;{ int size = strlen (string); if (size == 0) return;#ifndef MAX_OUTPUT_COLUMNS#define MAX_OUTPUT_COLUMNS 72#endif if (spacer && pfile->deps_column > 0 && (pfile->deps_column + size) > MAX_OUTPUT_COLUMNS) { deps_output (pfile, " \\\n ", 0); pfile->deps_column = 0; } if (pfile->deps_size + size + 8 > pfile->deps_allocated_size) { pfile->deps_allocated_size = (pfile->deps_size + size + 50) * 2; pfile->deps_buffer = (char *) xrealloc (pfile->deps_buffer, pfile->deps_allocated_size); } if (spacer == ' ' && pfile->deps_column > 0) pfile->deps_buffer[pfile->deps_size++] = ' '; bcopy (string, &pfile->deps_buffer[pfile->deps_size], size); pfile->deps_size += size; pfile->deps_column += size; if (spacer == ':') pfile->deps_buffer[pfile->deps_size++] = ':'; pfile->deps_buffer[pfile->deps_size] = 0;}/* Given a colon-separated list of file names PATH, add all the names to the search path for include files. */static voidpath_include (pfile, path) cpp_reader *pfile; char *path;{ char *p; p = path; if (*p) while (1) { char *q = p; char *name; struct file_name_list *dirtmp; /* Find the end of this name. */ while (*q != 0 && *q != PATH_SEPARATOR) q++; if (p == q) { /* An empty name in the path stands for the current directory. */ name = (char *) xmalloc (2); name[0] = '.'; name[1] = 0; } else { /* Otherwise use the directory that is named. */ name = (char *) xmalloc (q - p + 1); bcopy (p, name, q - p); name[q - p] = 0; } dirtmp = (struct file_name_list *) xmalloc (sizeof (struct file_name_list)); dirtmp->next = 0; /* New one goes on the end */ dirtmp->control_macro = 0; dirtmp->c_system_include_path = 0; dirtmp->fname = name; dirtmp->got_name_map = 0; append_include_chain (pfile, dirtmp, dirtmp); /* Advance past this name. */ p = q; if (*p == 0) break; /* Skip the colon. */ p++; }}voidinit_parse_options (opts) struct cpp_options *opts;{ bzero ((char *) opts, sizeof *opts); opts->in_fname = NULL; opts->out_fname = NULL; /* Initialize is_idchar to allow $. */ opts->dollars_in_ident = 1; initialize_char_syntax (opts); opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS > 0; opts->no_line_commands = 0; opts->no_trigraphs = 1; opts->put_out_comments = 0; opts->print_include_names = 0; opts->dump_macros = dump_none; opts->no_output = 0; opts->cplusplus = 0; opts->cplusplus_comments = 0; opts->verbose = 0; opts->objc = 0; opts->lang_asm = 0; opts->for_lint = 0; opts->chill = 0; opts->pedantic_errors = 0; opts->inhibit_warnings = 0; opts->warn_comments = 0; opts->warn_import = 1; opts->warnings_are_errors = 0;}enum cpp_tokennull_underflow (pfile) cpp_reader *pfile;{ return CPP_EOF;}intnull_cleanup (pbuf, pfile) cpp_buffer *pbuf; cpp_reader *pfile;{ return 0;}intmacro_cleanup (pbuf, pfile) cpp_buffer *pbuf; cpp_reader *pfile;{ HASHNODE *macro = (HASHNODE*)pbuf->data; if (macro->type == T_DISABLED) macro->type = T_MACRO; if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion) free (pbuf->buf); return 0;}intfile_cleanup (pbuf, pfile) cpp_buffer *pbuf; cpp_reader *pfile;{ if (pbuf->buf) { free (pbuf->buf); pbuf->buf = 0; } return 0;}static voidnewline_fix (pfile) cpp_reader *pfile;{#if 1 NEWLINE_FIX;#else register U_CHAR *p = bp; /* First count the backslash-newline pairs here. */ while (p[0] == '\\' && p[1] == '\n') p += 2; /* What follows the backslash-newlines is not embarrassing. */ if (*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 (bp < p) { *bp++ = '\\'; *bp++ = '\n'; }#endif}/* Assuming we have read '/'. If this is the start of a comment (followed by '*' or '/'), skip to the end of the comment, and return ' '. Return EOF if we reached the end of file before the end of the comment. If not the start of a comment, return '/'. */static intskip_comment (pfile, linep) cpp_reader *pfile; long *linep;{ int c; while (PEEKC() == '\\' && PEEKN(1) == '\n') { if (linep) (*linep)++; FORWARD(2); } if (PEEKC() == '*') { FORWARD(1); for (;;) { int prev_c = c; c = GETC (); if (c == EOF) return EOF; while (c == '\\' && PEEKC() == '\n') { if (linep) (*linep)++; FORWARD(1), c = GETC(); } if (prev_c == '*' && c == '/') return ' '; if (c == '\n' && linep) (*linep)++; } } else if (PEEKC() == '/' && CPP_OPTIONS (pfile)->cplusplus_comments) { FORWARD(1); for (;;) { c = GETC (); if (c == EOF) return ' '; /* Allow // to be terminated by EOF. */ while (c == '\\' && PEEKC() == '\n') { FORWARD(1); c = GETC(); if (linep) (*linep)++; } if (c == '\n') { /* Don't consider final '\n' to be part of comment. */ FORWARD(-1); return ' '; } } } else return '/';} /* Skip whitespace \-newline and comments. Does not macro-expand. */voidcpp_skip_hspace (pfile) cpp_reader *pfile;{ while (1) { int c = PEEKC(); if (c == EOF) return; /* FIXME */ if (is_hor_space[c]) { if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile)) cpp_pedwarn (pfile, "%s in preprocessing directive", c == '\f' ? "formfeed" : "vertical tab"); FORWARD(1); } else if (c == '/') { FORWARD (1); c = skip_comment (pfile, NULL); if (c == '/') FORWARD(-1); if (c == EOF || c == '/') return; } else if (c == '\\' && PEEKN(1) == '\n') { FORWARD(2); } else if (c == '@' && CPP_BUFFER (pfile)->has_escapes && is_hor_space[PEEKN(1)]) FORWARD(2); else return; }}/* Read the rest of the current line. The line is appended to PFILE's output buffer. */voidcopy_rest_of_line (pfile) cpp_reader *pfile;{ struct cpp_options *opts = CPP_OPTIONS (pfile); for (;;) { int c = GETC(); int nextc; switch (c) { case EOF: goto end_directive; case '\\': if (PEEKC() == '\n') { FORWARD (1); continue; } case '\'':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -