Commit Graph

557 Commits

Author SHA1 Message Date
rillig
7d5e8f8e1b make: convert VarEvalFlags back into an enum, but not a bit-set
As was apparent in VarEvalFlags_ToString, a bit-set was not the best
data type since most of the flags were not freely combinable.  The two
flags that could be combined were keepDollar and keepUndef, but even
these have distinguished names in the debug log.

The downside of struct bit-fields is that they need extra helper
functions in C90 (see nonints.h).  Exchange these for a few helper
functions in var.c, to keep the code outside var.c simple.

No functional change.
2021-04-04 11:56:43 +00:00
rillig
1d7f9c44eb make: remove filler word 'Do' from function names for parsing
No functional change, except for debug logging.
2021-04-04 10:13:09 +00:00
rillig
4967e3ac3b make: rename ambiguous functions
These two functions have counterparts that include the word 'Do' in
their name, which is confusing.

No functional change.
2021-04-04 09:58:51 +00:00
rillig
1e65de9557 make: rename function parameters to match boolean constants
No functional change.
2021-04-03 14:31:44 +00:00
rillig
244fd9f4c4 make: use C99 bool type instead of defining its own
No functional change.
2021-04-03 11:08:40 +00:00
rillig
2f8026b0e5 make: replace enum bit-field with struct bit-field for VarEvalFlags
This makes the code easier to read, especially in var.c.  It also makes
debugging sessions easier since some debuggers don't show enum
bit-fields symbolically as soon as more than one bit is set.

The code outside var.c is basically unchanged, except that instead of
passing the individual flags, there are 4 predefined evaluation modes.
These suffice for all practical use cases.  Only in the implementation
deep inside var.c, the value of the flags keepDollar and keepUndef
differs.

There is no way of passing the struct to EnumFlags_ToString, which means
the ToString function has to be spelled out explicitly.  This allows for
fine-tuning the representation in the debug log, to reduce the amount of
uppercae letters.

No functional change.
2021-03-15 12:15:03 +00:00
rillig
4fd3cf6eed make: rename VARE_NONE to VARE_PARSE_ONLY
The name 'NONE' described the bit pattern, which was not useful to
understand its meaning.  Omitting VARE_WANTRES only parses the
expression, without evaluating any part of it.

No functional change, not even in debug mode since Enum_FlagsToString
always returns "none" for all-bits-unset.
2021-03-15 11:41:07 +00:00
rillig
49c1680d06 make: remove freestanding freeIt variables
These variables all belong to a string variable.  Connect them using
FStr, which reduces the number of variables to keep track of.

No functional change.
2021-02-22 23:21:33 +00:00
rillig
d6f20baa76 make: clean up a few comments in parse.c 2021-02-05 05:46:27 +00:00
rillig
835b4db442 make: in the Var_ functions, move the scope to the front
This change provides for a more natural reading order in the code.
Placing the scope first makes it immediately clear in which context the
remaining parameters are interpreted.

No functional change.
2021-02-05 05:15:12 +00:00
rillig
715bef6038 make: add shortcut Global_Delete for deleting a global variable 2021-02-05 04:41:17 +00:00
rillig
4dc2cd5c6f make: rename context and ctxt to scope
This continues the previous commit, in which VAR_GLOBAL, VAR_INTERNAL
and VAR_CMDLINE were renamed.

Renaming the variable 'ctxt' was trivial since that word is used nowhere
else.  In the comments though, each occurrence of the word 'context' had
to be checked individually since the word 'context' was not only used
for referring to a variable scope.  It is also used to distinguish
different situations where characters are escaped in a certain way
('parsing context') and in a few other expressions.
2021-02-04 21:42:46 +00:00
rillig
5980c2c341 make: rename some VAR constants to SCOPE
The word "context" does not fit perfectly to the variables that are
associate with a GNode, as the context is usually something from the
outside and the variables are more like properties inherent to the
GNode.

The term "global context" fits even less.  Since the thing where
variables are looked up is commonly named a scope, use that term
instead.

This commit only renames the global variables VAR_GLOBAL, VAR_INTERNAL
and VAR_CMDLINE, plus a few very closely related comments.  These are:

	GNode.vars (because of line breaks)
	GNode_Free (dito)
	varname-make_print_var_on_error.mk
	varname-make_print_var_on_error-jobs.mk

The debug message in Var_Stats is left as-is since there is no unit test
for it yet.

The other renamings (variable names "context", "ctxt", as well as
further comments) will be done in a follow-up commit.
2021-02-04 21:33:13 +00:00
rillig
8660931fea make: rename Var_Set to Var_SetExpand
After doing the textual renaming across all files, I added a new
function Var_Set that does not expand the variable name.  I then undid
the renaming for all calls where the variable name cannot ever contain a
dollar sign.  I omitted the word "Expand" from the textual references in
the unit tests and in the debug logging messages since the focus is
usually on the "Set" part, not on the "Expand".

No functional change.
2021-02-04 19:00:45 +00:00
rillig
785cdc035e make: split Var_Exists into plain Var_Exists and Var_ExistsExpand
Most previous calls to Var_Exists use constant variable names.  Only the
two calls in parse.c need to expand the variable name.

It may be a good idea to expand the variable name once in VarAssign_Eval
instead of repeating the expansion in each of its special cases.

No functional change.
2021-02-03 14:33:09 +00:00
rillig
a1bc5ad8cf make: replace Global_AppendExpand with Global_Append
All callers with a variable name that is guaranteed to not contain a
dollar sign have been converted to call Global_Append instead of the
previous Global_AppendExpand.  After that, Global_AppendExpand was
unused, therefore it was effectively just renamed.
2021-02-03 13:53:12 +00:00
rillig
8c8241ebce make: split Var_Append into Var_Append and Var_AppendExpand
The plain Var_Append now does not expand the variable name anymore.  It
is used in situations where the variable name is known to not contain a
dollar sign.

This is a preparation for adding Global_Append, corresponding to
Global_AppendExpand.
2021-02-03 13:44:39 +00:00
rillig
87686000da make: replace Global_SetExpand with Global_Set for constant names 2021-02-03 08:08:18 +00:00
rillig
3ec10f8db6 make: use shortcut functions Global_SetExpand and Global_AppendExpand
There are many places where global variables are set or appended to.  To
reduce clutter and code size, encode the VAR_GLOBAL in the function
name.

The word Expand in the function names says that the variable name is
expanded.  In most of the cases, this is not necessary, but there are no
corresponding functions Global_Set or Global_Append yet.

Encoding the information whether the name is expanded or not in the
function name will make inconsistencies obvious in future manual code
reviews. Letting the compiler check this by using different types for
unexpanded and expanded variable names is probably not worth the effort.
There are still a few bugs to be fixed, such as in SetVar, which expands
the variable name twice in a row.
2021-02-03 08:00:36 +00:00
rillig
af3617fb7b make: clean up comments in parse.c 2021-02-01 22:21:33 +00:00
rillig
4d3c47ebd1 make: rename Parse_include_file to IncludeFile 2021-02-01 22:16:57 +00:00
rillig
fac4e91ef4 make: simplify VarAssign_EvalSubst
No functional change.
2021-02-01 22:06:05 +00:00
rillig
6735aca7b2 make: replace parse error "Need an operator" with better message
The previous error message is not easily understandable since it is
missing a crucial detail, the column where the operator is needed.
Without this information, the author of the makefile gets no useful
hint.  Furthermore, there are several types of operators in makefiles:

	the dependency operators ':', '!', '::',
	the variable assignment operators '=', '!=', '+=', '?=', ':=',
	the conditional operators '&&', '||', '!',
	the comparison operators '==', '!=', '>', '>=', '<', '<='.

This leaves too much ambiguity.

Replace this error message with "Invalid line type", which is more
generic, more accurate and thus less misleading.
2021-02-01 21:56:03 +00:00
rillig
39649bbcec make(1): split Buf_Destroy into Buf_Done and Buf_DoneData
In all cases except one, the boolean argument to Buf_Destroy was
constant.  Removing that argument by splitting the function into two
separate functions makes the intention clearer on the call site.  It
also removes the possibility for using the return value of Buf_Done,
which would have made no sense.

The function Buf_Done now pairs with Buf_Init, just as in HashTable and
Lst.

Even though Buf_Done is essentially a no-op, it is kept as a function,
both for symmetry with Buf_Init and for clearing the Buffer members
after use (this will be done only in CLEANUP mode, in a follow-up
commit).
2021-01-30 20:53:29 +00:00
rillig
11230f0e67 make(1): fix irrelevant message in -W mode 2021-01-27 00:02:38 +00:00
rillig
bf988a5d2f make(1): in -dp mode, print stack trace with each diagnostic
This makes it easier to track down where a warning or an error
originated from.  This information could be further enriched for .for
loops, to also include the variable names and their values.  For now,
it's good enough to replace the large comment describing how a stack
trace _could_ be generated with actual code that implements that idea.

The syntax of the locations is <filename>:<lineno>, which intentionally
differs from the traditional "<filename>" line <lineno>, since the
former is more widely supported by editors and IDEs.

Having this stacktrace information is especially intended for
complicated systems built upon make, such as pkgsrc.
2021-01-26 23:44:56 +00:00
rillig
f1a32e5707 make(1): convert SearchPath to struct
This prepares for making dotLast a simple struct member instead of a
fake CachedDir, which is easier to understand.
2021-01-24 20:11:55 +00:00
rillig
0e4d57561e make(1): improve variable names when parsing directives 2021-01-23 12:03:25 +00:00
rillig
c66282df08 make(1): rename Dir_AddDir, reorder parameters of SearchPath_ToFlags 2021-01-23 11:34:41 +00:00
rillig
34d4e06a16 make(1): rename Dir_Expand to SearchPath_Expand
The main subject of this function is the search path.  In this search
path the pattern is expanded.
2021-01-23 10:48:49 +00:00
rillig
9576543b4d make(1): merge duplicate code in Parse_MainName 2021-01-21 14:30:01 +00:00
rillig
31940a95cd make(1): consistently use boolean expressions in conditions
Most of the make code already followed the style of explicitly writing
(ptr != NULL) instead of the shorter (ptr) in conditions.

The remaining 50 instances have been found by an experimental,
unpublished check in lint(1) that treats bool expressions as
incompatible to any other scalar type, just as in Java, C#, Pascal and
several other languages.

The only unsafe operation on Boolean that is left over is (flags &
FLAG), for an enum implementing a bit set.  If Boolean is an ordinary
integer type (the default), some high bits may get lost.  But if Boolean
is the same as _Bool (by compiling with -DUSE_C99_BOOLEAN), C99 6.3.1.2
defines that a conversion from any scalar to the type _Bool acts as a
comparison to 0, which cannot lose any bits.
2021-01-10 21:20:46 +00:00
rillig
71c58e78f7 make(1): replace pointers in controlling conditions with booleans 2020-12-31 17:39:36 +00:00
rillig
b754dcb0cc make(1): format multi-line comments 2020-12-30 10:03:16 +00:00
rillig
76736a6e95 make(1): rename Buf_Expand_1 to Buf_Expand 2020-12-28 15:42:53 +00:00
rillig
a2efb39127 make(1): remove mmap for loading files, only allow files < 1 GiB
Using mmap is beneficial if the loaded data is read-only, or if it is
accessed in random order.  Neither of these applies here.  When loading
a file, make reads it strictly from top to bottom, once.  During
parsing, the loaded data is modified in-place to insert '\0' and '\n'
for terminating strings and lines.  Because of all of this, there is no
benefit in using mmap.

Reading the file using 2 calls to read(2) (one for the data, one for
checking for EOF) loads the data in a single pass, instead of producing
a page fault whenever the parser passes another page boundary.

Use a Buffer for loading the file data, to avoid calling bmake_realloc
directly.

Do not resize the loaded buffer at the end.  Each loaded file is
short-lived anyway, and only a few files are loaded at the same time, so
there is no point in optimizing this part for low memory usage.
2020-12-28 15:21:33 +00:00
rillig
fc135022e2 make(1): replace global preserveUndefined with VARE_KEEP_UNDEF
Controlling the expansion of variable expressions using a global
variable and a VARE flag was inconsistent.

Converting the global variable into a flag had to prerequisites:

1.  The unintended duplicate variable assignment had to be fixed, as
done in parse.c 1.520 from 2020-12-27.  Without this fix, it would have
been necessary to add more flags to Var_Exists and Var_SetWithFlags, and
this would have become too complex.

2.  There had to be a unit test demonstrating that VARE_KEEP_DOLLAR only
applies to the top-level expression and is not passed to the
subexpressions, while VARE_KEEP_UNDEF applies to all subexpressions as
well.  This test is in var-op-expand.mk 1.10 from 2020-12-28, at least
for the ':@word@' modifier.  In ParseModifierPartSubst, VARE_KEEP_UNDEF
is not passed down either, in the same way.
2020-12-28 00:46:24 +00:00
rillig
7c100c94f2 make(1): fix edge case in := with undefined in variable name
Previously, the assignment "VAR${UNDEF} := value" actually assigned to 2
variables.  See var-op-expand.mk for details.
2020-12-27 22:29:37 +00:00
rillig
996e51af2c make(1): skip variable expansion in ParseDependencyTargetWord
The goal of the code is just to skip over the variable expression, thus
there is no need to evaluate it.
2020-12-27 18:22:28 +00:00
rillig
bb4b461edd make(1): exit 2 on technical errors
This allows the -q option to distinguish errors from out-of-date
targets.  Granted, it's an edge case but it should be solved
consistently anyway.

The majority of cases in which make exits with exit status 1, even in -q
mode, is when there are parse errors.  These have been kept as-is for
now as they affect many of the unit tests.

The technical errors, on the other hand, occur so rarely that it's hard
to write reliable tests for them that fail consistently on all platforms
supported by make.
2020-12-27 11:47:04 +00:00
rillig
ea8c5a40a4 make(1): align names of VarExportMode with the directives 2020-12-27 05:06:17 +00:00
rillig
50fdf93be0 make(1): fix a few lint warnings 2020-12-23 14:13:49 +00:00
rillig
dff2a68ecc make(1): rename CmdOpts.lint to strict
When running lint(1) on the code, it defines the preprocessor macro
"lint" to 1, which generated a syntax error in the declaration "Boolean
lint", as that became "Boolean 1".
2020-12-23 13:50:54 +00:00
rillig
e6d109f2d3 make(1): re-add improved assertion in ParseGetLine 2020-12-22 08:51:30 +00:00
rillig
9582eb4d33 make(1): remove assertion about lines ending with '\n'
It fails the NetBSD build.sh.
2020-12-22 08:31:13 +00:00
rillig
75fb9c6afb make(1): remove needless assignment to line_end in ParseGetLine 2020-12-22 08:10:39 +00:00
rillig
b46e8d7cf5 make(1): fix assertion failure for files without trailing newline
Previously, mmapped files didn't always have the final newline added.
Only those that ended at a page boundary did.

This confused ParseRawLine, which assumed (and since parse.c 1.510 from
moments ago also asserted) that every line ends with a newline, which
allows the code to assume that after a backslash, there is at least one
other character in the buffer, thereby preventing an out-of-bounds read.

This bug had been there at least since parse.c 1.170 from 2010-12-25
04:57:07, maybe even earlier, I didn't check.

Now line_end always points to the trailing newline, which allows
ParseGetLine to overwrite that character to end the string.
2020-12-22 08:05:08 +00:00
rillig
9b03887383 make(1): prevent undefined behavior in loadfile_mmap
Reading a file without a trailing newline had resulted in an
out-of-bounds write, in the common case where the file is loaded via
mmap.
2020-12-22 06:48:33 +00:00
rillig
0743b63f41 make(1): fix garbled output for failed shell command (since 2020-12-20)
Passing a struct as printf argument for the %s conversion doesn't work.
On NetBSD-8.0-x86_64, the output looks normal, but on SunOS-5.9, the
output is garbled, containing bytes 0xFF and 0xFE.

This bug had been introduced in parse.c 1.507 from 2020-12-20 14:52:16.

Thanks to sjg for finding this bug so quickly.
2020-12-21 02:09:34 +00:00
rillig
9c42de2852 make(1): remove redundant const declarations for parameters 2020-12-20 18:23:24 +00:00