version 1.2, 1996/06/26 05:36:28 |
version 1.3, 1996/11/30 21:08:52 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
/* $NetBSD: cond.c,v 1.6 1995/06/14 15:18:58 christos Exp $ */ |
/* $NetBSD: cond.c,v 1.7 1996/11/06 17:59:02 christos Exp $ */ |
|
|
/* |
/* |
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
|
|
|
|
#ifndef lint |
#ifndef lint |
#if 0 |
#if 0 |
static char sccsid[] = "@(#)cond.c 5.6 (Berkeley) 6/1/90"; |
static char sccsid[] = "@(#)cond.c 8.2 (Berkeley) 1/2/94"; |
#else |
#else |
static char rcsid[] = "$OpenBSD$"; |
static char rcsid[] = "$OpenBSD$"; |
#endif |
#endif |
|
|
* Structures to handle elegantly the different forms of #if's. The |
* Structures to handle elegantly the different forms of #if's. The |
* last two fields are stored in condInvert and condDefProc, respectively. |
* last two fields are stored in condInvert and condDefProc, respectively. |
*/ |
*/ |
|
static void CondPushBack __P((Token)); |
static int CondGetArg __P((char **, char **, char *, Boolean)); |
static int CondGetArg __P((char **, char **, char *, Boolean)); |
static Boolean CondDoDefined __P((int, char *)); |
static Boolean CondDoDefined __P((int, char *)); |
static int CondStrMatch __P((ClientData, ClientData)); |
static int CondStrMatch __P((ClientData, ClientData)); |
|
|
char *form; /* Form of if */ |
char *form; /* Form of if */ |
int formlen; /* Length of form */ |
int formlen; /* Length of form */ |
Boolean doNot; /* TRUE if default function should be negated */ |
Boolean doNot; /* TRUE if default function should be negated */ |
Boolean (*defProc)(); /* Default function to apply */ |
Boolean (*defProc) __P((int, char *)); /* Default function to apply */ |
} ifs[] = { |
} ifs[] = { |
{ "ifdef", 5, FALSE, CondDoDefined }, |
{ "ifdef", 5, FALSE, CondDoDefined }, |
{ "ifndef", 6, TRUE, CondDoDefined }, |
{ "ifndef", 6, TRUE, CondDoDefined }, |
{ "ifmake", 6, FALSE, CondDoMake }, |
{ "ifmake", 6, FALSE, CondDoMake }, |
{ "ifnmake", 7, TRUE, CondDoMake }, |
{ "ifnmake", 7, TRUE, CondDoMake }, |
{ "if", 2, FALSE, CondDoDefined }, |
{ "if", 2, FALSE, CondDoDefined }, |
{ (char *)0, 0, FALSE, (Boolean (*)())0 } |
{ NULL, 0, FALSE, NULL } |
}; |
}; |
|
|
static Boolean condInvert; /* Invert the default function */ |
static Boolean condInvert; /* Invert the default function */ |
static Boolean (*condDefProc)(); /* Default function to apply */ |
static Boolean (*condDefProc) /* Default function to apply */ |
|
__P((int, char *)); |
static char *condExpr; /* The expression to parse */ |
static char *condExpr; /* The expression to parse */ |
static Token condPushBack=None; /* Single push-back token used in |
static Token condPushBack=None; /* Single push-back token used in |
* parsing */ |
* parsing */ |
|
|
* long. Why 16? Why not? |
* long. Why 16? Why not? |
*/ |
*/ |
buf = Buf_Init(16); |
buf = Buf_Init(16); |
|
|
while ((strchr(" \t)&|", *cp) == (char *)NULL) && (*cp != '\0')) { |
while ((strchr(" \t)&|", *cp) == (char *)NULL) && (*cp != '\0')) { |
if (*cp == '$') { |
if (*cp == '$') { |
/* |
/* |
|
|
*/ |
*/ |
cp++; |
cp++; |
} |
} |
|
|
*linePtr = cp; |
*linePtr = cp; |
return (argLen); |
return (argLen); |
} |
} |
|
|
* |
* |
* Side Effects: |
* Side Effects: |
* Can change 'value' even if string is not a valid number. |
* Can change 'value' even if string is not a valid number. |
* |
|
* |
* |
|
* |
*----------------------------------------------------------------------- |
*----------------------------------------------------------------------- |
*/ |
*/ |
static Boolean |
static Boolean |
|
|
|
|
buf = Buf_Init(0); |
buf = Buf_Init(0); |
qt = *rhs == '"' ? 1 : 0; |
qt = *rhs == '"' ? 1 : 0; |
|
|
for (cp = &rhs[qt]; |
for (cp = &rhs[qt]; |
((qt && (*cp != '"')) || |
((qt && (*cp != '"')) || |
(!qt && strchr(" \t)", *cp) == NULL)) && |
(!qt && strchr(" \t)", *cp) == NULL)) && |
(*cp != '\0'); cp++) { |
(*cp != '\0'); cp++) { |
if ((*cp == '\\') && (cp[1] != '\0')) { |
if ((*cp == '\\') && (cp[1] != '\0')) { |
/* |
/* |
|
|
} else if (*cp == '$') { |
} else if (*cp == '$') { |
int len; |
int len; |
Boolean freeIt; |
Boolean freeIt; |
|
|
cp2 = Var_Parse(cp, VAR_CMD, doEval,&len, &freeIt); |
cp2 = Var_Parse(cp, VAR_CMD, doEval,&len, &freeIt); |
if (cp2 != var_Error) { |
if (cp2 != var_Error) { |
Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2); |
Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2); |
|
|
if (*rhs == '$') { |
if (*rhs == '$') { |
int len; |
int len; |
Boolean freeIt; |
Boolean freeIt; |
|
|
string = Var_Parse(rhs, VAR_CMD, doEval,&len,&freeIt); |
string = Var_Parse(rhs, VAR_CMD, doEval,&len,&freeIt); |
if (string == var_Error) { |
if (string == var_Error) { |
right = 0.0; |
right = 0.0; |
|
|
} |
} |
} |
} |
} |
} |
|
|
if (DEBUG(COND)) { |
if (DEBUG(COND)) { |
printf("left = %f, right = %f, op = %.2s\n", left, |
printf("left = %f, right = %f, op = %.2s\n", left, |
right, op); |
right, op); |
|
|
break; |
break; |
} |
} |
default: { |
default: { |
Boolean (*evalProc)(); |
Boolean (*evalProc) __P((int, char *)); |
Boolean invert = FALSE; |
Boolean invert = FALSE; |
char *arg; |
char *arg; |
int arglen; |
int arglen; |
|
|
if (strncmp (condExpr, "defined", 7) == 0) { |
if (strncmp (condExpr, "defined", 7) == 0) { |
/* |
/* |
* Use CondDoDefined to evaluate the argument and |
* Use CondDoDefined to evaluate the argument and |
|
|
if (val == var_Error) { |
if (val == var_Error) { |
t = Err; |
t = Err; |
} else { |
} else { |
/* |
/* |
* A variable is empty when it just contains |
* A variable is empty when it just contains |
* spaces... 4/15/92, christos |
* spaces... 4/15/92, christos |
*/ |
*/ |
char *p; |
char *p; |
|
|
} else { |
} else { |
isElse = FALSE; |
isElse = FALSE; |
} |
} |
|
|
/* |
/* |
* Figure out what sort of conditional it is -- what its default |
* Figure out what sort of conditional it is -- what its default |
* function is, etc. -- by looking in the table of valid "ifs" |
* function is, etc. -- by looking in the table of valid "ifs" |
|
|
*/ |
*/ |
condDefProc = ifp->defProc; |
condDefProc = ifp->defProc; |
condInvert = ifp->doNot; |
condInvert = ifp->doNot; |
|
|
line += ifp->formlen; |
line += ifp->formlen; |
|
|
while (*line == ' ' || *line == '\t') { |
while (*line == ' ' || *line == '\t') { |
line++; |
line++; |
} |
} |
|
|
condExpr = line; |
condExpr = line; |
condPushBack = None; |
condPushBack = None; |
|
|
switch (CondE(TRUE)) { |
switch (CondE(TRUE)) { |
case True: |
case True: |
if (CondToken(TRUE) == EndOfFile) { |
if (CondToken(TRUE) == EndOfFile) { |