Subject: make: cond.c improvement?
To: None <tech-toolchain@netbsd.org>
From: Simon Gerraty <sjg@juniper.net>
List: tech-toolchain
Date: 01/05/2004 16:14:48
I was trying to use bmake to see why a freebsd ports build was
failing, but bmake vomits on an expression like:
.if exists(/usr/bin/perl5) && ${OSVERSION} >= 300000 && ${OSVERSION} < 500036
Adding () doesn't help either.
The patch below allows the following test case to perform as expected
for various values of A.
A?=42
all:
.if $A == 42
@echo "life; don't talk to me about life!"
.elif $A >= 0 && $A < 4
@echo sane
.else
@echo reality is over rated
.endif
FreeBSD's CondCvtArg also returns a char *, but they then have to test
for it being empty. Returning NULL for that case seems simpler.
--sjg
--- cond.c~ Mon Jan 5 15:15:49 2004
+++ cond.c Mon Jan 5 16:12:20 2004
@@ -145,7 +145,7 @@
static Boolean CondDoExists(int, char *);
static Boolean CondDoTarget(int, char *);
static Boolean CondDoCommands(int, char *);
-static Boolean CondCvtArg(char *, double *);
+static char * CondCvtArg(char *, double *);
static Token CondToken(Boolean);
static Token CondT(Boolean);
static Token CondF(Boolean);
@@ -491,7 +491,8 @@
*
* Results:
* Sets 'value' to double value of string.
- * Returns true if the string was a valid number, false o.w.
+ * Returns NULL if string was fully consumed,
+ * else returns remaining input.
*
* Side Effects:
* Can change 'value' even if string is not a valid number.
@@ -499,7 +500,7 @@
*
*-----------------------------------------------------------------------
*/
-static Boolean
+static char *
CondCvtArg(char *str, double *value)
{
if ((*str == '0') && (str[1] == 'x')) {
@@ -512,16 +513,15 @@
else if (isxdigit((unsigned char) *str))
x = 10 + *str - isupper((unsigned char) *str) ? 'A' : 'a';
else
- return FALSE;
+ break;
i = (i << 4) + x;
}
*value = (double) i;
- return TRUE;
- }
- else {
+ return *str ? str : NULL;
+ } else {
char *eptr;
*value = strtod(str, &eptr);
- return *eptr == '\0';
+ return *eptr ? eptr : NULL;
}
}
@@ -747,7 +747,7 @@
double left, right;
char *string;
- if (!CondCvtArg(lhs, &left))
+ if (CondCvtArg(lhs, &left))
goto do_string_compare;
if (*rhs == '$') {
int len;
@@ -757,7 +757,7 @@
if (string == var_Error) {
right = 0.0;
} else {
- if (!CondCvtArg(string, &right)) {
+ if (CondCvtArg(string, &right)) {
if (freeIt)
free(string);
goto do_string_compare;
@@ -768,16 +768,19 @@
condExpr += len;
}
} else {
- if (!CondCvtArg(rhs, &right))
+ char *cp;
+
+ if ((cp = CondCvtArg(rhs, &right)) &&
+ cp == rhs)
goto do_string_compare;
if (rhs == condExpr) {
/*
* Skip over the right-hand side
*/
- while(!isspace((unsigned char) *condExpr) &&
- (*condExpr != '\0')) {
- condExpr++;
- }
+ if (cp)
+ condExpr = cp;
+ else
+ condExpr = strchr(rhs, '\0');
}
}