cond.c (144473) | cond.c (144894) |
---|---|
1/*- 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1988, 1989 by Adam de Boor 5 * Copyright (c) 1989 by Berkeley Softworks 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by --- 26 unchanged lines hidden (view full) --- 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)cond.c 8.2 (Berkeley) 1/2/94 40 */ 41 42#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1988, 1989 by Adam de Boor 5 * Copyright (c) 1989 by Berkeley Softworks 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by --- 26 unchanged lines hidden (view full) --- 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)cond.c 8.2 (Berkeley) 1/2/94 40 */ 41 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/usr.bin/make/cond.c 144473 2005-04-01 12:31:15Z harti $"); | 43__FBSDID("$FreeBSD: head/usr.bin/make/cond.c 144894 2005-04-11 07:20:10Z harti $"); |
44 45/* 46 * Functions to handle conditionals in a makefile. 47 * 48 * Interface: 49 * Cond_Eval Evaluate the conditional in the passed line. 50 */ 51 --- 70 unchanged lines hidden (view full) --- 122static CondProc CondDoExists; 123static CondProc CondDoTarget; 124static char *CondCvtArg(char *, double *); 125static Token CondToken(Boolean); 126static Token CondT(Boolean); 127static Token CondF(Boolean); 128static Token CondE(Boolean); 129 | 44 45/* 46 * Functions to handle conditionals in a makefile. 47 * 48 * Interface: 49 * Cond_Eval Evaluate the conditional in the passed line. 50 */ 51 --- 70 unchanged lines hidden (view full) --- 122static CondProc CondDoExists; 123static CondProc CondDoTarget; 124static char *CondCvtArg(char *, double *); 125static Token CondToken(Boolean); 126static Token CondT(Boolean); 127static Token CondF(Boolean); 128static Token CondE(Boolean); 129 |
130static struct If { 131 char *form; /* Form of if */ 132 int formlen; /* Length of form */ | 130static const struct If { |
133 Boolean doNot; /* TRUE if default function should be negated */ 134 CondProc *defProc; /* Default function to apply */ | 131 Boolean doNot; /* TRUE if default function should be negated */ 132 CondProc *defProc; /* Default function to apply */ |
133 Boolean isElse; /* actually el<XXX> */ |
|
135} ifs[] = { | 134} ifs[] = { |
136 { "ifdef", 5, FALSE, CondDoDefined }, 137 { "ifndef", 6, TRUE, CondDoDefined }, 138 { "ifmake", 6, FALSE, CondDoMake }, 139 { "ifnmake", 7, TRUE, CondDoMake }, 140 { "if", 2, FALSE, CondDoDefined }, 141 { NULL, 0, FALSE, NULL } | 135 [COND_IF] = { FALSE, CondDoDefined, FALSE }, 136 [COND_IFDEF] = { FALSE, CondDoDefined, FALSE }, 137 [COND_IFNDEF] = { TRUE, CondDoDefined, FALSE }, 138 [COND_IFMAKE] = { FALSE, CondDoMake, FALSE }, 139 [COND_IFNMAKE] = { TRUE, CondDoMake, FALSE }, 140 [COND_ELIF] = { FALSE, CondDoDefined, TRUE }, 141 [COND_ELIFDEF] = { FALSE, CondDoDefined, TRUE }, 142 [COND_ELIFNDEF] = { TRUE, CondDoDefined, TRUE }, 143 [COND_ELIFMAKE] = { FALSE, CondDoMake, TRUE }, 144 [COND_ELIFNMAKE] = { TRUE, CondDoMake, TRUE }, |
142}; 143 144static Boolean condInvert; /* Invert the default function */ 145static CondProc *condDefProc; /* default function to apply */ 146static char *condExpr; /* The expression to parse */ 147static Token condPushBack = None; /* Single push-back token in parsing */ 148 149#define MAXIF 30 /* greatest depth of #if'ing */ 150 151static Boolean condStack[MAXIF]; /* Stack of conditionals's values */ 152static int condLineno[MAXIF]; /* Line numbers of the opening .if */ 153static int condTop = MAXIF; /* Top-most conditional */ 154static int skipIfLevel = 0; /* Depth of skipped conditionals */ 155static int skipIfLineno[MAXIF]; /* Line numbers of skipped .ifs */ | 145}; 146 147static Boolean condInvert; /* Invert the default function */ 148static CondProc *condDefProc; /* default function to apply */ 149static char *condExpr; /* The expression to parse */ 150static Token condPushBack = None; /* Single push-back token in parsing */ 151 152#define MAXIF 30 /* greatest depth of #if'ing */ 153 154static Boolean condStack[MAXIF]; /* Stack of conditionals's values */ 155static int condLineno[MAXIF]; /* Line numbers of the opening .if */ 156static int condTop = MAXIF; /* Top-most conditional */ 157static int skipIfLevel = 0; /* Depth of skipped conditionals */ 158static int skipIfLineno[MAXIF]; /* Line numbers of skipped .ifs */ |
156static Boolean skipLine = FALSE; /* Whether the parse module is skipping | 159Boolean skipLine = FALSE; /* Whether the parse module is skipping |
157 * lines */ 158 159/** 160 * CondPushBack 161 * Push back the most recent token read. We only need one level of 162 * this, so the thing is just stored in 'condPushback'. 163 * 164 * Side Effects: --- 835 unchanged lines hidden (view full) --- 1000 */ 1001 CondPushBack(o); 1002 } 1003 } 1004 return (l); 1005} 1006 1007/** | 160 * lines */ 161 162/** 163 * CondPushBack 164 * Push back the most recent token read. We only need one level of 165 * this, so the thing is just stored in 'condPushback'. 166 * 167 * Side Effects: --- 835 unchanged lines hidden (view full) --- 1003 */ 1004 CondPushBack(o); 1005 } 1006 } 1007 return (l); 1008} 1009 1010/** |
1008 * Cond_Eval -- 1009 * Evaluate the conditional in the passed line. The line 1010 * looks like this: 1011 * .<cond-type> <expr> 1012 * where <cond-type> is any of if, ifmake, ifnmake, ifdef, 1013 * ifndef, elif, elifmake, elifnmake, elifdef, elifndef 1014 * and <expr> consists of &&, ||, !, make(target), defined(variable) 1015 * and parenthetical groupings thereof. 1016 * 1017 * Results: 1018 * COND_PARSE if should parse lines after the conditional 1019 * COND_SKIP if should skip lines after the conditional 1020 * COND_INVALID if not a valid conditional. | 1011 * Cond_If 1012 * Handle .if<X> and .elif<X> directives. 1013 * This function is called even when we're skipping. |
1021 */ | 1014 */ |
1022int 1023Cond_Eval(char *line, int lineno) | 1015void 1016Cond_If(char *line, int code, int lineno) |
1024{ | 1017{ |
1025 struct If *ifp; 1026 Boolean isElse; 1027 Boolean value = FALSE; 1028 int level; /* Level at which to report errors. */ | 1018 const struct If *ifp; 1019 Boolean value; |
1029 | 1020 |
1030 level = PARSE_FATAL; | 1021 ifp = &ifs[code]; |
1031 | 1022 |
1032 for (line++; *line == ' ' || *line == '\t'; line++) { 1033 continue; 1034 } 1035 1036 /* 1037 * Find what type of if we're dealing with. The result is left 1038 * in ifp and isElse is set TRUE if it's an elif line. 1039 */ 1040 if (line[0] == 'e' && line[1] == 'l') { 1041 line += 2; 1042 isElse = TRUE; 1043 1044 } else if (strncmp(line, "endif", 5) == 0) { 1045 /* 1046 * End of a conditional section. If skipIfLevel is non-zero, 1047 * that conditional was skipped, so lines following it should 1048 * also be skipped. Hence, we return COND_SKIP. Otherwise, 1049 * the conditional was read so succeeding lines should be 1050 * parsed (think about it...) so we return COND_PARSE, unless 1051 * this endif isn't paired with a decent if. 1052 */ 1053 if (skipIfLevel != 0) { 1054 skipIfLevel -= 1; 1055 return (COND_SKIP); 1056 } else { 1057 if (condTop == MAXIF) { 1058 Parse_Error(level, "if-less endif"); 1059 return (COND_INVALID); 1060 } else { 1061 skipLine = FALSE; 1062 condTop += 1; 1063 return (COND_PARSE); 1064 } | 1023 if (ifp->isElse) { 1024 if (condTop == MAXIF) { 1025 Parse_Error(PARSE_FATAL, "if-less elif"); 1026 return; |
1065 } | 1027 } |
1066 } else { 1067 isElse = FALSE; 1068 } 1069 1070 /* 1071 * Figure out what sort of conditional it is -- what its default 1072 * function is, etc. -- by looking in the table of valid "ifs" 1073 */ 1074 for (ifp = ifs; ifp->form != NULL; ifp++) { 1075 if (strncmp(ifp->form, line, ifp->formlen) == 0) { 1076 break; 1077 } 1078 } 1079 1080 if (ifp->form == NULL) { 1081 /* 1082 * Nothing fit. If the first word on the line is actually 1083 * "else", it's a valid conditional whose value is the inverse 1084 * of the previous if we parsed. 1085 */ 1086 if (isElse && (line[0] == 's') && (line[1] == 'e')) { 1087 if (condTop == MAXIF) { 1088 Parse_Error(level, "if-less else"); 1089 return (COND_INVALID); 1090 } else if (skipIfLevel == 0) { 1091 value = !condStack[condTop]; 1092 lineno = condLineno[condTop]; 1093 } else { 1094 return (COND_SKIP); 1095 } 1096 } else { | 1028 if (skipIfLevel != 0) { |
1097 /* | 1029 /* |
1098 * Not a valid conditional type. No error... | 1030 * If skipping this conditional, just ignore 1031 * the whole thing. If we don't, the user 1032 * might be employing a variable that's 1033 * undefined, for which there's an enclosing 1034 * ifdef that we're skipping... |
1099 */ | 1035 */ |
1100 return (COND_INVALID); | 1036 skipIfLineno[skipIfLevel - 1] = lineno; 1037 return; |
1101 } 1102 | 1038 } 1039 |
1103 } else { 1104 if (isElse) { 1105 if (condTop == MAXIF) { 1106 Parse_Error(level, "if-less elif"); 1107 return (COND_INVALID); 1108 1109 } else if (skipIfLevel != 0) { 1110 /* 1111 * If skipping this conditional, just ignore 1112 * the whole thing. If we don't, the user 1113 * might be employing a variable that's 1114 * undefined, for which there's an enclosing 1115 * ifdef that we're skipping... 1116 */ 1117 skipIfLineno[skipIfLevel - 1] = lineno; 1118 return (COND_SKIP); 1119 } 1120 } else if (skipLine) { 1121 /* 1122 * Don't even try to evaluate a conditional that's 1123 * not an else if we're skipping things... 1124 */ 1125 skipIfLineno[skipIfLevel] = lineno; 1126 skipIfLevel += 1; 1127 return (COND_SKIP); 1128 } 1129 | 1040 } else if (skipLine) { |
1130 /* | 1041 /* |
1131 * Initialize file-global variables for parsing | 1042 * Don't even try to evaluate a conditional that's 1043 * not an else if we're skipping things... |
1132 */ | 1044 */ |
1133 condDefProc = ifp->defProc; 1134 condInvert = ifp->doNot; | 1045 skipIfLineno[skipIfLevel] = lineno; 1046 skipIfLevel += 1; 1047 return; 1048 } |
1135 | 1049 |
1136 line += ifp->formlen; | 1050 /* 1051 * Initialize file-global variables for parsing 1052 */ 1053 condDefProc = ifp->defProc; 1054 condInvert = ifp->doNot; |
1137 | 1055 |
1138 while (*line == ' ' || *line == '\t') { 1139 line++; 1140 } | 1056 while (*line == ' ' || *line == '\t') { 1057 line++; 1058 } |
1141 | 1059 |
1142 condExpr = line; 1143 condPushBack = None; | 1060 condExpr = line; 1061 condPushBack = None; |
1144 | 1062 |
1145 switch (CondE(TRUE)) { 1146 case True: 1147 if (CondToken(TRUE) == EndOfFile) { 1148 value = TRUE; 1149 break; 1150 } | 1063 switch (CondE(TRUE)) { 1064 case True: 1065 if (CondToken(TRUE) != EndOfFile) |
1151 goto err; | 1066 goto err; |
1152 /*FALLTHRU*/ | 1067 value = TRUE; 1068 break; |
1153 | 1069 |
1154 case False: 1155 if (CondToken(TRUE) == EndOfFile) { 1156 value = FALSE; 1157 break; 1158 } 1159 /*FALLTHRU*/ | 1070 case False: 1071 if (CondToken(TRUE) != EndOfFile) 1072 goto err; 1073 value = FALSE; 1074 break; |
1160 | 1075 |
1161 case Err: 1162 err: 1163 Parse_Error(level, "Malformed conditional (%s)", line); 1164 return (COND_INVALID); 1165 default: 1166 break; 1167 } | 1076 case Err: 1077 err: Parse_Error(PARSE_FATAL, "Malformed conditional (%s)", line); 1078 return; 1079 1080 default: 1081 abort(); |
1168 } | 1082 } |
1169 if (!isElse) { | 1083 1084 if (!ifp->isElse) { 1085 /* push this value */ |
1170 condTop -= 1; 1171 | 1086 condTop -= 1; 1087 |
1172 } else if ((skipIfLevel != 0) || condStack[condTop]) { | 1088 } else if (skipIfLevel != 0 || condStack[condTop]) { |
1173 /* 1174 * If this is an else-type conditional, it should only take 1175 * effect if its corresponding if was evaluated and FALSE. 1176 * If its if was TRUE or skipped, we return COND_SKIP (and 1177 * start skipping in case we weren't already), leaving the 1178 * stack unmolested so later elif's don't screw up... 1179 */ 1180 skipLine = TRUE; | 1089 /* 1090 * If this is an else-type conditional, it should only take 1091 * effect if its corresponding if was evaluated and FALSE. 1092 * If its if was TRUE or skipped, we return COND_SKIP (and 1093 * start skipping in case we weren't already), leaving the 1094 * stack unmolested so later elif's don't screw up... 1095 */ 1096 skipLine = TRUE; |
1181 return (COND_SKIP); | 1097 return; |
1182 } 1183 1184 if (condTop < 0) { 1185 /* 1186 * This is the one case where we can definitely proclaim a fatal 1187 * error. If we don't, we're hosed. 1188 */ | 1098 } 1099 1100 if (condTop < 0) { 1101 /* 1102 * This is the one case where we can definitely proclaim a fatal 1103 * error. If we don't, we're hosed. 1104 */ |
1189 Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.", 1190 MAXIF); 1191 return (COND_INVALID); 1192 } else { 1193 condStack[condTop] = value; 1194 condLineno[condTop] = lineno; 1195 skipLine = !value; 1196 return (value ? COND_PARSE : COND_SKIP); | 1105 Parse_Error(PARSE_FATAL, "Too many nested if's. %d max.",MAXIF); 1106 return; |
1197 } | 1107 } |
1108 1109 /* push */ 1110 condStack[condTop] = value; 1111 condLineno[condTop] = lineno; 1112 skipLine = !value; |
|
1198} 1199 1200/** | 1113} 1114 1115/** |
1116 * Cond_Else 1117 * Handle .else statement. 1118 */ 1119void 1120Cond_Else(char *line __unused, int code __unused, int lineno __unused) 1121{ 1122 1123 while (isspace((u_char)*line)) 1124 line++; 1125 1126 if (*line != '\0') { 1127 Parse_Error(PARSE_WARNING, "junk after .else ignored '%s'", line); 1128 } 1129 1130 if (condTop == MAXIF) { 1131 Parse_Error(PARSE_FATAL, "if-less else"); 1132 return; 1133 } 1134 if (skipIfLevel != 0) 1135 return; 1136 1137 if (skipIfLevel != 0 || condStack[condTop]) { 1138 /* 1139 * An else should only take effect if its corresponding if was 1140 * evaluated and FALSE. 1141 * If its if was TRUE or skipped, we return COND_SKIP (and 1142 * start skipping in case we weren't already), leaving the 1143 * stack unmolested so later elif's don't screw up... 1144 * XXX How does this work with two .else's? 1145 */ 1146 skipLine = TRUE; 1147 return; 1148 } 1149 1150 /* inverse value */ 1151 condStack[condTop] = !condStack[condTop]; 1152 skipLine = !condStack[condTop]; 1153} 1154 1155/** 1156 * Cond_Endif 1157 * Handle .endif statement. 1158 */ 1159void 1160Cond_Endif(char *line __unused, int code __unused, int lineno __unused) 1161{ 1162 1163 while (isspace((u_char)*line)) 1164 line++; 1165 1166 if (*line != '\0') { 1167 Parse_Error(PARSE_WARNING, "junk after .endif ignored '%s'", line); 1168 } 1169 /* 1170 * End of a conditional section. If skipIfLevel is non-zero, 1171 * that conditional was skipped, so lines following it should 1172 * also be skipped. Hence, we return COND_SKIP. Otherwise, 1173 * the conditional was read so succeeding lines should be 1174 * parsed (think about it...) so we return COND_PARSE, unless 1175 * this endif isn't paired with a decent if. 1176 */ 1177 if (skipIfLevel != 0) { 1178 skipIfLevel -= 1; 1179 return; 1180 } 1181 1182 if (condTop == MAXIF) { 1183 Parse_Error(PARSE_FATAL, "if-less endif"); 1184 return; 1185 } 1186 1187 /* pop */ 1188 skipLine = FALSE; 1189 condTop += 1; 1190} 1191 1192/** |
|
1201 * Cond_End 1202 * Make sure everything's clean at the end of a makefile. 1203 * 1204 * Side Effects: 1205 * Parse_Error will be called if open conditionals are around. 1206 */ 1207void 1208Cond_End(void) --- 20 unchanged lines hidden --- | 1193 * Cond_End 1194 * Make sure everything's clean at the end of a makefile. 1195 * 1196 * Side Effects: 1197 * Parse_Error will be called if open conditionals are around. 1198 */ 1199void 1200Cond_End(void) --- 20 unchanged lines hidden --- |