Initialization and destruction of the fields is independent from the
other fields. Therefore use declaration order, which allows to quickly
see whether a field was forgotten.
While here, add comments that in cleanup mode, not all memory is freed.
The variables of a node and the suffix survive right now.
In CLEANUP mode, Var_Init depends on Targ_Init since the variable scopes
are implemented as GNodes.
By the way, since 1999-09-15 variables are no longer stored in lists but
in hash tables.
This function is a classical constructor function, and if it weren't for
CLEANUP mode, it would have no dependencies on anything else besides the
memory allocator. Therefore it doesn't really matter which module
defines this function, and there is no need for the "Targ" to be part of
the function name.
Fix some mistakes in comments.
Improve some comments to be easier understandable.
Inline variables that are irrelevant for the test at hand (RUN,
MAKE_CMD).
Remove references to functions and constants that have since been removed
or renamed.
The main changes are in the comments, which have been shortened and
corrected.
Some local variables changed their names.
In ParseErrorInternal, the scope of va_start is now narrower.
In ParseDoDependency, the type of tOp has been fixed.
ParseGetLine doesn't take flags anymore but instead a parsing mode.
Previously, the flags had not been combined anyway.
At the beginning of Parse_File, fatals is already guaranteed to be 0, and
even if not, it would be wrong to just discard the fatal errors.
When running the tests with specifying absolute filenames, it doesn't
make sense to prefix the MAKEFILE with "./", which made the tests fail on
FreeBSD.
An unintended side effect from the GNode implementation was that the
variable modifier :tA and the other places where cached_realpath are
used could be affected by setting a variable in the global scope,
thereby "redirecting" absolute paths to completely unrelated but
existing paths.
Another unintended side effect was that filenames containing a dollar
sign would not be resolved correctly since the dollar sign would be
expanded as a variable expression by Var_Set.
While here, the debugging output for the realpath cache has been
adjusted to the standard behavior. Previously, when a new entry was
added to the cache, this was logged for the module VAR, as a side effect
of calling Var_Set, but only if the preprocessor macro
DEBUG_REALPATH_CACHE was defined at compilation time. When relative
paths were purged from the cache because the current directory changed
and logging for the DIR module was active, the log output went directly
to stderr instead of the usual opts.debug_file. This deviation from the
standard behavior was probably not intended as well.
All logging concerning the realpath cache now goes into the standard
debug log file and is controlled by the -dd option, not -dv.
Instead of HashTable_CreateEntry and HashEntry_Set, several places just
need the HashEntry for storing a value in it. This makes the calling
code simpler to understand.
These parts of the code are already hard enough to understand since they
are about memory management and aliasing. Having a too detailed API for
the HashTable only distracts from these topics.
In the cache for stat(2) and lstat(2), only one of the two timestamps
was ever used. To prevent a result from stat(2) leaking into the cache
for lstat(2), there have been two completely separate caches all the
time. Using different fields in the struct was therefore unnecessary.
By removing the redundant field, the internal struct in the cache is the
same as the external struct. This makes one of them redundant, thus
struct make_stat has been renamed to cached_stat, which better describes
its purpose, and the internal struct cache_st has been removed.
Just as before, the cache prevents any direct access to its internal
data. When passing it to the caller, it is copied.
Just as before, the field names of struct cached_stat cannot correspond
to those from struct stat, since the latter are often defined as macros.
Therefore they are prefixed with cst instead of st.
The redundancy had been added on 2020-06-05.
This only affects the warning that chdir to objdir failed. In sub-makes
the progname includes the [n], allowing to narrow down the actual cause
of the problem.
The * is preferred for iterators. Since argv[i] is not an iterator but
a fixed string, argv[i][0] expresses the idea "read the first character"
more directly.
Error messages belong on stderr, not stdout. Since at least 1993,
stdout had been used for no good reason. Plus, in all these years,
nobody ever tested this code path since otherwise the missing newline at
the end of the error message would have been obvious.
This is a good candidate for the "oldest bug in make" trophy.
This macro had been bad in several ways. Its name started with DB, an
unnecessary abbreviation for DEBUG. Many places that used this macro
used it with the same format string, "%s\n". This format string can
better be expressed in a function name, JobPrintln.
Only in a few places was the macro used with different format strings.
The one for "set -x" was even forced to arbitrarily separate the
argument from the format string in order to match the expected macro
parameters.
A better choice would have been to use the standard form "%s\n", "set
-x" from the beginning. Anyway, that call is calling JobPrintln as well
now.
The remaining templates are user-specified, and if anyone should ever
define a completely custom shell with echo handling and error handling
enabled, they will easily crash make when the templates don't contain
exactly one %s conversion. That's the responsibility of the user, and
it has always been.
Previously, the individual IfStates contained redundant information,
which was apparent in the documentation. This led to expressions like
(state > ELSE_ACTIVE) that are hard to read since the reader has to look
up the order of the enum.
To avoid this, the state of an '.if' block is now encoded using a bitset,
encoding the properties of each state directly. This replaces the
previous (state > ELSE_ACTIVE) with !(state & IFS_ACTIVE), which is
easier to understand.
No change in behavior.
For curdir and an explicit .OBJDIR target, we allow for
the directory to be read-only.
During InitObjdir we otherwise default to requiring objdir to be
writable - this can be controlled by env variable
MAKE_OBJDIR_CHECK_WRITABLE
Add unit-tests/objdir-writable
Reviewed by: christos rillig