Lst_Find is called with a "comparison" function that returns the integer
0 if the desired node is found. This leads to confusion since there are
so many different return value conventions for int, such as 0/1 for
mimicking false/true, -1/0 as in close(2), and the sign as in strcmp(3).
This API is much easier to understand if the "comparison" function is
not called a comparison function (since that is too close to strcmp),
but a "match" function that just returns a boolean.
In Lst_FindFromB, the node argument may be null. This deviates from the
other Lst functions, which require Lst and LstNode to generally be
non-null. In this case it is useful though to make the calling code
simpler.
In arch.c, this makes a lot of the previous documentation redundant.
In cond.c, the documentation is reduced a little bit since it had
already been cleaned up before. It also removes the strange negation
from CondFindStrMatch.
In dir.c, the documentation collapses as well.
In main.c, separating the ReadMakefile function from the callbacks for
Lst_FindB allows the former to get back its natural function signature,
with proper types and no unused parameters.
To catch any accidental mistakes during the migration from Lst_Find to
Lst_FindB, the code can be compiled with -DUSE_DOUBLE_BOOLEAN, which
will complain about incompatible function pointer types.
Remove redundant parts of the function comments. Move the "side
effects" to the main section, since these effects are main effects, not
side effects.
Remove the redundant prototype for ArchFree.
The migration from null-passing Lst functions to argument-checking Lst
functions is completed.
There were 2 surprises: The targets list may be NULL, and in Dir_AddDir,
the path may be NULL. The latter case is especially surprising since
that function turns into an almost-nop in that case. This is another
case where probably 2 independent functions have been squeezed into a
single function. This may be improved in a follow-up commit.
All other lists were fine. They were always defined and thus didn't
need much work.
In most cases the Lst functions are only called when the arguments are
indeed valid. It's not guaranteed though, therefore each function call
needs to be analyzed and converted individually.
While here, remove a few statements that were only useful when the Lst
functions handled circular lists.
The code for handling archives is not widely used. Therefore it does
not need to be fast. Clarity of the code is more important. Therefore
replace the malloc + strlen + realloc + snprintf string processing with
the Buffer type, which removes a lot of redundancy.
In the wildcard loop, the "if (sz > nsz)" looked like a mistake. Why
should it be useful to first allocate a large buffer and then resize it
to a smaller buffer, but still twice as large as necessary?
Except for once instance in parse.c, the usage pattern for Lst_Dequeue
was to first test whether the list is empty. This pattern allowed the
implementation of Lst_Dequeue to become simpler since the null check is
not needed anymore.
The calls to Lst_Enqueue never pass an invalid list or a null pointer,
therefore making them strict was trivial.
This change ensures that there is actually something added to the list.
Lst_AtEnd had silently skipped the addition if the list was invalid
(null pointer), which was not intended in these cases. The "(void)" is
assumed to mean "I know that this cannot fail", while it could also mean
"I don't care whether something actually happened".
Running "./build.sh -j6 tools" still succeeds after this change,
therefore chances are very low that this change breaks anything. If
there is any change, it's an obvious assertion failure. There is no
silent change in behavior though.
In several places, it just doesn't make sense to have a null pointer
when a list is expected.
In the existing unit tests, the list passed to Lst_Open is always valid,
but that's not a guarantee for real-world usage. Therefore, Lst_Open
has been left for now, and Lst_OpenS is only the preferred alternative
to it.
The list library had probably been imported from a general-purpose
library that also supported circular lists. These are not used by make
though.
After replacing Lst_Init(FALSE) with Lst_Init(), only a single call to
Lst_Init remained with a non-constant argument, and that was in
Lst_Concat, which was to be expected.
Somewhere in the refactorings of the last month, the parameter types of
the Arch functions had their constness fixed, therefore the UNCONST is
no longer necessary.
NetBSD make is intended to be maximally portable, therefore it uses only
C89. This was not declared in the Makefile before.
There are still a few places in parse.c and metachar.c that use
end-of-line comments. These will be fixed in a follow-up commit.
strncpy is not suited for string processing, despite its name.
Even though the previous code used the correct code pattern for strncpy,
it still wasted cycles since strncpy always fills the whole target
buffer. That's not needed.
The first parameter from Var_Subst had been a literal NULL in all cases.
These have been fixed using this command:
sed -i 's|Var_Subst(NULL, |Var_Subst(|' *.c
The one remaining case was not found because the "NULL," was followed by
a line break instead of a space.
The removed code probably wouldn't have worked as expected anyway.
Expanding a single variable to a literal string would have led to
unexpected behavior for cases like ${VAR:M${pattern}}, in case pattern
would contain an unescaped ':' itself.
The return value of Var_Value must not be modified. Ideally it would be
declared as const char *, but that still takes a while, especially since
much of the make code is not yet covered by the unit tests.
The variable cp had to be changed to const char * as well, and while here
was split up into one variable per actual use case.
This return value is not supposed to be modified since it can be a string
literal. The modifiable part is returned via freePtr, but only for
freeing, not for actually modifying anything.
In var.c there are lots of different flag types. To make any accidental
mixture obvious, each flag group gets its own prefix.
The only flag group that is visible outside of var.c is concerned with
evaluating variables, therefore the "e", which replaces the former "f"
that probably just meant "flag".
The enum corresponding to this int parameter is only defined in var.c,
which makes it impractical for the outside to set this parameter to
anything but 0.
On x86_64, this reduces the size of the resulting executable by 5 kB.
with versions prefixed by MAKE_ATTR_* to avoid modifying the
implementation namespace. Make sure they are available in all places
using nonints.h to fix bootstrap on Linux.
bmake_malloc and friends. Implement them via macros for the native case
and provide fallback implementations otherwise. Avoid polluting the
namespace by not defining enomem globally. Don't bother to provide
strdup and strndup, they were only used for the estrdup and estrndup
comapt code.
This addresses the presence of emalloc in system libraries on A/UX and
resulted strange issues as reported by Timothy E. Larson.