Subject: Re: make(1) question; purpose of ${ :? : }
To: Luke Mewburn <lukem@NetBSD.org>
From: Simon Gerraty <sjg@juniper.net>
List: tech-toolchain
Date: 01/09/2004 15:46:14
Not sure this is a good idea... CondToken is in need of
restructuring I suspect...
Anyway, the patch below allows you to do expressions like
string == string
N > M
etc, which are not currently supported unless the lhs is a variable
expression.
Ie. with this you can actually do
x:
@echo "The answer for '$A' is ${$A :? yes : no}"
$ make -f /homes/sjg/make-tests/ternary A='1 > 2'
The answer for '1 > 2' is no
$ make -f /homes/sjg/make-tests/ternary A='3 > 2'
The answer for '3 > 2' is yes
$ make -f /homes/sjg/make-tests/ternary A='defined(USER) && ${USER} == "sjg"'
The answer for 'defined(USER) && sjg == sjg' is yes
$ make -f /homes/sjg/make-tests/ternary A='defined(USER) && ${USER} == "root"'
The answer for 'defined(USER) && sjg == root' is no
$
--sjg
--- cond.c~ Mon Jan 5 17:18:52 2004
+++ cond.c Fri Jan 9 15:24:10 2004
@@ -542,6 +542,13 @@
CondToken(Boolean doEval)
{
Token t;
+ Boolean doFree;
+ Boolean rawSymbol;
+ char *lhs;
+ char *rhs;
+ char *op;
+
+ rawSymbol = False;
if (condPushBack == None) {
while (*condExpr == ' ' || *condExpr == '\t') {
@@ -580,11 +587,7 @@
t = EndOfFile;
break;
case '$': {
- char *lhs;
- char *rhs;
- char *op;
int varSpecLen;
- Boolean doFree;
/*
* Parse the variable spec and skip over it, saving its
@@ -601,6 +604,7 @@
}
condExpr += varSpecLen;
+ do_expr:
if (!isspace((unsigned char) *condExpr) &&
strchr("!=><", *condExpr) == NULL) {
Buffer buf;
@@ -950,10 +954,28 @@
* binary operator) and set to invert the evaluation
* function if condInvert is TRUE.
*/
+ rawSymbol = True;
use_default:
invert = condInvert;
evalProc = condDefProc;
arglen = CondGetArg(&condExpr, &arg, "", FALSE);
+
+ if (rawSymbol) {
+ char *cp = condExpr;
+
+ while (isspace((unsigned char) *cp)) {
+ cp++;
+ }
+ switch (*cp) {
+ case '!':
+ case '=':
+ case '<':
+ case '>':
+ doFree = (arglen > 0);
+ lhs = arg;
+ goto do_expr;
+ }
+ }
}
/*