diff options
author | Neil Booth <neilb@earthling.net> | 2000-12-04 22:05:19 +0000 |
---|---|---|
committer | Neil Booth <neil@gcc.gnu.org> | 2000-12-04 22:05:19 +0000 |
commit | 7682e7bc2eb0a7a2a839fabd7c9fa103c117b876 (patch) | |
tree | bc7b3cf21ebfc2cd79f75c6f070954666bce9eef | |
parent | 23a535c4fff08a3224a41a118f1114d53256431b (diff) | |
download | gcc-7682e7bc2eb0a7a2a839fabd7c9fa103c117b876.zip gcc-7682e7bc2eb0a7a2a839fabd7c9fa103c117b876.tar.gz gcc-7682e7bc2eb0a7a2a839fabd7c9fa103c117b876.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/tradcif.y | 13 | ||||
-rw-r--r-- | gcc/tradcpp.c | 49 | ||||
-rw-r--r-- | gcc/tradcpp.h | 1 |
4 files changed, 65 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 522d51d..1941372 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/tradcif.y b/gcc/tradcif.y index db95563..19e8b51 100644 --- a/gcc/tradcif.y +++ b/gcc/tradcif.y @@ -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; diff --git a/gcc/tradcpp.c b/gcc/tradcpp.c index 51c8aff..5db2a84 100644 --- a/gcc/tradcpp.c +++ b/gcc/tradcpp.c @@ -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) diff --git a/gcc/tradcpp.h b/gcc/tradcpp.h index 023e642..b646939 100644 --- a/gcc/tradcpp.h +++ b/gcc/tradcpp.h @@ -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[]; |