Commit Graph

252 Commits

Author SHA1 Message Date
rillig
536f0554b2 make(1): document inefficient cache lookup in DirMatchFiles 2020-11-08 11:57:49 +00:00
rillig
04f1ad0734 make(1): change return type of Dir_MTime to void
Only some callers actually needed the updated time, and because of the
many branches, it was difficult to see that the return value was indeed
gn->mtime all the time.
2020-11-08 09:34:55 +00:00
rillig
4b8c84d3fa make(1): change return type of Arch_MTime to void
This makes it easier to prove that Dir_MTime always returns gn->mtime,
without looking at the implementation of Arch_UpdateMTime.
2020-11-08 09:15:19 +00:00
rillig
76d1f7676d make(1): change return type of Arch_MemberMTime to void
This makes it easier to prove that Dir_MTime always returns gn->mtime,
without looking at the implementation of Arch_UpdateMemberMTime.
2020-11-08 09:06:22 +00:00
rillig
82e2acd33b make(1): use proper enum constant instead of 0 for CachedStatsFlags 2020-11-07 20:45:21 +00:00
rillig
84d259f4c7 make(1): make API of Buf_Init simpler
In most cases, the caller doesn't want to specify the exact number of
preallocated bytes.
2020-11-07 14:11:58 +00:00
rillig
a0c9252554 make(1): clean up code stylistically
* Replace character literal 0 with '\0'.
* Replace pointer literal 0 with NULL.
* Remove redundant parentheses.
* Parentheses in multi-line conditions are not redundant at the
  beginning of a line.
* Replace a few !ptr with ptr == NULL.
* Replace a few ptr with ptr != NULL.
* Replace (expr & mask) == 0 with !(expr & mask).
* Remove redundant braces for blocks in cases where the generated code
  stays the same.  (Assertions further down in the code would get
  different line numbers.)
* Rename parameters in CondParser_String to reflect the data flow.
* Replace #ifdef notdef with #if 0.

The generated code stays exactly the same, at least with GCC 5.5.0 on
NetBSD 8.0 amd64 using the default configuration.
2020-11-07 10:16:18 +00:00
rillig
94119fc036 make(1): rename Arch_MemMTime to Arch_MemberMTime
The abbreviation Mem was ambiguous, it could have meant memory as well.
2020-11-06 23:59:21 +00:00
rillig
143a32671d make(1): remove redundant parentheses from sizeof operator
The parentheses are only needed if the argument is a type, not an
expression.
2020-11-05 17:27:16 +00:00
rillig
090539ffb6 make(1): remove dead code for filename expansion using curly braces
Any string containing curly braces is already handled in the very first
if statement.
2020-10-31 17:39:20 +00:00
rillig
09c6b7ecfa make(1): fix indentation in source code 2020-10-30 15:39:17 +00:00
rillig
98387f227e make(1): rewrap and reword the large comment for directory caching
Hashing the directories is not a problem at all, it's the caching that
makes things complicated.
2020-10-27 06:55:18 +00:00
rillig
fedd370f09 make(1): remove "Results: none" from the documentation of void functions 2020-10-26 23:28:52 +00:00
rillig
bc562b20b4 make(1): add GNode_Path to access the path of a GNode 2020-10-25 21:51:48 +00:00
rillig
74df83559b make(1): rename hash functions to identify the type name
This makes it easier to spot mismatches between the function name and
its first parameter, although the compiler should already catch most of
them.  Except for void pointers.
2020-10-25 19:19:07 +00:00
rillig
a1846b64fb make(1): replace Dir_CopyDir with Dir_CopyDirSearchPath
Callback functions for the Lst functions do not belong in the public API
of a module.
2020-10-25 10:00:20 +00:00
rillig
09fa974936 make(1): clean up Dir_HasWildcards 2020-10-25 09:51:52 +00:00
rillig
c7f3973ba9 make(1): clean up DirLookupSubdir and DirLookupAbs
As with cp2, the variable names p1 and p2 are not expressive.
2020-10-25 09:30:45 +00:00
rillig
a76c6d4cc8 make(1): omit trailing space in debug output for expanding file patterns 2020-10-25 09:19:10 +00:00
rillig
0d39d4e042 make(1): clean up documentation of DirExpandInt, rename it
The code in that function is so trivial that there is no point in
writing this much redundant documentation.
2020-10-25 09:10:46 +00:00
rillig
bc35674c4f make(1): document pattern matching edge case in DirMatchFiles 2020-10-25 09:03:05 +00:00
rillig
b2f9b20ec2 make(1): refactor DirMatchFiles
Split the conditions since the comment only applies to one of them.
Use local variables for common subexpressions.
2020-10-25 08:59:26 +00:00
rillig
ed3ade7515 make(1): clean up documentation of DirExpandCurly and Dir_Expand 2020-10-25 08:10:03 +00:00
rillig
981bdba9a6 make(1): document that the SearchPath of Dir_FindFile may be NULL 2020-10-25 07:59:09 +00:00
rillig
6e07ffdb96 make(1): remove unused parameter from DirFindDot 2020-10-25 07:46:05 +00:00
rillig
b3f2652101 make(1): rename parameter of DirLookup
The DirLookup functions work on "name", which may be a complete path,
and on "base" or "cp", which is the basename of the file.  Don't use
"name" for the basename, since that would be confusing.
2020-10-25 07:44:16 +00:00
rillig
b4d430b61d make(1): remove unused parameters from DirLookup 2020-10-25 07:32:07 +00:00
rillig
826ef3ac6a make(1): only define OpenDirs_Done if necessary 2020-10-25 07:27:06 +00:00
rillig
3175bbc35a make(1): remove UNCONST from Dir_Expand
That code is called so seldom that one more memory allocation doesn't
hurt.  It needs a wildcard character in a dependency declaration, which
is rare in practice; see dep-wildcards.mk for an example.
2020-10-24 23:27:33 +00:00
rillig
417d95c57a make(1): inline DirFindName 2020-10-24 09:18:09 +00:00
rillig
60b23912e3 make(1): remove redundant type casts
This mainly affects the void pointers in callback functions for lists.
These had been necessary once when the parameter type was still
ClientData instead of void pointer.
2020-10-22 05:50:02 +00:00
rillig
859199ba81 make(1): inline simple Lst getters
The function call variant takes more screen space than the direct field
access.  Having an abstract API is usually a good idea, in this case of
simple read-only member access it makes the code more difficult to read.

LstNode_Set has been kept as a function since it is not a read-only
accessor function.
2020-10-19 21:57:37 +00:00
rillig
2e62f9c853 make(1): add tags to enum types
This allows IDEs to offer better type information than "anonymous enum".
2020-10-18 17:19:54 +00:00
rillig
e769b7497f make(1): replace Lst_Open with simple iteration in Dir_SetPATH 2020-10-18 14:36:09 +00:00
rillig
56ae3bf01a make(1): replace Lst_Open with simple iteration in Dir_FindFile 2020-10-18 14:32:04 +00:00
rillig
92688ee547 make(1): rename Lst_Init to Lst_New
For the other types such as HashTable and Buffer, the Init function does
not allocate the memory for the structure itself, it only fills it.
2020-10-18 13:02:10 +00:00
rillig
fb73d14d90 make(1): rename HashEntry.name to key 2020-10-18 12:47:43 +00:00
rillig
5a07777488 make(1): remove underscore from Hash_Table and Hash_Entry
For consistency with the other type names, such as GNodeListNode.
2020-10-18 12:36:43 +00:00
rillig
363a9449ba make(1): make API for iterating over hash tables simpler 2020-10-18 10:44:25 +00:00
rillig
ac2722ebb3 make(1): normalize initialization and cleanup of the modules 2020-10-17 21:32:30 +00:00
rillig
b6ce0a8a76 make(1): fix indentation 2020-10-17 17:47:14 +00:00
rillig
1b9c32a3c0 make(1): remove pathname limit for Dir_FindHereOrAbove
While trying to compile the code with GCC's -Wformat-truncation, the
snprintf calls felt quite complicated.  The function Dir_FindHereOrAbove
is not in a bottleneck execution path, therefore it doesn't hurt to
dynamically allocate the memory instead of using size-limited stack
memory.
2020-10-05 22:45:47 +00:00
rillig
a7157845f7 make(1): make dir.c, for.c and hash.c ready for WARNS=6
Some types have changed from int to unsigned int, size_t or time_t.

The variable i in hash.c has been kept as int since it counts down to
-1, which generates efficient machine code, at least on x86_64.
2020-10-05 20:21:30 +00:00
rillig
c85833020f make(1): fix double-free bug in -DCLEANUP mode (since 2020-10-02)
The bug had been introduced with dir.c 1.155 on 2020-10-02 22:20:25.  In
that commit, openDirectories was replaced with a combination of a list
with a hash table, for more efficient lookup by name.

Upon cleanup, OpenDirs_Done is called, which in turn called
Dir_ClearPath.  Dir_ClearPath takes full ownership of the given list and
empties it.  This was no problem before since afterwards the list was
empty and calling Lst_Free just frees the remaining list pointer.

With OpenDirs, this list was combined with a hash table, and the hash
table contains the list nodes, assuming that the OpenDirs functions have
full ownership of both the list and the hash table.  This assumption was
generally correct, except for the one moment during cleanup where full
ownership of the list was passed to Dir_ClearPath, while the hash table
still contained pointers to the (now freed) list nodes.  This by itself
was not a problem since the hash table would be freed afterwards.  But
as part of Dir_ClearPath, OpenDirs_Remove was called, which looked up
the freed directory by name and now found the freed list node, trying to
free it again.  Boom.

Fixed by replacing the call to Dir_ClearPath with code that only frees
the directories, without giving up control over the list.
2020-10-05 19:30:37 +00:00
rillig
f336e55bc4 make(1): revert previous commit
It had accidentally reverted all the work from the past few days.
2020-10-05 19:27:47 +00:00
rillig
b6c0384ff9 make(1): fix double-free bug in -DCLEANUP mode (since 2020-10-02)
The bug had been introduced with dir.c 1.155 on 2020-10-02 22:20:25.  In
that commit, openDirectories was replaced with a combination of a list
with a hash table, for more efficient lookup by name.

Upon cleanup, OpenDirs_Done is called, which in turn called
Dir_ClearPath.  Dir_ClearPath takes full ownership of the given list and
empties it.  This was no problem before since afterwards the list was
empty and calling Lst_Free just frees the remaining list pointer.

With OpenDirs, this list was combined with a hash table, and the hash
table contains the list nodes, assuming that the OpenDirs functions have
full ownership of both the list and the hash table.  This assumption was
generally correct, except for the one moment during cleanup where full
ownership of the list was passed to Dir_ClearPath, while the hash table
still contained pointers to the (now freed) list nodes.  This by itself
was not a problem since the hash table would be freed afterwards.  But
as part of Dir_ClearPath, OpenDirs_Remove was called, which looked up
the freed directory by name and now found the freed list node, trying to
free it again.  Boom.

Fixed by replacing the call to Dir_ClearPath with code that only frees
the directories, without giving up control over the list.
2020-10-05 19:24:29 +00:00
rillig
052e64b5e1 make(1): clean up #include sections 2020-10-03 21:52:50 +00:00
rillig
a2ba7e7ed3 make(1): use hash table for looking up open directories by name
As long as there are less than 20 open directories, it's perfectly fine
to use a doubly-linked list for name lookup.  A singly linked list or
even an array list would have been better, but anyway.

When the number of directories rises above 1000, which happens with
dirdeps.mk, linear list lookup becomes too expensive, especially since
each list entry is compared using a strcmp call, in a callback function
that is not inlined.

Using a hash table is much more efficient than linear lookup.  While
here, abstract all operations regarding the openDirectories list into a
new data type that provides a simple and straight-forward API.  This
strongly typed API is especially important since the current
implementation of the list and hash table is weakly typed, using void *
for the actual data, and StringList and CachedDirList refer to the
exactly same type, they just have different names to help the human
readers but don't provide any type safety.
2020-10-02 22:20:25 +00:00
rillig
ef0b5be0ac make(1): remove redundant function prototypes 2020-10-01 22:42:00 +00:00
rillig
35a8c8e3ca make(1): replace += 1 with ++ and -= 1 with --
Just for visual consistency.  The generated code stays exactly the same.
2020-09-28 23:13:57 +00:00
rillig
37111947f1 make(1): make debug logging simpler
This avoids referring to the debug_file variable in many places where
this implementation detail is not necessary.
2020-09-28 22:23:35 +00:00
rillig
ae6e2b2c4b make(1): make debugging code shorter 2020-09-28 20:46:11 +00:00
rillig
74e0563954 make(1): improve documentation of CachedDir and Dir_AddDir 2020-09-27 22:17:07 +00:00
rillig
c4def5ee7a make(1): normalize whitespace in source code
There is no more space tab.  Either only tabs or only spaces or tabs
followed by spaces, but not spaces followed by tabs.
2020-09-27 21:35:16 +00:00
rillig
073f669ad5 make(1): inline and remove LstNode_Prev and LstNode_Next
These functions made the code larger than necessary.  The prev and next
fields are published intentionally since navigating in a doubly-linked
list is simple to do and there is no need to wrap this in a layer of
function calls, not even syntactically.  (On the execution level, the
function calls had been inlined anyway.)
2020-09-26 17:15:20 +00:00
rillig
921a8f8fce make(1): replace a few calls to Lst_Open with simple loops
This avoids relying on the internal iterator of the list, which is
supposed to be removed in the near future.
2020-09-25 06:49:13 +00:00
rillig
c51b6afb9a make(1): inline Lst_ForEach for debugging output in search paths 2020-09-24 07:49:58 +00:00
rillig
4ec7405c5c make(1): rename Lst_ForEach to Lst_ForEachUntil
Since the callback function returns a terminating condition, this is not
really a foreach loop.

Many of the calls to Lst_ForEachUntil don't make use of the terminating
condition, and several don't modify the list structurally, which means
they don't need this complicated implementation.

In a follow-up commit, Lst_ForEach will be added back with a much
simpler implementation that iterates over the list naively, without a
terminating condition and without taking the iteration state from
Lst_Open/Lst_Next/Lst_Close into account.  The migration to this simpler
implementation will be done step by step since each callback function
needs to be examined closely.
2020-09-24 07:11:29 +00:00
rillig
a2ec3df107 make(1): use fine-grained type names for lists and their nodes
This is only intended to help the human reader.  There is no additional
type safety yet.
2020-09-22 04:05:41 +00:00
rillig
222b541caf make(1): rename type Path to CachedDir
The word "path" is commonly used either as an abbreviation for pathname
(a string consisting of several directory or file names) or as an
abbreviation for search path (a list of directory names used for
searching files), but not for a single directory.
2020-09-22 02:26:22 +00:00
rillig
6de75a95f8 make(1): clean up RCSID blocks
These blocks mostly consisted of redundant structure, following the same
#ifndef pattern over and over, with only minimal variation.

It's easier to maintain if the common structure is only written once and
encapsulated in a macro.

To avoid "defined but unused" warnings from GCC in the case where
MAKE_NATIVE is not defined, I had to add volatile.  Adding
MAKE_ATTR_UNUSED alone would not preserve the rcsid variable in the
resulting binary.
2020-09-13 15:15:51 +00:00
rillig
cfc1011dce make(1): fix assertion failure in Dir_Destroy in -DCLEANUP mode
When the openDirectories path list is cleaned up, each path from it is
first dequeued and then freed via Dir_Destroy.  At this point, the path
is no longer in openDirectories, which triggered an assertion in
Lst_Remove, called by Dir_Destroy.
2020-09-12 23:12:44 +00:00
rillig
5d597631bc make(1): fix indentation in dir.c 2020-09-12 12:24:21 +00:00
rillig
fb925e321c make(1): rename local variable in Dir_FindFile
The name "cp" is not appropriate for a variable containing the basename
of a path.
2020-09-12 12:15:22 +00:00
rillig
fc3e32ef07 make(1): replace *a->b with a->b[0]
This allows the code to be read strictly from left to right.  In most
places this style was already used.
2020-09-11 04:32:39 +00:00
rillig
3bb127c1bf make(1): document that nested braces work as expected now 2020-09-07 19:48:08 +00:00
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