cpphash.h (struct cpp_macro): Put comments on their own lines.
* cpphash.h (struct cpp_macro): Put comments on their own lines. (_cpp_expansions_different_trad): New. * cppmacro.c (warn_of_redefinition): Fix for traditional case. * cpptrad.c (canonicalize_text): New. (scan_out_logical_line): Handle no arguments correctly. (save_replacement_text): Commit memory when finished. (_cpp_expansions_different_trad): New. From-SVN: r54432
This commit is contained in:
parent
36d010cabf
commit
6618c5d49d
4 changed files with 145 additions and 30 deletions
|
@ -1,3 +1,13 @@
|
|||
2002-06-10 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* cpphash.h (struct cpp_macro): Put comments on their own lines.
|
||||
(_cpp_expansions_different_trad): New.
|
||||
* cppmacro.c (warn_of_redefinition): Fix for traditional case.
|
||||
* cpptrad.c (canonicalize_text): New.
|
||||
(scan_out_logical_line): Handle no arguments correctly.
|
||||
(save_replacement_text): Commit memory when finished.
|
||||
(_cpp_expansions_different_trad): New.
|
||||
|
||||
2002-06-10 Tim Josling <tej@melbpc.org.au>
|
||||
|
||||
* gengtype.c (unnamed enum containing BASE_FILE_*): Add languages
|
||||
|
|
|
@ -69,18 +69,35 @@ struct dummy
|
|||
Variadic macros cannot occur with traditional cpp. */
|
||||
struct cpp_macro
|
||||
{
|
||||
cpp_hashnode **params; /* Parameters, if any. */
|
||||
/* Parameters, if any. */
|
||||
cpp_hashnode **params;
|
||||
|
||||
/* Replacement tokens (ISO) or replacement text (traditional). See
|
||||
comment at top of cpptrad.c for how traditional function-like
|
||||
macros are encoded. */
|
||||
union
|
||||
{
|
||||
cpp_token *tokens; /* Tokens of replacement list (ISO). */
|
||||
const uchar *text; /* Expansion text (traditional). */
|
||||
cpp_token *tokens;
|
||||
const uchar *text;
|
||||
} exp;
|
||||
unsigned int line; /* Starting line number. */
|
||||
unsigned int count; /* Number of tokens / bytes in expansion. */
|
||||
unsigned short paramc; /* Number of parameters. */
|
||||
unsigned int fun_like : 1; /* If a function-like macro. */
|
||||
unsigned int variadic : 1; /* If a variadic macro. */
|
||||
unsigned int syshdr : 1; /* If macro defined in system header. */
|
||||
|
||||
/* Definition line number. */
|
||||
unsigned int line;
|
||||
|
||||
/* Number of tokens in expansion, or bytes for traditional macros. */
|
||||
unsigned int count;
|
||||
|
||||
/* Number of parameters. */
|
||||
unsigned short paramc;
|
||||
|
||||
/* If a function-like macro. */
|
||||
unsigned int fun_like : 1;
|
||||
|
||||
/* If a variadic macro. */
|
||||
unsigned int variadic : 1;
|
||||
|
||||
/* If macro defined in system header. */
|
||||
unsigned int syshdr : 1;
|
||||
};
|
||||
|
||||
/* A generic memory buffer, and operations on it. */
|
||||
|
@ -499,6 +516,7 @@ extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
|
|||
extern cpp_hashnode *_cpp_lex_identifier_trad PARAMS ((cpp_reader *));
|
||||
extern void _cpp_set_trad_context PARAMS ((cpp_reader *));
|
||||
extern bool _cpp_create_trad_definition PARAMS ((cpp_reader *, cpp_macro *));
|
||||
extern bool _cpp_expansions_different_trad PARAMS ((cpp_macro *, cpp_macro *));
|
||||
|
||||
/* Utility routines and macros. */
|
||||
#define DSC(str) (const uchar *)str, sizeof str - 1
|
||||
|
|
|
@ -1176,9 +1176,9 @@ warn_of_redefinition (pfile, node, macro2)
|
|||
definitions are the same. (6.10.3 paragraph 2). */
|
||||
macro1 = node->value.macro;
|
||||
|
||||
/* The quick failures. */
|
||||
if (macro1->count != macro2->count
|
||||
|| macro1->paramc != macro2->paramc
|
||||
/* Don't check count here as it can be different in valid
|
||||
traditional redefinitions with just whitespace differences. */
|
||||
if (macro1->paramc != macro2->paramc
|
||||
|| macro1->fun_like != macro2->fun_like
|
||||
|| macro1->variadic != macro2->variadic)
|
||||
return true;
|
||||
|
@ -1190,11 +1190,12 @@ warn_of_redefinition (pfile, node, macro2)
|
|||
|
||||
/* Check the replacement text or tokens. */
|
||||
if (CPP_OPTION (pfile, traditional))
|
||||
return memcmp (macro1->exp.text, macro2->exp.text, macro1->count);
|
||||
return _cpp_expansions_different_trad (macro1, macro2);
|
||||
|
||||
for (i = 0; i < macro1->count; i++)
|
||||
if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i]))
|
||||
return true;
|
||||
if (macro1->count == macro2->count)
|
||||
for (i = 0; i < macro1->count; i++)
|
||||
if (!_cpp_equiv_tokens (¯o1->exp.tokens[i], ¯o2->exp.tokens[i]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
114
gcc/cpptrad.c
114
gcc/cpptrad.c
|
@ -89,6 +89,8 @@ 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 *));
|
||||
static size_t canonicalize_text PARAMS ((uchar *, const uchar *, size_t,
|
||||
uchar *));
|
||||
|
||||
/* Ensures we have N bytes' space in the output buffer, and
|
||||
reallocates it if not. */
|
||||
|
@ -557,16 +559,11 @@ scan_out_logical_line (pfile, 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;
|
||||
}
|
||||
/* A single zero-length argument is no argument. */
|
||||
if (fmacro.argc == 1
|
||||
&& m->paramc == 0
|
||||
&& out == pfile->trad_out_base + 1)
|
||||
fmacro.argc = 0;
|
||||
|
||||
if (_cpp_arguments_ok (pfile, m, fmacro.node, fmacro.argc))
|
||||
{
|
||||
|
@ -758,11 +755,11 @@ save_replacement_text (pfile, macro, arg_index)
|
|||
/* Lex the rest into the start of the output buffer. */
|
||||
pfile->trad_out_cur = pfile->trad_out_base;
|
||||
|
||||
/* If this is the end of the macro, count up the bytes of text
|
||||
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). */
|
||||
macro->count += blen;
|
||||
|
||||
/* If we've finished, commit the memory. */
|
||||
if (arg_index == 0)
|
||||
BUFF_FRONT (pfile->a_buff) += macro->count;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,6 +811,95 @@ _cpp_create_trad_definition (pfile, macro)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Copy SRC of length LEN to DEST, but convert all contiguous
|
||||
whitespace to a single space, provided it is not in quotes. The
|
||||
quote currently in effect is pointed to by PQUOTE, and is updated
|
||||
by the function. Returns the number of bytes copied. */
|
||||
static size_t
|
||||
canonicalize_text (dest, src, len, pquote)
|
||||
uchar *dest;
|
||||
const uchar *src;
|
||||
size_t len;
|
||||
uchar *pquote;
|
||||
{
|
||||
uchar *orig_dest = dest;
|
||||
uchar quote = *pquote;
|
||||
|
||||
while (len)
|
||||
{
|
||||
if (is_space (*src) && !quote)
|
||||
{
|
||||
do
|
||||
src++, len--;
|
||||
while (len && is_space (*src));
|
||||
*dest++ = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*src == '\'' || *src == '"')
|
||||
{
|
||||
if (!quote)
|
||||
quote = *src;
|
||||
else if (quote == *src)
|
||||
quote = 0;
|
||||
}
|
||||
*dest++ = *src++, len--;
|
||||
}
|
||||
}
|
||||
|
||||
*pquote = quote;
|
||||
return dest - orig_dest;
|
||||
}
|
||||
|
||||
/* Returns true if MACRO1 and MACRO2 have expansions different other
|
||||
than in the form of their whitespace. */
|
||||
bool
|
||||
_cpp_expansions_different_trad (macro1, macro2)
|
||||
cpp_macro *macro1, *macro2;
|
||||
{
|
||||
uchar *p1 = xmalloc (macro1->count + macro2->count);
|
||||
uchar *p2 = p1 + macro1->count;
|
||||
uchar quote1 = 0, quote2;
|
||||
bool mismatch;
|
||||
size_t len1, len2;
|
||||
|
||||
if (macro1->paramc > 0)
|
||||
{
|
||||
const uchar *exp1 = macro1->exp.text, *exp2 = macro2->exp.text;
|
||||
|
||||
mismatch = true;
|
||||
for (;;)
|
||||
{
|
||||
struct block *b1 = (struct block *) exp1;
|
||||
struct block *b2 = (struct block *) exp2;
|
||||
|
||||
if (b1->arg_index != b2->arg_index)
|
||||
break;
|
||||
|
||||
len1 = canonicalize_text (p1, b1->text, b1->text_len, "e1);
|
||||
len2 = canonicalize_text (p2, b2->text, b2->text_len, "e2);
|
||||
if (len1 != len2 || memcmp (p1, p2, len1))
|
||||
break;
|
||||
if (b1->arg_index == 0)
|
||||
{
|
||||
mismatch = false;
|
||||
break;
|
||||
}
|
||||
exp1 += BLOCK_LEN (b1->text_len);
|
||||
exp2 += BLOCK_LEN (b2->text_len);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
len1 = canonicalize_text (p1, macro1->exp.text, macro1->count, "e1);
|
||||
len2 = canonicalize_text (p2, macro2->exp.text, macro2->count, "e2);
|
||||
mismatch = (len1 != len2 || memcmp (p1, p2, len1));
|
||||
}
|
||||
|
||||
free (p1);
|
||||
return mismatch;
|
||||
}
|
||||
|
||||
/* Prepare to be able to scan the current buffer. */
|
||||
void
|
||||
_cpp_set_trad_context (pfile)
|
||||
|
|
Loading…
Add table
Reference in a new issue