Subject: RE: make: cond.c improvement?
To: Simon Gerraty <sjg@juniper.net>
From: jmc <jmc@ksu.edu>
List: tech-toolchain
Date: 01/05/2004 18:19:39
>===== Original Message From Simon Gerraty <sjg@juniper.net> =====
>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


Looks good to me. I'm also looking at redoing the way .for loops work so the 
loop iterator variable can be used in conditionals as well. (today you have to 
assign it to a var via := during each iteration due to the way it's 
implemented)

James

>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');
> 			}
> 		    }