var.c (29957) | var.c (36588) |
---|---|
1/* 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1989 by Berkeley Softworks 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. --- 21 unchanged lines hidden (view full) --- 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * | 1/* 2 * Copyright (c) 1988, 1989, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * Copyright (c) 1989 by Berkeley Softworks 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. --- 21 unchanged lines hidden (view full) --- 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * |
38 * $Id: var.c,v 1.9 1997/02/22 19:27:25 peter Exp $ | 38 * $Id: var.c,v 1.10 1997/09/29 03:53:53 imp Exp $ |
39 */ 40 41#ifndef lint 42static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 43#endif /* not lint */ 44 45/*- 46 * var.c -- --- 1062 unchanged lines hidden (view full) --- 1109 * or braces */ 1110 int cnt; /* Used to count brace pairs when variable in 1111 * in parens or braces */ 1112 char *start; 1113 Boolean dynamic; /* TRUE if the variable is local and we're 1114 * expanding it in a non-local context. This 1115 * is done to support dynamic sources. The 1116 * result is just the invocation, unaltered */ | 39 */ 40 41#ifndef lint 42static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 43#endif /* not lint */ 44 45/*- 46 * var.c -- --- 1062 unchanged lines hidden (view full) --- 1109 * or braces */ 1110 int cnt; /* Used to count brace pairs when variable in 1111 * in parens or braces */ 1112 char *start; 1113 Boolean dynamic; /* TRUE if the variable is local and we're 1114 * expanding it in a non-local context. This 1115 * is done to support dynamic sources. The 1116 * result is just the invocation, unaltered */ |
1117 int vlen; /* length of variable name, after embedded variable 1118 * expansion */ |
|
1117 1118 *freePtr = FALSE; 1119 dynamic = FALSE; 1120 start = str; 1121 1122 if (str[1] != '(' && str[1] != '{') { 1123 /* 1124 * If it's not bounded by braces of some sort, life is much simpler. --- 35 unchanged lines hidden (view full) --- 1160 */ 1161 return (err ? var_Error : varNoError); 1162 } else { 1163 haveModifier = FALSE; 1164 tstr = &str[1]; 1165 endc = str[1]; 1166 } 1167 } else { | 1119 1120 *freePtr = FALSE; 1121 dynamic = FALSE; 1122 start = str; 1123 1124 if (str[1] != '(' && str[1] != '{') { 1125 /* 1126 * If it's not bounded by braces of some sort, life is much simpler. --- 35 unchanged lines hidden (view full) --- 1162 */ 1163 return (err ? var_Error : varNoError); 1164 } else { 1165 haveModifier = FALSE; 1166 tstr = &str[1]; 1167 endc = str[1]; 1168 } 1169 } else { |
1170 /* build up expanded variable name in this buffer */ 1171 Buffer buf = Buf_Init(MAKE_BSIZE); 1172 |
|
1168 startc = str[1]; 1169 endc = startc == '(' ? ')' : '}'; 1170 1171 /* | 1173 startc = str[1]; 1174 endc = startc == '(' ? ')' : '}'; 1175 1176 /* |
1172 * Skip to the end character or a colon, whichever comes first. | 1177 * Skip to the end character or a colon, whichever comes first, 1178 * replacing embedded variables as we go. |
1173 */ | 1179 */ |
1174 for (tstr = str + 2; 1175 *tstr != '\0' && *tstr != endc && *tstr != ':'; 1176 tstr++) 1177 { 1178 continue; 1179 } 1180 if (*tstr == ':') { 1181 haveModifier = TRUE; 1182 } else if (*tstr != '\0') { 1183 haveModifier = FALSE; 1184 } else { | 1180 for (tstr = str + 2; *tstr != '\0' && *tstr != endc && *tstr != ':'; tstr++) 1181 if (*tstr == '$') { 1182 int rlen; 1183 Boolean rfree; 1184 char* rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree); 1185 1186 if (rval == var_Error) { 1187 Fatal("Error expanding embedded variable."); 1188 } else if (rval != NULL) { 1189 Buf_AddBytes(buf, strlen(rval), (Byte *) rval); 1190 if (rfree) 1191 free(rval); 1192 } 1193 tstr += rlen - 1; 1194 } else 1195 Buf_AddByte(buf, (Byte) *tstr); 1196 1197 if (*tstr == '\0') { |
1185 /* 1186 * If we never did find the end character, return NULL 1187 * right now, setting the length to be the distance to 1188 * the end of the string, since that's what make does. 1189 */ 1190 *lengthPtr = tstr - str; 1191 return (var_Error); 1192 } | 1198 /* 1199 * If we never did find the end character, return NULL 1200 * right now, setting the length to be the distance to 1201 * the end of the string, since that's what make does. 1202 */ 1203 *lengthPtr = tstr - str; 1204 return (var_Error); 1205 } |
1206 1207 haveModifier = (*tstr == ':'); |
|
1193 *tstr = '\0'; 1194 | 1208 *tstr = '\0'; 1209 |
1195 v = VarFind (str + 2, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); | 1210 Buf_AddByte(buf, (Byte) '\0'); 1211 str = Buf_GetAll(buf, NULL); 1212 vlen = strlen(str); 1213 1214 v = VarFind (str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); |
1196 if ((v == (Var *)NIL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) && | 1215 if ((v == (Var *)NIL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) && |
1197 ((tstr-str) == 4) && (str[3] == 'F' || str[3] == 'D')) | 1216 (vlen == 2) && (str[1] == 'F' || str[1] == 'D')) |
1198 { 1199 /* 1200 * Check for bogus D and F forms of local variables since we're 1201 * in a local context and the name is the right length. 1202 */ | 1217 { 1218 /* 1219 * Check for bogus D and F forms of local variables since we're 1220 * in a local context and the name is the right length. 1221 */ |
1203 switch(str[2]) { | 1222 switch(str[0]) { |
1204 case '@': 1205 case '%': 1206 case '*': 1207 case '!': 1208 case '>': 1209 case '<': 1210 { 1211 char vname[2]; 1212 char *val; 1213 1214 /* 1215 * Well, it's local -- go look for it. 1216 */ | 1223 case '@': 1224 case '%': 1225 case '*': 1226 case '!': 1227 case '>': 1228 case '<': 1229 { 1230 char vname[2]; 1231 char *val; 1232 1233 /* 1234 * Well, it's local -- go look for it. 1235 */ |
1217 vname[0] = str[2]; | 1236 vname[0] = str[0]; |
1218 vname[1] = '\0'; 1219 v = VarFind(vname, ctxt, 0); 1220 1221 if (v != (Var *)NIL) { 1222 /* 1223 * No need for nested expansion or anything, as we're 1224 * the only one who sets these things and we sure don't | 1237 vname[1] = '\0'; 1238 v = VarFind(vname, ctxt, 0); 1239 1240 if (v != (Var *)NIL) { 1241 /* 1242 * No need for nested expansion or anything, as we're 1243 * the only one who sets these things and we sure don't |
1225 * but nested invocations in them... | 1244 * put nested invocations in them... |
1226 */ 1227 val = (char *)Buf_GetAll(v->val, (int *)NULL); 1228 | 1245 */ 1246 val = (char *)Buf_GetAll(v->val, (int *)NULL); 1247 |
1229 if (str[3] == 'D') { | 1248 if (str[1] == 'D') { |
1230 val = VarModify(val, VarHead, (ClientData)0); 1231 } else { 1232 val = VarModify(val, VarTail, (ClientData)0); 1233 } 1234 /* 1235 * Resulting string is dynamically allocated, so 1236 * tell caller to free it. 1237 */ 1238 *freePtr = TRUE; 1239 *lengthPtr = tstr-start+1; 1240 *tstr = endc; | 1249 val = VarModify(val, VarHead, (ClientData)0); 1250 } else { 1251 val = VarModify(val, VarTail, (ClientData)0); 1252 } 1253 /* 1254 * Resulting string is dynamically allocated, so 1255 * tell caller to free it. 1256 */ 1257 *freePtr = TRUE; 1258 *lengthPtr = tstr-start+1; 1259 *tstr = endc; |
1260 Buf_Destroy(buf, TRUE); |
|
1241 return(val); 1242 } 1243 break; 1244 } 1245 } 1246 } 1247 1248 if (v == (Var *)NIL) { | 1261 return(val); 1262 } 1263 break; 1264 } 1265 } 1266 } 1267 1268 if (v == (Var *)NIL) { |
1249 if ((((tstr-str) == 3) || 1250 ((((tstr-str) == 4) && (str[3] == 'F' || 1251 str[3] == 'D')))) && | 1269 if (((vlen == 1) || 1270 (((vlen == 2) && (str[1] == 'F' || 1271 str[1] == 'D')))) && |
1252 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) 1253 { 1254 /* 1255 * If substituting a local variable in a non-local context, 1256 * assume it's for dynamic source stuff. We have to handle 1257 * this specially and return the longhand for the variable 1258 * with the dollar sign escaped so it makes it back to the 1259 * caller. Only four of the local variables are treated 1260 * specially as they are the only four that will be set 1261 * when dynamic sources are expanded. 1262 */ | 1272 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) 1273 { 1274 /* 1275 * If substituting a local variable in a non-local context, 1276 * assume it's for dynamic source stuff. We have to handle 1277 * this specially and return the longhand for the variable 1278 * with the dollar sign escaped so it makes it back to the 1279 * caller. Only four of the local variables are treated 1280 * specially as they are the only four that will be set 1281 * when dynamic sources are expanded. 1282 */ |
1263 switch (str[2]) { | 1283 switch (str[0]) { |
1264 case '@': 1265 case '%': 1266 case '*': 1267 case '!': 1268 dynamic = TRUE; 1269 break; 1270 } | 1284 case '@': 1285 case '%': 1286 case '*': 1287 case '!': 1288 dynamic = TRUE; 1289 break; 1290 } |
1271 } else if (((tstr-str) > 4) && (str[2] == '.') && 1272 isupper((unsigned char) str[3]) && | 1291 } else if ((vlen > 2) && (str[0] == '.') && 1292 isupper((unsigned char) str[1]) && |
1273 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) 1274 { 1275 int len; 1276 | 1293 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) 1294 { 1295 int len; 1296 |
1277 len = (tstr-str) - 3; 1278 if ((strncmp(str+2, ".TARGET", len) == 0) || 1279 (strncmp(str+2, ".ARCHIVE", len) == 0) || 1280 (strncmp(str+2, ".PREFIX", len) == 0) || 1281 (strncmp(str+2, ".MEMBER", len) == 0)) | 1297 len = vlen - 1; 1298 if ((strncmp(str, ".TARGET", len) == 0) || 1299 (strncmp(str, ".ARCHIVE", len) == 0) || 1300 (strncmp(str, ".PREFIX", len) == 0) || 1301 (strncmp(str, ".MEMBER", len) == 0)) |
1282 { 1283 dynamic = TRUE; 1284 } 1285 } 1286 1287 if (!haveModifier) { 1288 /* 1289 * No modifiers -- have specification length so we can return 1290 * now. 1291 */ 1292 *lengthPtr = tstr - start + 1; 1293 *tstr = endc; 1294 if (dynamic) { 1295 str = emalloc(*lengthPtr + 1); 1296 strncpy(str, start, *lengthPtr); 1297 str[*lengthPtr] = '\0'; 1298 *freePtr = TRUE; | 1302 { 1303 dynamic = TRUE; 1304 } 1305 } 1306 1307 if (!haveModifier) { 1308 /* 1309 * No modifiers -- have specification length so we can return 1310 * now. 1311 */ 1312 *lengthPtr = tstr - start + 1; 1313 *tstr = endc; 1314 if (dynamic) { 1315 str = emalloc(*lengthPtr + 1); 1316 strncpy(str, start, *lengthPtr); 1317 str[*lengthPtr] = '\0'; 1318 *freePtr = TRUE; |
1319 Buf_Destroy(buf, TRUE); |
|
1299 return(str); 1300 } else { | 1320 return(str); 1321 } else { |
1322 Buf_Destroy(buf, TRUE); |
|
1301 return (err ? var_Error : varNoError); 1302 } 1303 } else { 1304 /* 1305 * Still need to get to the end of the variable specification, 1306 * so kludge up a Var structure for the modifications 1307 */ 1308 v = (Var *) emalloc(sizeof(Var)); 1309 v->name = &str[1]; 1310 v->val = Buf_Init(1); 1311 v->flags = VAR_JUNK; 1312 } 1313 } | 1323 return (err ? var_Error : varNoError); 1324 } 1325 } else { 1326 /* 1327 * Still need to get to the end of the variable specification, 1328 * so kludge up a Var structure for the modifications 1329 */ 1330 v = (Var *) emalloc(sizeof(Var)); 1331 v->name = &str[1]; 1332 v->val = Buf_Init(1); 1333 v->flags = VAR_JUNK; 1334 } 1335 } |
1336 Buf_Destroy(buf, TRUE); |
|
1314 } 1315 1316 if (v->flags & VAR_IN_USE) { 1317 Fatal("Variable %s is recursive.", v->name); 1318 /*NOTREACHED*/ 1319 } else { 1320 v->flags |= VAR_IN_USE; 1321 } --- 724 unchanged lines hidden --- | 1337 } 1338 1339 if (v->flags & VAR_IN_USE) { 1340 Fatal("Variable %s is recursive.", v->name); 1341 /*NOTREACHED*/ 1342 } else { 1343 v->flags |= VAR_IN_USE; 1344 } --- 724 unchanged lines hidden --- |