mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-07 07:06:50 +08:00
cpphash.h (_cpp_push_text_context): Update.
* cpphash.h (_cpp_push_text_context): Update. (_cpp_arguments_ok): New. * cppmacro.c (_cpp_arguments_ok): New, split out from... (collect_args): ...here. (_cpp_push_text_context): Change inputs. * cpptrad.c (struct fun_macro, maybe_start_funlike, save_argument, replace_args_and_push): New. (lex_identifier, _cpp_lex_identifier_trad, scan_parameters): Don't use IS macros directly. (scan_out_logical_line): Handle function-like macro argument collection. (push_replacement_text): Update. (replacement_length): Remove. (_cpp_create_trad_definition): Don't skip whitespace before checking for '('. From-SVN: r54412
This commit is contained in:
parent
25f2e17641
commit
1ce676a061
@ -1,3 +1,21 @@
|
||||
2002-06-09 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* cpphash.h (_cpp_push_text_context): Update.
|
||||
(_cpp_arguments_ok): New.
|
||||
* cppmacro.c (_cpp_arguments_ok): New, split out from...
|
||||
(collect_args): ...here.
|
||||
(_cpp_push_text_context): Change inputs.
|
||||
* cpptrad.c (struct fun_macro, maybe_start_funlike, save_argument,
|
||||
replace_args_and_push): New.
|
||||
(lex_identifier, _cpp_lex_identifier_trad, scan_parameters):
|
||||
Don't use IS macros directly.
|
||||
(scan_out_logical_line): Handle function-like macro argument
|
||||
collection.
|
||||
(push_replacement_text): Update.
|
||||
(replacement_length): Remove.
|
||||
(_cpp_create_trad_definition): Don't skip whitespace before
|
||||
checking for '('.
|
||||
|
||||
2002-06-09 Marek Michalkiewicz <marekm@amelek.gda.pl>
|
||||
|
||||
* config/avr/avr.c (avr_mcu_types): Update for new devices.
|
||||
|
@ -438,9 +438,12 @@ extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
|
||||
extern bool _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
extern void _cpp_pop_context PARAMS ((cpp_reader *));
|
||||
extern void _cpp_push_text_context PARAMS ((cpp_reader *, cpp_hashnode *,
|
||||
const uchar *, const uchar*));
|
||||
const uchar *, size_t));
|
||||
extern bool _cpp_save_parameter PARAMS ((cpp_reader *, cpp_macro *,
|
||||
cpp_hashnode *));
|
||||
extern bool _cpp_arguments_ok PARAMS ((cpp_reader *, cpp_macro *,
|
||||
const cpp_hashnode *,
|
||||
unsigned int));
|
||||
|
||||
/* In cpphash.c */
|
||||
extern void _cpp_init_hashtable PARAMS ((cpp_reader *, hash_table *));
|
||||
|
@ -451,6 +451,52 @@ paste_all_tokens (pfile, lhs)
|
||||
push_token_context (pfile, NULL, lhs, 1);
|
||||
}
|
||||
|
||||
/* Returns TRUE if the number of arguments ARGC supplied in an
|
||||
invocation of the MACRO referenced by NODE is valid. An empty
|
||||
invocation to a macro with no parameters should pass ARGC as zero.
|
||||
|
||||
Note that MACRO cannot necessarily be deduced from NODE, in case
|
||||
NODE was redefined whilst collecting arguments. */
|
||||
bool
|
||||
_cpp_arguments_ok (pfile, macro, node, argc)
|
||||
cpp_reader *pfile;
|
||||
cpp_macro *macro;
|
||||
const cpp_hashnode *node;
|
||||
unsigned int argc;
|
||||
{
|
||||
if (argc == macro->paramc)
|
||||
return true;
|
||||
|
||||
if (argc < macro->paramc)
|
||||
{
|
||||
/* As an extension, a rest argument is allowed to not appear in
|
||||
the invocation at all.
|
||||
e.g. #define debug(format, args...) something
|
||||
debug("string");
|
||||
|
||||
This is exactly the same as if there had been an empty rest
|
||||
argument - debug("string", ). */
|
||||
|
||||
if (argc + 1 == macro->paramc && macro->variadic)
|
||||
{
|
||||
if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
|
||||
cpp_error (pfile, DL_PEDWARN,
|
||||
"ISO C99 requires rest arguments to be used");
|
||||
return true;
|
||||
}
|
||||
|
||||
cpp_error (pfile, DL_ERROR,
|
||||
"macro \"%s\" requires %u arguments, but only %u given",
|
||||
NODE_NAME (node), macro->paramc, argc);
|
||||
}
|
||||
else
|
||||
cpp_error (pfile, DL_ERROR,
|
||||
"macro \"%s\" passed %u arguments, but takes just %u",
|
||||
NODE_NAME (node), argc, macro->paramc);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Reads and returns the arguments to a function-like macro
|
||||
invocation. Assumes the opening parenthesis has been processed.
|
||||
If there is an error, emits an appropriate diagnostic and returns
|
||||
@ -466,7 +512,6 @@ collect_args (pfile, node)
|
||||
macro_arg *args, *arg;
|
||||
const cpp_token *token;
|
||||
unsigned int argc;
|
||||
bool error = false;
|
||||
|
||||
macro = node->value.macro;
|
||||
if (macro->paramc)
|
||||
@ -561,47 +606,17 @@ collect_args (pfile, node)
|
||||
cpp_error (pfile, DL_ERROR,
|
||||
"unterminated argument list invoking macro \"%s\"",
|
||||
NODE_NAME (node));
|
||||
error = true;
|
||||
}
|
||||
else if (argc < macro->paramc)
|
||||
else
|
||||
{
|
||||
/* As an extension, a rest argument is allowed to not appear in
|
||||
the invocation at all.
|
||||
e.g. #define debug(format, args...) something
|
||||
debug("string");
|
||||
|
||||
This is exactly the same as if there had been an empty rest
|
||||
argument - debug("string", ). */
|
||||
|
||||
if (argc + 1 == macro->paramc && macro->variadic)
|
||||
{
|
||||
if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
|
||||
cpp_error (pfile, DL_PEDWARN,
|
||||
"ISO C99 requires rest arguments to be used");
|
||||
}
|
||||
else
|
||||
{
|
||||
cpp_error (pfile, DL_ERROR,
|
||||
"macro \"%s\" requires %u arguments, but only %u given",
|
||||
NODE_NAME (node), macro->paramc, argc);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
else if (argc > macro->paramc)
|
||||
{
|
||||
/* Empty argument to a macro taking no arguments is OK. */
|
||||
if (argc != 1 || arg->count)
|
||||
{
|
||||
cpp_error (pfile, DL_ERROR,
|
||||
"macro \"%s\" passed %u arguments, but takes just %u",
|
||||
NODE_NAME (node), argc, macro->paramc);
|
||||
error = true;
|
||||
}
|
||||
/* A single empty argument is counted as no argument. */
|
||||
if (argc == 1 && macro->paramc == 0 && args[0].count == 0)
|
||||
argc = 0;
|
||||
if (_cpp_arguments_ok (pfile, macro, node, argc))
|
||||
return base_buff;
|
||||
}
|
||||
|
||||
if (!error)
|
||||
return base_buff;
|
||||
|
||||
/* An error occurred. */
|
||||
_cpp_release_buff (pfile, base_buff);
|
||||
return NULL;
|
||||
}
|
||||
@ -919,10 +934,11 @@ push_token_context (pfile, macro, first, count)
|
||||
|
||||
/* Push a traditional macro's replacement text. */
|
||||
void
|
||||
_cpp_push_text_context (pfile, macro, start, end)
|
||||
_cpp_push_text_context (pfile, macro, start, len)
|
||||
cpp_reader *pfile;
|
||||
cpp_hashnode *macro;
|
||||
const uchar *start, *end;
|
||||
const uchar *start;
|
||||
size_t len;
|
||||
{
|
||||
cpp_context *context = next_context (pfile);
|
||||
|
||||
@ -930,7 +946,7 @@ _cpp_push_text_context (pfile, macro, start, end)
|
||||
context->macro = macro;
|
||||
context->buff = NULL;
|
||||
CUR (context) = start;
|
||||
RLIMIT (context) = end;
|
||||
RLIMIT (context) = start + len;
|
||||
}
|
||||
|
||||
/* Expand an argument ARG before replacing parameters in a
|
||||
|
296
gcc/cpptrad.c
296
gcc/cpptrad.c
@ -44,6 +44,29 @@ struct block
|
||||
#define BLOCK_HEADER_LEN offsetof (struct block, text)
|
||||
#define BLOCK_LEN(TEXT_LEN) CPP_ALIGN (BLOCK_HEADER_LEN + TEXT_LEN)
|
||||
|
||||
/* Structure holding information about a function-like macro
|
||||
invocation. */
|
||||
struct fun_macro
|
||||
{
|
||||
/* Memory buffer holding the trad_arg array. */
|
||||
_cpp_buff *buff;
|
||||
|
||||
/* An array of size the number of macro parameters + 1, containing
|
||||
the offsets of the start of each macro argument in the output
|
||||
buffer. The argument continues until the character before the
|
||||
start of the next one. */
|
||||
size_t *args;
|
||||
|
||||
/* The hashnode of the macro. */
|
||||
cpp_hashnode *node;
|
||||
|
||||
/* The offset of the macro name in the output buffer. */
|
||||
size_t offset;
|
||||
|
||||
/* Zero-based index of argument being currently lexed. */
|
||||
unsigned int argc;
|
||||
};
|
||||
|
||||
/* Lexing TODO: Handle -C, maybe -CC, and space in escaped newlines.
|
||||
Stop cpplex.c from recognizing comments and directives during its
|
||||
lexing pass. Get rid of line_base usage - seems pointless? Do we
|
||||
@ -62,7 +85,10 @@ static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
|
||||
static bool scan_parameters PARAMS ((cpp_reader *, cpp_macro *));
|
||||
static void save_replacement_text PARAMS ((cpp_reader *, cpp_macro *,
|
||||
unsigned int));
|
||||
static unsigned int replacement_length PARAMS ((cpp_macro *));
|
||||
static void maybe_start_funlike PARAMS ((cpp_reader *, cpp_hashnode *,
|
||||
const uchar *, struct fun_macro *));
|
||||
static void save_argument PARAMS ((struct fun_macro *, size_t));
|
||||
static void replace_args_and_push PARAMS ((cpp_reader *, struct fun_macro *));
|
||||
|
||||
/* Ensures we have N bytes' space in the output buffer, and
|
||||
reallocates it if not. */
|
||||
@ -205,10 +231,10 @@ lex_identifier (pfile, cur)
|
||||
{
|
||||
do
|
||||
*out++ = *cur++;
|
||||
while (ISIDNUM (*cur));
|
||||
while (is_numchar (*cur));
|
||||
cur = skip_escaped_newlines (pfile, cur);
|
||||
}
|
||||
while (ISIDNUM (*cur));
|
||||
while (is_numchar (*cur));
|
||||
|
||||
CUR (pfile->context) = cur;
|
||||
len = out - pfile->trad_out_cur;
|
||||
@ -226,7 +252,7 @@ _cpp_lex_identifier_trad (pfile)
|
||||
{
|
||||
const uchar *cur = skip_whitespace (pfile, CUR (pfile->context));
|
||||
|
||||
if (!ISIDST (*cur))
|
||||
if (!is_idstart (*cur))
|
||||
{
|
||||
CUR (pfile->context) = cur;
|
||||
return NULL;
|
||||
@ -309,12 +335,45 @@ _cpp_read_logical_line_trad (pfile)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Set up state for finding the opening '(' of a function-like
|
||||
macro. */
|
||||
static void
|
||||
maybe_start_funlike (pfile, node, start, macro)
|
||||
cpp_reader *pfile;
|
||||
cpp_hashnode *node;
|
||||
const uchar *start;
|
||||
struct fun_macro *macro;
|
||||
{
|
||||
unsigned int n = node->value.macro->paramc + 1;
|
||||
|
||||
if (macro->buff)
|
||||
_cpp_release_buff (pfile, macro->buff);
|
||||
macro->buff = _cpp_get_buff (pfile, n * sizeof (size_t));
|
||||
macro->args = (size_t *) BUFF_FRONT (macro->buff);
|
||||
macro->node = node;
|
||||
macro->offset = start - pfile->trad_out_base;
|
||||
macro->argc = 0;
|
||||
|
||||
pfile->state.parsing_args = 1;
|
||||
}
|
||||
|
||||
/* Save the OFFSET of the start of the next argument to MACRO. */
|
||||
static void
|
||||
save_argument (macro, offset)
|
||||
struct fun_macro *macro;
|
||||
size_t offset;
|
||||
{
|
||||
macro->argc++;
|
||||
if (macro->argc <= macro->node->value.macro->paramc)
|
||||
macro->args[macro->argc] = offset;
|
||||
}
|
||||
|
||||
/* Copies the next logical line in the current buffer to the output
|
||||
buffer. The output is guaranteed to terminate with a NUL
|
||||
character.
|
||||
|
||||
If MACRO is non-NULL, then we are scanning the replacement list of
|
||||
MACRO, and we call save_replacement_text every time we meet an
|
||||
MACRO, and we call save_replacement_text() every time we meet an
|
||||
argument. */
|
||||
static void
|
||||
scan_out_logical_line (pfile, macro)
|
||||
@ -323,9 +382,11 @@ scan_out_logical_line (pfile, macro)
|
||||
{
|
||||
cpp_context *context;
|
||||
const uchar *cur;
|
||||
unsigned int c, quote = 0;
|
||||
unsigned int c, paren_depth, quote = 0;
|
||||
uchar *out;
|
||||
struct fun_macro fmacro;
|
||||
|
||||
fmacro.buff = NULL;
|
||||
new_context:
|
||||
context = pfile->context;
|
||||
cur = CUR (context);
|
||||
@ -357,16 +418,22 @@ scan_out_logical_line (pfile, macro)
|
||||
cur--;
|
||||
if (!pfile->buffer->from_stage3)
|
||||
cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
|
||||
if (pfile->state.parsing_args == 2)
|
||||
cpp_error (pfile, DL_ERROR,
|
||||
"unterminated argument list invoking macro \"%s\"",
|
||||
NODE_NAME (fmacro.node));
|
||||
pfile->line++;
|
||||
goto finish_output;
|
||||
goto done;
|
||||
|
||||
case '\r': case '\n':
|
||||
cur = handle_newline (pfile, cur - 1);
|
||||
out[-1] = '\0';
|
||||
finish_output:
|
||||
CUR (context) = cur;
|
||||
pfile->trad_out_cur = out - 1;
|
||||
return;
|
||||
if (pfile->state.parsing_args == 2)
|
||||
{
|
||||
/* Newlines in arguments become a space. */
|
||||
out[-1] = ' ';
|
||||
continue;
|
||||
}
|
||||
goto done;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
@ -418,16 +485,25 @@ scan_out_logical_line (pfile, macro)
|
||||
pfile->trad_out_cur = --out;
|
||||
node = lex_identifier (pfile, cur - 1);
|
||||
|
||||
if (node->type == NT_MACRO && !pfile->state.prevent_expansion)
|
||||
if (node->type == NT_MACRO
|
||||
&& pfile->state.parsing_args != 2
|
||||
&& !pfile->state.prevent_expansion)
|
||||
{
|
||||
/* Remove the macro name from the output. */
|
||||
pfile->trad_out_cur = out;
|
||||
push_replacement_text (pfile, node);
|
||||
goto new_context;
|
||||
if (node->value.macro->fun_like)
|
||||
maybe_start_funlike (pfile, node, out, &fmacro);
|
||||
else
|
||||
{
|
||||
/* Remove the object-like macro's name from the
|
||||
output, and push its replacement text. */
|
||||
pfile->trad_out_cur = out;
|
||||
push_replacement_text (pfile, node);
|
||||
goto new_context;
|
||||
}
|
||||
}
|
||||
else if (macro && node->arg_index)
|
||||
{
|
||||
/* Remove the macro name from the output. */
|
||||
/* Found a parameter in the replacement text of a
|
||||
#define. Remove its name from the output. */
|
||||
pfile->trad_out_cur = out;
|
||||
save_replacement_text (pfile, macro, node->arg_index);
|
||||
}
|
||||
@ -437,15 +513,91 @@ scan_out_logical_line (pfile, macro)
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
if (quote == 0)
|
||||
{
|
||||
paren_depth++;
|
||||
if (pfile->state.parsing_args == 1)
|
||||
{
|
||||
const uchar *p = pfile->trad_out_base + fmacro.offset;
|
||||
|
||||
/* Invoke a prior function-like macro if there is only
|
||||
white space in-between. */
|
||||
while (is_numchar (*p))
|
||||
p++;
|
||||
while (is_space (*p))
|
||||
p++;
|
||||
|
||||
if (p == out - 1)
|
||||
{
|
||||
pfile->state.parsing_args = 2;
|
||||
paren_depth = 1;
|
||||
out = pfile->trad_out_base + fmacro.offset;
|
||||
fmacro.args[0] = fmacro.offset;
|
||||
}
|
||||
else
|
||||
pfile->state.parsing_args = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
if (quote == 0 && pfile->state.parsing_args == 2 && paren_depth == 1)
|
||||
save_argument (&fmacro, out - pfile->trad_out_base);
|
||||
break;
|
||||
|
||||
case ')':
|
||||
if (quote == 0)
|
||||
{
|
||||
paren_depth--;
|
||||
if (pfile->state.parsing_args == 2 && paren_depth == 0)
|
||||
{
|
||||
cpp_macro *m = fmacro.node->value.macro;
|
||||
|
||||
pfile->state.parsing_args = 0;
|
||||
save_argument (&fmacro, out - pfile->trad_out_base);
|
||||
|
||||
/* A single whitespace argument is no argument. */
|
||||
if (fmacro.argc == 1 && m->paramc == 0)
|
||||
{
|
||||
const uchar *p = pfile->trad_out_base;
|
||||
p += fmacro.args[0];
|
||||
while (is_space (*p))
|
||||
p++;
|
||||
if (p == pfile->trad_out_base + fmacro.args[1])
|
||||
fmacro.argc = 0;
|
||||
}
|
||||
|
||||
if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
|
||||
{
|
||||
/* Remove the macro's invocation from the
|
||||
output, and push its replacement text. */
|
||||
pfile->trad_out_cur = (pfile->trad_out_base
|
||||
+ fmacro.offset);
|
||||
CUR (context) = cur;
|
||||
replace_args_and_push (pfile, &fmacro);
|
||||
goto new_context;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
out[-1] = '\0';
|
||||
CUR (context) = cur;
|
||||
pfile->trad_out_cur = out - 1;
|
||||
if (fmacro.buff)
|
||||
_cpp_release_buff (pfile, fmacro.buff);
|
||||
}
|
||||
|
||||
/* Push a context holding the replacement text of the macro NODE on
|
||||
the context stack. Doesn't yet handle special built-ins or
|
||||
function-like macros. */
|
||||
the context stack. NODE is either object-like, or a function-like
|
||||
macro with no arguments. */
|
||||
static void
|
||||
push_replacement_text (pfile, node)
|
||||
cpp_reader *pfile;
|
||||
@ -453,9 +605,70 @@ push_replacement_text (pfile, node)
|
||||
{
|
||||
cpp_macro *macro = node->value.macro;
|
||||
|
||||
_cpp_push_text_context (pfile, node,
|
||||
macro->exp.text,
|
||||
macro->exp.text + macro->count);
|
||||
_cpp_push_text_context (pfile, node, macro->exp.text, macro->count);
|
||||
}
|
||||
|
||||
/* Push a context holding the replacement text of the macro NODE on
|
||||
the context stack. NODE is either object-like, or a function-like
|
||||
macro with no arguments. */
|
||||
static void
|
||||
replace_args_and_push (pfile, fmacro)
|
||||
cpp_reader *pfile;
|
||||
struct fun_macro *fmacro;
|
||||
{
|
||||
cpp_macro *macro = fmacro->node->value.macro;
|
||||
|
||||
if (macro->paramc == 0)
|
||||
push_replacement_text (pfile, fmacro->node);
|
||||
else
|
||||
{
|
||||
const uchar *exp;
|
||||
uchar *p;
|
||||
_cpp_buff *buff;
|
||||
size_t len = 0;
|
||||
|
||||
/* Calculate the length of the argument-replaced text. */
|
||||
for (exp = macro->exp.text;;)
|
||||
{
|
||||
struct block *b = (struct block *) exp;
|
||||
|
||||
len += b->text_len;
|
||||
if (b->arg_index == 0)
|
||||
break;
|
||||
len += (fmacro->args[b->arg_index]
|
||||
- fmacro->args[b->arg_index - 1] - 1);
|
||||
exp += BLOCK_LEN (b->text_len);
|
||||
}
|
||||
|
||||
/* Allocate room for the expansion plus NUL. */
|
||||
buff = _cpp_get_buff (pfile, len + 1);
|
||||
|
||||
/* Copy the expansion and replace arguments. */
|
||||
p = BUFF_FRONT (buff);
|
||||
for (exp = macro->exp.text;;)
|
||||
{
|
||||
struct block *b = (struct block *) exp;
|
||||
size_t arglen;
|
||||
|
||||
memcpy (p, b->text, b->text_len);
|
||||
p += b->text_len;
|
||||
if (b->arg_index == 0)
|
||||
break;
|
||||
arglen = (fmacro->args[b->arg_index]
|
||||
- fmacro->args[b->arg_index - 1] - 1);
|
||||
memcpy (p, pfile->trad_out_base + fmacro->args[b->arg_index - 1],
|
||||
arglen);
|
||||
p += arglen;
|
||||
exp += BLOCK_LEN (b->text_len);
|
||||
}
|
||||
|
||||
/* NUL-terminate. */
|
||||
*p = '\0';
|
||||
_cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);
|
||||
|
||||
/* So we free buffer allocation when macro is left. */
|
||||
pfile->context->buff = buff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read and record the parameters, if any, of a function-like macro
|
||||
@ -476,7 +689,7 @@ scan_parameters (pfile, macro)
|
||||
{
|
||||
cur = skip_whitespace (pfile, cur);
|
||||
|
||||
if (ISIDST (*cur))
|
||||
if (is_idstart (*cur))
|
||||
{
|
||||
ok = false;
|
||||
if (_cpp_save_parameter (pfile, macro, lex_identifier (pfile, cur)))
|
||||
@ -500,25 +713,6 @@ scan_parameters (pfile, macro)
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Calculate the length of the replacement text of MACRO. */
|
||||
static unsigned int
|
||||
replacement_length (macro)
|
||||
cpp_macro *macro;
|
||||
{
|
||||
unsigned int result = 0;
|
||||
const uchar *exp = macro->exp.text;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
struct block *block = (struct block *) exp;
|
||||
|
||||
result += block->text_len;
|
||||
if (block->arg_index == 0)
|
||||
return result;
|
||||
exp += BLOCK_LEN (block->text_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the text from pfile->trad_out_base to pfile->trad_out_cur as
|
||||
the replacement text for the current macro, followed by argument
|
||||
ARG_INDEX, with zero indicating the end of the replacement
|
||||
@ -568,10 +762,7 @@ save_replacement_text (pfile, macro, arg_index)
|
||||
in the replacement list, excluding the parameter names, and
|
||||
save this in macro->count, else store the total bytes in the
|
||||
replacement text so far (including block headers). */
|
||||
if (arg_index == 0)
|
||||
macro->count = replacement_length (macro);
|
||||
else
|
||||
macro->count += blen;
|
||||
macro->count += blen;
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,13 +776,11 @@ _cpp_create_trad_definition (pfile, macro)
|
||||
const uchar *cur;
|
||||
uchar *limit;
|
||||
|
||||
/* Skip leading whitespace now. */
|
||||
CUR (pfile->context) = skip_whitespace (pfile, CUR (pfile->context));
|
||||
|
||||
/* Is this a function-like macro? */
|
||||
if (* CUR (pfile->context) == '(')
|
||||
{
|
||||
/* Setting macro to NULL indicates an error occurred. */
|
||||
/* Setting macro to NULL indicates an error occurred, and
|
||||
prevents unnecessary work in scan_out_logical_line. */
|
||||
if (!scan_parameters (pfile, macro))
|
||||
macro = NULL;
|
||||
else
|
||||
@ -601,10 +790,11 @@ _cpp_create_trad_definition (pfile, macro)
|
||||
BUFF_FRONT (pfile->a_buff) = (uchar *) ¯o->params[macro->paramc];
|
||||
macro->fun_like = 1;
|
||||
}
|
||||
|
||||
CUR (pfile->context) = skip_whitespace (pfile, CUR (pfile->context));
|
||||
}
|
||||
|
||||
/* Skip leading whitespace in the replacement text. */
|
||||
CUR (pfile->context) = skip_whitespace (pfile, CUR (pfile->context));
|
||||
|
||||
pfile->trad_out_cur = pfile->trad_out_base;
|
||||
pfile->state.prevent_expansion++;
|
||||
scan_out_logical_line (pfile, macro);
|
||||
|
Loading…
Reference in New Issue
Block a user