Deleted Added
full compact
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 ---