aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNeil Booth <neilb@earthling.net>2000-12-04 22:05:19 +0000
committerNeil Booth <neil@gcc.gnu.org>2000-12-04 22:05:19 +0000
commit7682e7bc2eb0a7a2a839fabd7c9fa103c117b876 (patch)
treebc7b3cf21ebfc2cd79f75c6f070954666bce9eef /gcc
parent23a535c4fff08a3224a41a118f1114d53256431b (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/tradcif.y13
-rw-r--r--gcc/tradcpp.c49
-rw-r--r--gcc/tradcpp.h1
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[];