Sun Aug 2 19:59:17 2020 UTC ()
make(1): clean up NULL pointer comparisons, use separate variable

st->newVal is not meant to be a general-purpose storage.

Eliminate the unnecessary initialization of freeIt since Var_Parse
initializes it in every case.


(rillig)
diff -r1.405 -r1.406 src/usr.bin/make/var.c

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

--- src/usr.bin/make/var.c 2020/08/02 19:49:17 1.405
+++ src/usr.bin/make/var.c 2020/08/02 19:59:17 1.406
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: var.c,v 1.405 2020/08/02 19:49:17 rillig Exp $ */ 1/* $NetBSD: var.c,v 1.406 2020/08/02 19:59:17 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.
@@ -59,34 +59,34 @@ @@ -59,34 +59,34 @@
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE. 68 * SUCH DAMAGE.
69 */ 69 */
70 70
71#ifndef MAKE_NATIVE 71#ifndef MAKE_NATIVE
72static char rcsid[] = "$NetBSD: var.c,v 1.405 2020/08/02 19:49:17 rillig Exp $"; 72static char rcsid[] = "$NetBSD: var.c,v 1.406 2020/08/02 19:59:17 rillig Exp $";
73#else 73#else
74#include <sys/cdefs.h> 74#include <sys/cdefs.h>
75#ifndef lint 75#ifndef lint
76#if 0 76#if 0
77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
78#else 78#else
79__RCSID("$NetBSD: var.c,v 1.405 2020/08/02 19:49:17 rillig Exp $"); 79__RCSID("$NetBSD: var.c,v 1.406 2020/08/02 19:59:17 rillig Exp $");
80#endif 80#endif
81#endif /* not lint */ 81#endif /* not lint */
82#endif 82#endif
83 83
84/*- 84/*-
85 * var.c -- 85 * var.c --
86 * Variable-handling functions 86 * Variable-handling functions
87 * 87 *
88 * Interface: 88 * Interface:
89 * Var_Set Set the value of a variable in the given 89 * Var_Set Set the value of a variable in the given
90 * context. The variable is created if it doesn't 90 * context. The variable is created if it doesn't
91 * yet exist. 91 * yet exist.
92 * 92 *
@@ -2051,53 +2051,53 @@ ApplyModifier_Hash(const char *mod, Appl @@ -2051,53 +2051,53 @@ ApplyModifier_Hash(const char *mod, Appl
2051static ApplyModifierResult 2051static ApplyModifierResult
2052ApplyModifier_Path(const char *mod, ApplyModifiersState *st) 2052ApplyModifier_Path(const char *mod, ApplyModifiersState *st)
2053{ 2053{
2054 if (st->v->flags & VAR_JUNK) 2054 if (st->v->flags & VAR_JUNK)
2055 st->v->flags |= VAR_KEEP; 2055 st->v->flags |= VAR_KEEP;
2056 GNode *gn = Targ_FindNode(st->v->name, TARG_NOCREATE); 2056 GNode *gn = Targ_FindNode(st->v->name, TARG_NOCREATE);
2057 if (gn == NULL || gn->type & OP_NOPATH) { 2057 if (gn == NULL || gn->type & OP_NOPATH) {
2058 st->newVal = NULL; 2058 st->newVal = NULL;
2059 } else if (gn->path) { 2059 } else if (gn->path) {
2060 st->newVal = bmake_strdup(gn->path); 2060 st->newVal = bmake_strdup(gn->path);
2061 } else { 2061 } else {
2062 st->newVal = Dir_FindFile(st->v->name, Suff_FindPath(gn)); 2062 st->newVal = Dir_FindFile(st->v->name, Suff_FindPath(gn));
2063 } 2063 }
2064 if (!st->newVal) 2064 if (st->newVal == NULL)
2065 st->newVal = bmake_strdup(st->v->name); 2065 st->newVal = bmake_strdup(st->v->name);
2066 st->next = mod + 1; 2066 st->next = mod + 1;
2067 return AMR_OK; 2067 return AMR_OK;
2068} 2068}
2069 2069
2070/* :!cmd! */ 2070/* :!cmd! */
2071static ApplyModifierResult 2071static ApplyModifierResult
2072ApplyModifier_Exclam(const char *mod, ApplyModifiersState *st) 2072ApplyModifier_Exclam(const char *mod, ApplyModifiersState *st)
2073{ 2073{
2074 st->next = mod + 1; 2074 st->next = mod + 1;
2075 char delim = '!'; 2075 char delim = '!';
2076 char *cmd = ParseModifierPart(&st->next, delim, st->eflags, st->ctxt, 2076 char *cmd = ParseModifierPart(&st->next, delim, st->eflags, st->ctxt,
2077 NULL, NULL, NULL); 2077 NULL, NULL, NULL);
2078 if (cmd == NULL) { 2078 if (cmd == NULL) {
2079 st->missing_delim = delim; 2079 st->missing_delim = delim;
2080 return AMR_CLEANUP; 2080 return AMR_CLEANUP;
2081 } 2081 }
2082 2082
2083 const char *emsg = NULL; 2083 const char *emsg = NULL;
2084 if (st->eflags & VARE_WANTRES) 2084 if (st->eflags & VARE_WANTRES)
2085 st->newVal = Cmd_Exec(cmd, &emsg); 2085 st->newVal = Cmd_Exec(cmd, &emsg);
2086 else 2086 else
2087 st->newVal = varNoError; 2087 st->newVal = varNoError;
2088 free(cmd); 2088 free(cmd);
2089 2089
2090 if (emsg) 2090 if (emsg != NULL)
2091 Error(emsg, st->val); /* XXX: why still return AMR_OK? */ 2091 Error(emsg, st->val); /* XXX: why still return AMR_OK? */
2092 2092
2093 if (st->v->flags & VAR_JUNK) 2093 if (st->v->flags & VAR_JUNK)
2094 st->v->flags |= VAR_KEEP; 2094 st->v->flags |= VAR_KEEP;
2095 return AMR_OK; 2095 return AMR_OK;
2096} 2096}
2097 2097
2098/* The :range modifier generates an integer sequence as long as the words. 2098/* The :range modifier generates an integer sequence as long as the words.
2099 * The :range=7 modifier generates an integer sequence from 1 to 7. */ 2099 * The :range=7 modifier generates an integer sequence from 1 to 7. */
2100static ApplyModifierResult 2100static ApplyModifierResult
2101ApplyModifier_Range(const char *mod, ApplyModifiersState *st) 2101ApplyModifier_Range(const char *mod, ApplyModifiersState *st)
2102{ 2102{
2103 if (!ModMatchEq(mod, "range", st->endc)) 2103 if (!ModMatchEq(mod, "range", st->endc))
@@ -2739,32 +2739,32 @@ ApplyModifier_Assign(const char *mod, Ap @@ -2739,32 +2739,32 @@ ApplyModifier_Assign(const char *mod, Ap
2739 st->missing_delim = delim; 2739 st->missing_delim = delim;
2740 return AMR_CLEANUP; 2740 return AMR_CLEANUP;
2741 } 2741 }
2742 2742
2743 st->next--; 2743 st->next--;
2744 2744
2745 if (st->eflags & VARE_WANTRES) { 2745 if (st->eflags & VARE_WANTRES) {
2746 switch (op[0]) { 2746 switch (op[0]) {
2747 case '+': 2747 case '+':
2748 Var_Append(st->v->name, val, v_ctxt); 2748 Var_Append(st->v->name, val, v_ctxt);
2749 break; 2749 break;
2750 case '!': { 2750 case '!': {
2751 const char *emsg; 2751 const char *emsg;
2752 st->newVal = Cmd_Exec(val, &emsg); 2752 char *cmd_output = Cmd_Exec(val, &emsg);
2753 if (emsg) 2753 if (emsg)
2754 Error(emsg, st->val); 2754 Error(emsg, st->val);
2755 else 2755 else
2756 Var_Set(st->v->name, st->newVal, v_ctxt); 2756 Var_Set(st->v->name, cmd_output, v_ctxt);
2757 free(st->newVal); 2757 free(cmd_output);
2758 break; 2758 break;
2759 } 2759 }
2760 case '?': 2760 case '?':
2761 if (!(st->v->flags & VAR_JUNK)) 2761 if (!(st->v->flags & VAR_JUNK))
2762 break; 2762 break;
2763 /* FALLTHROUGH */ 2763 /* FALLTHROUGH */
2764 default: 2764 default:
2765 Var_Set(st->v->name, val, v_ctxt); 2765 Var_Set(st->v->name, val, v_ctxt);
2766 break; 2766 break;
2767 } 2767 }
2768 } 2768 }
2769 free(val); 2769 free(val);
2770 st->newVal = varNoError; 2770 st->newVal = varNoError;
@@ -3582,27 +3582,27 @@ Var_Subst(const char *str, GNode *ctxt,  @@ -3582,27 +3582,27 @@ Var_Subst(const char *str, GNode *ctxt,
3582 str += 2; 3582 str += 2;
3583 } else if (*str != '$') { 3583 } else if (*str != '$') {
3584 /* 3584 /*
3585 * Skip as many characters as possible -- either to the end of 3585 * Skip as many characters as possible -- either to the end of
3586 * the string or to the next dollar sign (variable invocation). 3586 * the string or to the next dollar sign (variable invocation).
3587 */ 3587 */
3588 const char *cp; 3588 const char *cp;
3589 3589
3590 for (cp = str++; *str != '$' && *str != '\0'; str++) 3590 for (cp = str++; *str != '$' && *str != '\0'; str++)
3591 continue; 3591 continue;
3592 Buf_AddBytesBetween(&buf, cp, str); 3592 Buf_AddBytesBetween(&buf, cp, str);
3593 } else { 3593 } else {
3594 int length; 3594 int length;
3595 void *freeIt = NULL; 3595 void *freeIt;
3596 const char *val = Var_Parse(str, ctxt, eflags, &length, &freeIt); 3596 const char *val = Var_Parse(str, ctxt, eflags, &length, &freeIt);
3597 3597
3598 /* 3598 /*
3599 * When we come down here, val should either point to the 3599 * When we come down here, val should either point to the
3600 * value of this variable, suitably modified, or be NULL. 3600 * value of this variable, suitably modified, or be NULL.
3601 * Length should be the total length of the potential 3601 * Length should be the total length of the potential
3602 * variable invocation (from $ to end character...) 3602 * variable invocation (from $ to end character...)
3603 */ 3603 */
3604 if (val == var_Error || val == varNoError) { 3604 if (val == var_Error || val == varNoError) {
3605 /* 3605 /*
3606 * If performing old-time variable substitution, skip over 3606 * If performing old-time variable substitution, skip over
3607 * the variable and continue with the substitution. Otherwise, 3607 * the variable and continue with the substitution. Otherwise,
3608 * store the dollar sign and advance str so we continue with 3608 * store the dollar sign and advance str so we continue with