Module Name:    src
Committed By:   rillig
Date:           Fri Feb  5 05:42:39 UTC 2021

Modified Files:
        src/usr.bin/make: make.h var.c

Log Message:
make: improve documentation about variable scopes

In an experiment, I tried to separate the concepts of a GNode and a
variable scope.  The global variables SCOPE_GLOBAL, SCOPE_INTERNAL and
SCOPE_CMDLINE are implemented as GNode even though they only need the
members 'name' and 'vars'.  All their other members are unused.
Therefore it seemed natural to extract this part of the GNode into a
separate type called Scope.

The resulting code was harder to read though since it had split the
namespace of the functions into several parts that were not obviously
related: The Var_ functions, the Scope_ functions, and the short-cut
Global_ functions.  Because of this, I threw away the experiment.

All that is left are a few updated comments.


To generate a diff of this commit:
cvs rdiff -u -r1.254 -r1.255 src/usr.bin/make/make.h
cvs rdiff -u -r1.806 -r1.807 src/usr.bin/make/var.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/make.h
diff -u src/usr.bin/make/make.h:1.254 src/usr.bin/make/make.h:1.255
--- src/usr.bin/make/make.h:1.254	Thu Feb  4 21:50:39 2021
+++ src/usr.bin/make/make.h	Fri Feb  5 05:42:39 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: make.h,v 1.254 2021/02/04 21:50:39 rillig Exp $	*/
+/*	$NetBSD: make.h,v 1.255 2021/02/05 05:42:39 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -500,7 +500,7 @@ extern GNode *defaultNode;
  * by makefiles.
  */
 extern GNode *SCOPE_INTERNAL;
-/* Variables defined in a global scope, e.g in the Makefile itself. */
+/* Variables defined in a global scope, e.g in the makefile itself. */
 extern GNode *SCOPE_GLOBAL;
 /* Variables defined on the command line. */
 extern GNode *SCOPE_CMDLINE;

Index: src/usr.bin/make/var.c
diff -u src/usr.bin/make/var.c:1.806 src/usr.bin/make/var.c:1.807
--- src/usr.bin/make/var.c:1.806	Fri Feb  5 05:19:57 2021
+++ src/usr.bin/make/var.c	Fri Feb  5 05:42:39 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.806 2021/02/05 05:19:57 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.807 2021/02/05 05:42:39 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -139,7 +139,7 @@
 #include "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.806 2021/02/05 05:19:57 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.807 2021/02/05 05:42:39 rillig Exp $");
 
 typedef enum VarFlags {
 	VAR_NONE	= 0,
@@ -289,22 +289,29 @@ static char varUndefined[] = "";
 static Boolean save_dollars = TRUE;
 
 /*
- * Internally, variables are contained in four different scopes.
- *	1) the environment. They cannot be changed. If an environment
- *	   variable is appended to, the result is placed in the global
- *	   scope.
- *	2) the global scope. Variables set in the makefiles are located
- *	   here.
- *	3) the command-line scope. All variables set on the command line
- *	   are placed in this scope.
- *	4) the local scope, containing only the 7 local variables such as
- *	   '.TARGET'.
- * The four scopes are searched in the reverse order from which they are
- * listed (but see opts.checkEnvFirst).
- */
-GNode          *SCOPE_INTERNAL;	/* variables from make itself */
-GNode          *SCOPE_GLOBAL;	/* variables from the makefile */
-GNode          *SCOPE_CMDLINE;	/* variables defined on the command-line */
+ * A scope collects variable names and their values.
+ *
+ * The main scope is SCOPE_GLOBAL, which contains the variables that are set
+ * in the makefiles.  SCOPE_INTERNAL acts as a fallback for SCOPE_GLOBAL and
+ * contains some internal make variables.  These internal variables can thus
+ * be overridden, they can also be restored by undefining the overriding
+ * variable.
+ *
+ * SCOPE_CMDLINE contains variables from the command line arguments.  These
+ * override variables from SCOPE_GLOBAL.
+ *
+ * There is no scope for environment variables, these are generated on-the-fly
+ * whenever they are referenced.  If there were such a scope, each change to
+ * environment variables would have to be reflected in that scope, which may
+ * be simpler or more complex than the current implementation.
+ *
+ * Each target has its own scope, containing the 7 target-local variables
+ * .TARGET, .ALLSRC, etc.  No other variables are in these scopes.
+ */
+
+GNode *SCOPE_CMDLINE;
+GNode *SCOPE_GLOBAL;
+GNode *SCOPE_INTERNAL;
 
 ENUM_FLAGS_RTTI_6(VarFlags,
 		  VAR_IN_USE, VAR_FROM_ENV,
@@ -2379,6 +2386,10 @@ ApplyModifier_Loop(const char **pp, cons
 	    ModifyWords(val, ModifyWord_Loop, &args, st->oneBigWord, st->sep));
 	st->sep = prev_sep;
 	/* XXX: Consider restoring the previous variable instead of deleting. */
+	/*
+	 * XXX: The variable name should not be expanded here, see
+	 * ModifyWord_Loop.
+	 */
 	Var_DeleteExpand(st->scope, args.tvar);
 	free(args.tvar);
 	free(args.str);

Reply via email to