/* Copy the replacement text of MACRO to DEST, which must be of sufficient size. It is not NUL-terminated. The next character is returned. */ uchar * _cpp_copy_replacement_text (const cpp_macro *macro, uchar *dest) { if (macro->fun_like && (macro->paramc != 0)) { const uchar *exp; for (exp = macro->exp.text;;) { struct block *b = (struct block *) exp; cpp_hashnode *param; memcpy (dest, b->text, b->text_len); dest += b->text_len; if (b->arg_index == 0) break; param = macro->params[b->arg_index - 1]; memcpy (dest, NODE_NAME (param), NODE_LEN (param)); dest += NODE_LEN (param); exp += BLOCK_LEN (b->text_len); } } else { memcpy (dest, macro->exp.text, macro->count); dest += macro->count; } return dest; }
/* Return the length of the replacement text of a function-like or object-like non-builtin macro. */ size_t _cpp_replacement_text_len (const cpp_macro *macro) { size_t len; if (macro->fun_like && (macro->paramc != 0)) { const uchar *exp; len = 0; for (exp = macro->exp.text;;) { struct block *b = (struct block *) exp; len += b->text_len; if (b->arg_index == 0) break; len += NODE_LEN (macro->params[b->arg_index - 1]); exp += BLOCK_LEN (b->text_len); } } else len = macro->count; return len; }
/* Write the spelling of a token TOKEN to BUFFER. The buffer must already contain the enough space to hold the token's spelling. Returns a pointer to the character after the last character written. FIXME: Would be nice if we didn't need the PFILE argument. */ unsigned char * cpp_spell_token (cpp_reader *pfile, const cpp_token *token, unsigned char *buffer) { switch (TOKEN_SPELL (token)) { case SPELL_OPERATOR: { const unsigned char *spelling; unsigned char c; if (token->flags & DIGRAPH) spelling = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH]; else if (token->flags & NAMED_OP) goto spell_ident; else spelling = TOKEN_NAME (token); while ((c = *spelling++) != '\0') *buffer++ = c; } break; spell_ident: case SPELL_IDENT: memcpy (buffer, NODE_NAME (token->val.node), NODE_LEN (token->val.node)); buffer += NODE_LEN (token->val.node); break; case SPELL_LITERAL: memcpy (buffer, token->val.str.text, token->val.str.len); buffer += token->val.str.len; break; case SPELL_NONE: cpp_error (pfile, CPP_DL_ICE, "unspellable token %s", TOKEN_NAME (token)); break; } return buffer; }
void recognized_function (const cpp_token *fname, unsigned int line, int kind, int have_arg_list) { struct partial_proto *partial; int i; struct fn_decl *fn; fn = lookup_std_proto ((const char *) NODE_NAME (fname->val.node), NODE_LEN (fname->val.node)); /* Remove the function from the list of required function. */ if (fn) { if (REQUIRED (fn)) required_unseen_count--; SET_SEEN (fn); } /* If we have a full prototype, we're done. */ if (have_arg_list) return; if (kind == 'I') /* don't edit inline function */ return; /* If the partial prototype was included from some other file, we don't need to patch it up (in this run). */ i = strlen (cur_file); if (i < inc_filename_length || strcmp (inc_filename, cur_file + (i - inc_filename_length)) != 0) return; if (fn == NULL) return; if (fn->params[0] == '\0') return; /* We only have a partial function declaration, so remember that we have to add a complete prototype. */ partial_count++; partial = obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto)); partial->line_seen = line; partial->fn = fn; fn->partial = partial; partial->next = partial_proto_list; partial_proto_list = partial; if (verbose) { fprintf (stderr, "(%s: %s non-prototype function declaration.)\n", inc_filename, fn->fname); } }
static int write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p) { FILE *f = (FILE *) file_p; switch (hn->type) { case NT_VOID: if (! (hn->flags & NODE_POISONED)) return 1; case NT_MACRO: if ((hn->flags & NODE_BUILTIN) && (!pfile->cb.user_builtin_macro || !pfile->cb.user_builtin_macro (pfile, hn))) return 1; { struct macrodef_struct s; const unsigned char *defn; s.name_length = NODE_LEN (hn); s.flags = hn->flags & NODE_POISONED; if (hn->type == NT_MACRO) { defn = cpp_macro_definition (pfile, hn); s.definition_length = ustrlen (defn); } else { defn = NODE_NAME (hn); s.definition_length = s.name_length; } if (fwrite (&s, sizeof (s), 1, f) != 1 || fwrite (defn, 1, s.definition_length, f) != s.definition_length) { cpp_errno (pfile, CPP_DL_ERROR, "while writing precompiled header"); return 0; } } return 1; case NT_ASSERTION: /* Not currently implemented. */ return 1; default: abort (); } }
/* An upper bound on the number of bytes needed to spell TOKEN. Does not include preceding whitespace. */ unsigned int cpp_token_len (const cpp_token *token) { unsigned int len; switch (TOKEN_SPELL (token)) { default: len = 4; break; case SPELL_LITERAL: len = token->val.str.len; break; case SPELL_IDENT: len = NODE_LEN (token->val.node); break; } return len; }
/* Writes the spelling of token to FP, without any preceding space. Separated from cpp_spell_token for efficiency - to avoid stdio double-buffering. */ void cpp_output_token (const cpp_token *token, FILE *fp) { switch (TOKEN_SPELL (token)) { case SPELL_OPERATOR: { const unsigned char *spelling; int c; if (token->flags & DIGRAPH) spelling = digraph_spellings[(int) token->type - (int) CPP_FIRST_DIGRAPH]; else if (token->flags & NAMED_OP) goto spell_ident; else spelling = TOKEN_NAME (token); c = *spelling; do putc (c, fp); while ((c = *++spelling) != '\0'); } break; spell_ident: case SPELL_IDENT: fwrite (NODE_NAME (token->val.node), 1, NODE_LEN (token->val.node), fp); break; case SPELL_LITERAL: fwrite (token->val.str.text, 1, token->val.str.len, fp); break; case SPELL_NONE: /* An error, most probably. */ break; } }