Sat Nov 21 15:32:52 2020 UTC ()
make(1): clean up freeing of environment variables in Var_Parse

The previous code with the extra boolean variable was a brain-twister
since the responsibility of freeing the memory was distributed over 3
different functions.


(rillig)
diff -r1.691 -r1.692 src/usr.bin/make/var.c

cvs diff -r1.691 -r1.692 src/usr.bin/make/var.c (expand / switch to unified diff)

--- src/usr.bin/make/var.c 2020/11/21 15:28:44 1.691
+++ src/usr.bin/make/var.c 2020/11/21 15:32:52 1.692
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.691 2020/11/21 15:28:44 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.692 2020/11/21 15:32:52 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 <regex.h> 120#include <regex.h>
121#endif 121#endif
122#include <errno.h> 122#include <errno.h>
123#include <inttypes.h> 123#include <inttypes.h>
124#include <limits.h> 124#include <limits.h>
125#include <time.h> 125#include <time.h>
126 126
127#include "make.h" 127#include "make.h"
128#include "dir.h" 128#include "dir.h"
129#include "job.h" 129#include "job.h"
130#include "metachar.h" 130#include "metachar.h"
131 131
132/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ 132/* "@(#)var.c 8.3 (Berkeley) 3/19/94" */
133MAKE_RCSID("$NetBSD: var.c,v 1.691 2020/11/21 15:28:44 rillig Exp $"); 133MAKE_RCSID("$NetBSD: var.c,v 1.692 2020/11/21 15:32:52 rillig Exp $");
134 134
135#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1) 135#define VAR_DEBUG1(fmt, arg1) DEBUG1(VAR, fmt, arg1)
136#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2) 136#define VAR_DEBUG2(fmt, arg1, arg2) DEBUG2(VAR, fmt, arg1, arg2)
137#define VAR_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(VAR, fmt, arg1, arg2, arg3) 137#define VAR_DEBUG3(fmt, arg1, arg2, arg3) DEBUG3(VAR, fmt, arg1, arg2, arg3)
138#define VAR_DEBUG4(fmt, arg1, arg2, arg3, arg4) DEBUG4(VAR, fmt, arg1, arg2, arg3, arg4) 138#define VAR_DEBUG4(fmt, arg1, arg2, arg3, arg4) DEBUG4(VAR, fmt, arg1, arg2, arg3, arg4)
139 139
140ENUM_FLAGS_RTTI_3(VarEvalFlags, 140ENUM_FLAGS_RTTI_3(VarEvalFlags,
141 VARE_UNDEFERR, VARE_WANTRES, VARE_KEEP_DOLLAR); 141 VARE_UNDEFERR, VARE_WANTRES, VARE_KEEP_DOLLAR);
142 142
143/* 143/*
144 * This lets us tell if we have replaced the original environ 144 * This lets us tell if we have replaced the original environ
145 * (which we cannot free). 145 * (which we cannot free).
146 */ 146 */
@@ -3915,32 +3915,37 @@ Var_Parse(const char **pp, GNode *ctxt,  @@ -3915,32 +3915,37 @@ Var_Parse(const char **pp, GNode *ctxt,
3915 v, &exprFlags, ctxt, eflags, out_val_freeIt); 3915 v, &exprFlags, ctxt, eflags, out_val_freeIt);
3916 free(extraFree); 3916 free(extraFree);
3917 } else { 3917 } else {
3918 *out_val_freeIt = extraFree; 3918 *out_val_freeIt = extraFree;
3919 } 3919 }
3920 } 3920 }
3921 3921
3922 if (*p != '\0') /* Skip past endc if possible. */ 3922 if (*p != '\0') /* Skip past endc if possible. */
3923 p++; 3923 p++;
3924 3924
3925 *pp = p; 3925 *pp = p;
3926 3926
3927 if (v->flags & VAR_FROM_ENV) { 3927 if (v->flags & VAR_FROM_ENV) {
3928 /* Free the environment variable now since we own it, 3928 /* Free the environment variable now since we own it. */
3929 * but don't free the variable value if it will be returned. */ 3929
3930 Boolean keepValue = value == Buf_GetAll(&v->val, NULL); 3930 char *varValue = Buf_Destroy(&v->val, FALSE);
3931 if (keepValue) 3931 if (value == varValue) {
3932 *out_val_freeIt = value; 3932 /* Don't free the variable value since it will be returned. */
3933 (void)VarFreeEnv(v, !keepValue); 3933 *out_val_freeIt = varValue;
 3934 } else
 3935 free(varValue);
 3936
 3937 free(v->name_freeIt);
 3938 free(v);
3934 3939
3935 } else if (exprFlags & VEF_UNDEF) { 3940 } else if (exprFlags & VEF_UNDEF) {
3936 if (!(exprFlags & VEF_DEF)) { 3941 if (!(exprFlags & VEF_DEF)) {
3937 /* TODO: Use a local variable instead of out_val_freeIt. 3942 /* TODO: Use a local variable instead of out_val_freeIt.
3938 * Variables named out_* must only be written to. */ 3943 * Variables named out_* must only be written to. */
3939 if (*out_val_freeIt != NULL) { 3944 if (*out_val_freeIt != NULL) {
3940 free(*out_val_freeIt); 3945 free(*out_val_freeIt);
3941 *out_val_freeIt = NULL; 3946 *out_val_freeIt = NULL;
3942 } 3947 }
3943 if (dynamic) { 3948 if (dynamic) {
3944 value = bmake_strsedup(start, p); 3949 value = bmake_strsedup(start, p);
3945 *out_val_freeIt = value; 3950 *out_val_freeIt = value;
3946 } else { 3951 } else {