tradcif.y: Move lexptr to top of file.

* tradcif.y: Move lexptr to top of file.  Add rule to handle
        assertions in conditional expressions.
        * tradcpp.c (parse_answer): Assertions do not need to go to
        end of line in conditional directives.
        (parse_assertion): Get first character of identifiers correct.
        (test_assertion): New function.
        * tradcpp.h (test_assertion): New prototype.

From-SVN: r38011
This commit is contained in:
Neil Booth 2000-12-04 22:05:19 +00:00 committed by Neil Booth
parent 23a535c4ff
commit 7682e7bc2e
4 changed files with 65 additions and 8 deletions

View File

@ -1,3 +1,13 @@
2000-12-04 Neil Booth <neilb@earthling.net>
* tradcif.y: Move lexptr to top of file. Add rule to handle
assertions in conditional expressions.
* tradcpp.c (parse_answer): Assertions do not need to go to
end of line in conditional directives.
(parse_assertion): Get first character of identifiers correct.
(test_assertion): New function.
* tradcpp.h (test_assertion): New prototype.
2000-12-01 Rodney Brown <RodneyBrown@mynd.com>
* config.gcc: Fix typo for UnixWare 7.

View File

@ -36,6 +36,11 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static int expression_value;
static jmp_buf parse_return_error;
/* During parsing of a C expression, the pointer to the next
character is in this variable. */
static const char *lexptr;
%}
%union {
@ -199,14 +204,11 @@ exp : exp '*' exp
| NAME
{ $$.value = 0;
$$.unsignedp = 0; }
| '#' { $$.value =
test_assertion ((unsigned char **) &lexptr); }
;
%%
/* During parsing of a C expression, the pointer to the next character
is in this variable. */
static const char *lexptr;
/* Take care of parsing a number (anything that starts with a digit).
Set yylval and return the token type; update lexptr.
LEN is the number of characters in it. */
@ -389,6 +391,7 @@ yylex ()
case '{':
case '}':
case ',':
case '#':
lexptr++;
return c;

View File

@ -3057,11 +3057,14 @@ parse_answer (buf, limit, answerp, type)
buf++;
/* Parentheses are optional here. */
if (buf == limit && (type == T_IF || type == T_UNASSERT))
if (buf == limit && type == T_UNASSERT)
return 0;
if (buf == limit || *buf++ != '(')
{
if (type == T_IF)
return 0;
error ("missing '(' after predicate");
return 1;
}
@ -3118,8 +3121,12 @@ parse_assertion (buf, limit, answerp, type)
unsigned int len;
bp = symname;
while (bp < climit && is_idchar[*bp])
bp++;
if (bp < climit && is_idstart[*bp])
{
do
bp++;
while (bp < climit && is_idchar[*bp]);
}
len = bp - symname;
*answerp = 0;
@ -3130,6 +3137,8 @@ parse_assertion (buf, limit, answerp, type)
else
error ("predicate must be an identifier");
}
/* Unfortunately, because of the way we handle #if, we don't avoid
macro expansion in answers. This is not easy to fix. */
else if (parse_answer (bp, climit, answerp, type) == 0)
{
unsigned char *sym = alloca (len + 1);
@ -3148,6 +3157,40 @@ parse_assertion (buf, limit, answerp, type)
return result;
}
/* Test an assertion within a preprocessor conditional. Returns zero
on error or failure, one on success. */
int
test_assertion (pbuf)
unsigned char **pbuf; /* NUL-terminated. */
{
unsigned char *buf = *pbuf;
unsigned char *limit = buf + strlen ((char *) buf);
struct answer *answer;
HASHNODE *node;
int result = 0;
node = parse_assertion (buf, limit, &answer, T_IF);
if (node)
{
result = (node->type == T_ASSERT &&
(answer == 0 || *find_answer (node, answer) != 0));
/* Yuk. We update pbuf to point after the assertion test.
First, move past the identifier. */
if (is_space[*buf])
buf++;
while (is_idchar[*buf])
buf++;
/* If we have an answer, we need to move past the parentheses. */
if (answer)
while (*buf++ != ')')
;
*pbuf = buf;
}
return result;
}
/* Handle a #assert directive. */
static void
do_assert (buf, limit, op)

View File

@ -34,6 +34,7 @@ extern void fancy_abort PARAMS ((int, const char *)) ATTRIBUTE_NORETURN;
extern struct hashnode *lookup PARAMS ((const unsigned char *, int, int));
extern int parse_c_expression PARAMS ((const char *)); /* in tradcif.y */
extern int test_assertion PARAMS ((unsigned char **));
/* some external tables of character types */
extern unsigned char is_idstart[], is_idchar[];