Commit Graph

136 Commits

Author SHA1 Message Date
rillig
59980735fc make(1): remove initial size argument from Hash_InitTable
In all but one case this argument was set to auto-detect anyway.  The
one case where it was set was not worth keeping this complicated API.
2020-09-05 13:55:08 +00:00
rillig
34a9f9ee4a make(1): fix cached_stat for files with st_mtime 0 2020-09-02 04:32:13 +00:00
rillig
13b5ed8e96 make(1): fix aliasing problem in cached_stat from the previous commit
When the struct stat was used for both calling the actual stat and for
returning the result, no copying was needed.  This also had the side
effect that for the first call of cached_stat, the returned struct stat
included all the fields properly filled in, and on later calls, these
fields were all zeroed out.

These two variables are separate now, thus the fields need to be copied
explicitly.  There are no existing unit tests for this, but ./build.sh
failed reliably.
2020-09-02 04:19:52 +00:00
rillig
0c93b3da8f make(1): reduce number of stat fields returned by cached_stat
Only st_mtime and st_mode are actually filled, the remaining fields had
been set to zero.  To prevent these from ever being accessed, a custom
struct make_stat replaces the previously used struct stat.

The fields in struct make_stat are intentionally named different from
the fields in struct stat because NetBSD and some other operating
systems define st_mtime as a macro, and that would not work in a field
declaration.
2020-09-02 04:08:54 +00:00
rillig
e2052aea2d make(1): use proper types in API of cached_stat and cached_lstat 2020-09-02 03:28:12 +00:00
rillig
2626dad6cf make(1): use Hash API from dir.c
When the Hash struct fields are renamed the next time, this should not
influence any code outside hash.h and hash.c.
2020-09-02 03:15:21 +00:00
rillig
5518d2b27c make(1): rename Hash_Table fields
Back in the 1980s it made sense to have the type information encoded in
the variable names.  At the time when make was imported into the NetBSD
tree (1993-03-21), the functions did indeed not have prototypes, they
only had return types.  The void type was already invented at that time.
Since the compiler could not verify the types of function parameters, it
made perfect sense to have each variable tell whether it was a pointer
or not.

Since ISO C90 this is no longer necessary since the compiler checks
this.  The variable names can now focus on the application level and
their high-level meaning, expressing the relationship to other
variables instead of encoding redundant type information.
2020-09-01 21:11:31 +00:00
rillig
93d390f91b make(1): improve variable names and data types in Dir_FindHereOrAbove 2020-09-01 20:17:18 +00:00
rillig
39ed054cac make(1): make data types in Dir_HasWildcards more precise 2020-09-01 17:56:32 +00:00
rillig
f8cb0fda82 make(1): rename GNode.iParents to implicitParents
The i alone was too ambiguous.  It could have meant ignore, implicit,
interactive, and probably many more.
2020-08-30 14:11:42 +00:00
rillig
eb0c83b502 make(1): rename Lst_Datum to LstNode_Datum 2020-08-30 11:15:05 +00:00
rillig
2d4a05ee59 make(1): rename Lst_Memeber to Lst_FindDatum
The new name nicely aligns with Lst_Find and Lst_FindFrom.
2020-08-30 11:12:05 +00:00
rillig
0f5754839c make(1): clean up comments in dir.c 2020-08-29 12:39:32 +00:00
rillig
bb2ba6a0e5 make(1): rename LstNode functions to match their type 2020-08-29 10:41:12 +00:00
rillig
f6a7d0bc31 make(1): rename Lst_FindB back to Lst_Find
The migration from "comparison function" to "match function" is done,
the "B" in the names is no longer needed.
2020-08-29 10:12:06 +00:00
rillig
d1c1d9370a make(1): start replacing Lst_Find with Lst_FindB
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.
2020-08-29 09:30:10 +00:00
rillig
d5d52de25e make(1): clean up Dir_AddDir
Extract the null check for path to the top level.  This has the
side-effect of only incrementing dotLast.refCount if that entry is
actually used.

Reduce the indentation of the code by returning early from the simple
branches.
2020-08-28 04:59:17 +00:00
rillig
942d06c278 make(1): remove trailing 'S' from names of Lst functions
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.
2020-08-28 04:48:56 +00:00
rillig
4acfd85d5e make(1): migrate Lst_Find to Lst_FindS 2020-08-28 04:28:45 +00:00
rillig
acebd2797e make(1): remove unused reference to Lst_Last 2020-08-28 04:16:57 +00:00
rillig
4b307a6103 make(1): migrate Lst_First to Lst_FirstS 2020-08-28 04:14:31 +00:00
rillig
74fd7ff4cd make(1): migrate Lst_IsEmpty to Lst_IsEmptyS 2020-08-27 19:15:35 +00:00
rillig
b855b10134 make(1): migrate Lst_Succ to Lst_SuccS 2020-08-27 07:00:29 +00:00
rillig
6c196ebe9c make(1): migrate Lst_ForEach to Lst_ForEachS
Most lists are always valid.  Only the "targets" variable may be null in
some cases, probably.
2020-08-27 06:53:57 +00:00
rillig
760b7512c6 make(1): migrate remaining code from Lst_Open to Lst_OpenS 2020-08-27 06:28:44 +00:00
rillig
4862a68b32 make(1): add stricter variants for remaining Lst functions
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.
2020-08-26 22:55:46 +00:00
rillig
27d66938d5 make(1): reverse order of the Lst_Find parameters
The other callbacks all have (function, param), only the Lst_Find had
(param, function), which was inconsistent.
2020-08-23 16:58:02 +00:00
rillig
43c60c497e make(1): migrate Lst_AtFront to Lst_PrependS
This makes Lst_AtFront unused, as well as LstInsertBefore.
2020-08-22 23:06:51 +00:00
rillig
e288063ccd make(1): replace Lst_Duplicate with Lst_CopyS
Lst_Duplicate would have passed through any null pointer, which was not
needed for make.  It was the last function that used Lst_AtEnd, which in
turn was the last function that used LstInsertAfter.  As a result, these
two functions have been removed.
2020-08-22 22:57:53 +00:00
rillig
c145566082 make(1): use Lst_OpenS in Dir_SetPATH
Since dirSearchPath is initialized in Dir_Init, opening the list can
never fail.
2020-08-22 19:57:43 +00:00
rillig
885e5a1b8a make(1): fix indentation 2020-08-22 17:34:25 +00:00
rillig
68f9487da7 make(1): extract percentage calculation out of Dir_PrintDirectories 2020-08-22 15:55:22 +00:00
rillig
f724405abb make(1): require argument of Lst_Member to be non-null
Since the lists don't contain null pointers, it doesn't make sense to
search for a null pointer.  All calls but one already had obviously
non-null arguments.  The one remaining call using targ->suff has been
guarded for now.

The code for Lst_Member became much simpler than before.  Partly because
the old code had an extra condition for circular lists, which are not
used by make.
2020-08-22 15:43:32 +00:00
rillig
4ea2d96bef make(1): replace Lst_Datum with non-null guaranteeing Lst_DatumS 2020-08-22 15:17:09 +00:00
rillig
182c9e03db make(1): convert Lst_Enqueue and Lst_Dequeue to nonnull variants
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.
2020-08-22 14:39:12 +00:00
rillig
bbc184419a make(1): remove wrong comment for Dir_Init
Neither the list nor the hash table modules have anything to do with
opening directories.
2020-08-22 14:04:22 +00:00
rillig
e997d2617b make(1): replace "(void)Lst_AtEnd" with stricter "Lst_AppendS"
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.
2020-08-22 11:35:00 +00:00
rillig
a4890d871b make(1): add Lst_Append to add an item at the end of the list
The previous variant of using a special case of Lst_InsertAfter was
unnecessarily complicated.  Linked lists are a very basic data
structure, and there is no need to overcomplicate things by introducing
unnecessary conditions and branches.
2020-08-22 09:40:18 +00:00
rillig
76aca411e7 make(1): remove unused return value for DirMatchFiles 2020-08-22 09:03:53 +00:00
rillig
956e4defda make(1): split Dir_Init into two functions
There's just no point in having a function consisting of a big
if-then-else.
2020-08-22 00:48:02 +00:00
rillig
82a6520aed make(1): use stricter list API for sequential access
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.
2020-08-21 04:42:02 +00:00
rillig
2825a464f9 make(1): assert correct usage of the Lst_Open API
All calls to Lst_Next are properly protected by Lst_Open, so there is no
possible assertion failure here.
2020-08-21 04:09:12 +00:00
rillig
7b0da2fa03 make(1): make list library code stricter
Up to now, the list library didn't distinguish between programming
mistakes (violations of invariants, illegal parameter values) and
actually interesting situations like "element not found in list".

The current code contains many branches for conditions that are neither
exercised by the unit tests nor by real-world usage.  There is no point
in keeping this unnecessary code.

The list functions will be migrated from their lenient variants to the
stricter variants in small parts, each function getting the S suffix
when it is made strict, to avoid any confusion about how strict a
particular function is.  When all functions have been migrated, they
will be renamed back to their original names.

While here, the comments of the functions are cleaned up since they
mention irrelevant implementation details in the API comments, as well
as "side effects" that are really main effects.
2020-08-21 03:36:03 +00:00
rillig
7f136885e3 make(1): remove unused code for circular lists
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.
2020-08-21 02:20:47 +00:00
rillig
d4d42bc70a make(1): clean up debug logging in dir.c
In C90, the variadic macro argument __VA_ARGS__ is not known, therefore
fall back to the forms listing the number of actual printf arguments.
2020-08-13 03:33:56 +00:00
rillig
4ff1f1ac37 make(1): avoid negated conditions in DirExpandCurly 2020-08-13 03:07:49 +00:00
rillig
ef9eb65a77 make(1): clean up DirExpandCurly
Now that nested curly braces work as expected and are covered by unit
tests, the debug log is no longer necessary.
2020-08-13 03:00:44 +00:00
rillig
022d5c4ff0 make(1): use enum instead of #define for cached_stats 2020-08-13 02:53:15 +00:00
rillig
6abaf3bbe5 make(1): make Dir_MakeFlags simpler
This avoids unnecessary string allocations, especially for long lists.

There is no unit test to cover this code.  Since this is an obscure,
undocumented part of make, I wasn't able to come up with a unit test.
Therefore I resorted to write a separate testing program to verify the
expected results.

$ cat <<'EOF' >dir_test.c
#include <stdio.h>

#include "make.h"
#include "dir.h"

int main(int argc, char **argv)
{
    int i;
    Lst lst;
    char *flags;

    lst = Lst_Init(FALSE);
    for (i = 1; i < argc; i++)
    	Dir_AddDir(lst, argv[i]);
    flags = Dir_MakeFlags("-I", lst);

    printf("%s\n", flags);
    free(flags);
    return 0;
}
EOF

# Needs some trivial patches to Makefile and main.c
$ make PROG=dir_test EXTRA_SRCS=dir_test.c EXTRA_CPPFLAGS=-DNO_MAIN \
       COPTS.main.c=-Wno-unused-function NOMAN=1

$ ./dir_test a b c

$ mkdir a b c
$ ./dir_test a b c
 -Ia -Ib -Ic
$ rmdir a b c
2020-08-12 03:05:57 +00:00
rillig
644e5ad76b make(1): replace str_concat with str_concat2 and str_concat3
The new functions have a simpler interface, and str_concat3 is even more
general-purpose, since the middle string is no longer required to be
exactly of length 1.
2020-08-10 19:53:19 +00:00