Mon Nov 2 18:24:42 2020 UTC ()
make(1): use freeIt pattern in Arch_ParseArchive

This makes the memory management more obvious than before, where the
status of the variable libName depended on subLibName.


(rillig)
diff -r1.151 -r1.152 src/usr.bin/make/arch.c

cvs diff -r1.151 -r1.152 src/usr.bin/make/arch.c (expand / switch to unified diff)

--- src/usr.bin/make/arch.c 2020/10/31 18:41:07 1.151
+++ src/usr.bin/make/arch.c 2020/11/02 18:24:42 1.152
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: arch.c,v 1.151 2020/10/31 18:41:07 rillig Exp $ */ 1/* $NetBSD: arch.c,v 1.152 2020/11/02 18:24:42 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -120,27 +120,27 @@ @@ -120,27 +120,27 @@
120#include <sys/types.h> 120#include <sys/types.h>
121#include <sys/stat.h> 121#include <sys/stat.h>
122#include <sys/time.h> 122#include <sys/time.h>
123#include <sys/param.h> 123#include <sys/param.h>
124 124
125#include <ar.h> 125#include <ar.h>
126#include <utime.h> 126#include <utime.h>
127 127
128#include "make.h" 128#include "make.h"
129#include "dir.h" 129#include "dir.h"
130#include "config.h" 130#include "config.h"
131 131
132/* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */ 132/* "@(#)arch.c 8.2 (Berkeley) 1/2/94" */
133MAKE_RCSID("$NetBSD: arch.c,v 1.151 2020/10/31 18:41:07 rillig Exp $"); 133MAKE_RCSID("$NetBSD: arch.c,v 1.152 2020/11/02 18:24:42 rillig Exp $");
134 134
135#ifdef TARGET_MACHINE 135#ifdef TARGET_MACHINE
136#undef MAKE_MACHINE 136#undef MAKE_MACHINE
137#define MAKE_MACHINE TARGET_MACHINE 137#define MAKE_MACHINE TARGET_MACHINE
138#endif 138#endif
139#ifdef TARGET_MACHINE_ARCH 139#ifdef TARGET_MACHINE_ARCH
140#undef MAKE_MACHINE_ARCH 140#undef MAKE_MACHINE_ARCH
141#define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH 141#define MAKE_MACHINE_ARCH TARGET_MACHINE_ARCH
142#endif 142#endif
143 143
144typedef struct List ArchList; 144typedef struct List ArchList;
145typedef struct ListNode ArchListNode; 145typedef struct ListNode ArchListNode;
146 146
@@ -195,64 +195,67 @@ ArchFree(void *ap) @@ -195,64 +195,67 @@ ArchFree(void *ap)
195 * 195 *
196 * Results: 196 * Results:
197 * TRUE if it was a valid specification. The linePtr is updated 197 * TRUE if it was a valid specification. The linePtr is updated
198 * to point to the first non-space after the archive spec. The 198 * to point to the first non-space after the archive spec. The
199 * nodes for the members are placed on the given list. 199 * nodes for the members are placed on the given list.
200 *----------------------------------------------------------------------- 200 *-----------------------------------------------------------------------
201 */ 201 */
202Boolean 202Boolean
203Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, GNode *ctxt) 203Arch_ParseArchive(char **linePtr, GNodeList *nodeLst, GNode *ctxt)
204{ 204{
205 char *cp; /* Pointer into line */ 205 char *cp; /* Pointer into line */
206 GNode *gn; /* New node */ 206 GNode *gn; /* New node */
207 char *libName; /* Library-part of specification */ 207 char *libName; /* Library-part of specification */
 208 char *libName_freeIt = NULL;
208 char *memName; /* Member-part of specification */ 209 char *memName; /* Member-part of specification */
209 char saveChar; /* Ending delimiter of member-name */ 210 char saveChar; /* Ending delimiter of member-name */
210 Boolean subLibName; /* TRUE if libName should have/had 211 Boolean subLibName; /* TRUE if libName should have/had
211 * variable substitution performed on it */ 212 * variable substitution performed on it */
212 213
213 libName = *linePtr; 214 libName = *linePtr;
214 215
215 subLibName = FALSE; 216 subLibName = FALSE;
216 217
217 for (cp = libName; *cp != '(' && *cp != '\0';) { 218 for (cp = libName; *cp != '(' && *cp != '\0';) {
218 if (*cp == '$') { 219 if (*cp == '$') {
219 /* 220 /*
220 * Variable spec, so call the Var module to parse the puppy 221 * Variable spec, so call the Var module to parse the puppy
221 * so we can safely advance beyond it... 222 * so we can safely advance beyond it...
222 */ 223 */
223 const char *nested_p = cp; 224 const char *nested_p = cp;
224 void *result_freeIt; 225 void *result_freeIt;
225 const char *result; 226 const char *result;
226 Boolean isError; 227 Boolean isError;
227 228
 229 /* XXX: is expanded twice: once here and once below */
228 (void)Var_Parse(&nested_p, ctxt, VARE_UNDEFERR|VARE_WANTRES, 230 (void)Var_Parse(&nested_p, ctxt, VARE_UNDEFERR|VARE_WANTRES,
229 &result, &result_freeIt); 231 &result, &result_freeIt);
230 /* TODO: handle errors */ 232 /* TODO: handle errors */
231 isError = result == var_Error; 233 isError = result == var_Error;
232 free(result_freeIt); 234 free(result_freeIt);
233 if (isError) 235 if (isError)
234 return FALSE; 236 return FALSE;
235 237
236 subLibName = TRUE; 238 subLibName = TRUE;
237 cp += nested_p - cp; 239 cp += nested_p - cp;
238 } else 240 } else
239 cp++; 241 cp++;
240 } 242 }
241 243
242 *cp++ = '\0'; 244 *cp++ = '\0';
243 if (subLibName) { 245 if (subLibName) {
244 (void)Var_Subst(libName, ctxt, VARE_UNDEFERR|VARE_WANTRES, &libName); 246 (void)Var_Subst(libName, ctxt, VARE_UNDEFERR|VARE_WANTRES, &libName);
245 /* TODO: handle errors */ 247 /* TODO: handle errors */
 248 libName_freeIt = libName;
246 } 249 }
247 250
248 251
249 for (;;) { 252 for (;;) {
250 /* 253 /*
251 * First skip to the start of the member's name, mark that 254 * First skip to the start of the member's name, mark that
252 * place and skip to the end of it (either white-space or 255 * place and skip to the end of it (either white-space or
253 * a close paren). 256 * a close paren).
254 */ 257 */
255 Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */ 258 Boolean doSubst = FALSE; /* TRUE if need to substitute in memName */
256 259
257 pp_skip_whitespace(&cp); 260 pp_skip_whitespace(&cp);
258 261
@@ -378,32 +381,27 @@ Arch_ParseArchive(char **linePtr, GNodeL @@ -378,32 +381,27 @@ Arch_ParseArchive(char **linePtr, GNodeL
378 * the OP_ARCHV bit before we place it on the end of the 381 * the OP_ARCHV bit before we place it on the end of the
379 * provided list. 382 * provided list.
380 */ 383 */
381 gn->type |= OP_ARCHV; 384 gn->type |= OP_ARCHV;
382 Lst_Append(nodeLst, gn); 385 Lst_Append(nodeLst, gn);
383 } 386 }
384 if (doSubst) { 387 if (doSubst) {
385 free(memName); 388 free(memName);
386 } 389 }
387 390
388 *cp = saveChar; 391 *cp = saveChar;
389 } 392 }
390 393
391 /* 394 free(libName_freeIt);
392 * If substituted libName, free it now, since we need it no longer. 
393 */ 
394 if (subLibName) { 
395 free(libName); 
396 } 
397 395
398 cp++; /* skip the ')' */ 396 cp++; /* skip the ')' */
399 /* We promised that linePtr would be set up at the next non-space. */ 397 /* We promised that linePtr would be set up at the next non-space. */
400 pp_skip_whitespace(&cp); 398 pp_skip_whitespace(&cp);
401 *linePtr = cp; 399 *linePtr = cp;
402 return TRUE; 400 return TRUE;
403} 401}
404 402
405/* Locate a member of an archive, given the path of the archive and the path 403/* Locate a member of an archive, given the path of the archive and the path
406 * of the desired member. 404 * of the desired member.
407 * 405 *
408 * Input: 406 * Input:
409 * archive Path to the archive 407 * archive Path to the archive