The variable "line" was misnamed since it turned from the beginning of
the line to the variable name. The variable "cp" was named too broadly.
Having two moving pointers in a single parsing function was too much.
Now p is the only moving pointer. From it, the variable name and value
are extracted as the pointer flies by. These more specific names make
the lower half of the function more readable since Var_Set(name, value)
sounds more correct and to the point than Var_Set(line, cp).
Memory management for the possibly expanded variable value is now
simpler as there may or may not be an expanded value, and that is freed
in every case. No need for another Boolean variable called freeCp
anymore. Distinguishing between the unexpanded value and the actual
value highlights the data flow.
Using const pointers is a step into the direction of having a parser
that operates on a read-only string. Right now the string is destroyed
upon parsing.
When a line starts with "=value", this is interpreted as a variable
assignment, with an empty variable name. In that case, there is no
"previous character" from the '='. Accessing that character therefore
was an out-of-bounds read access.
If a whole file starts with "=value", instead of just a single line,
this out-of-bounds access can actually lead to a segmentation fault.
This depends on the memory allocator though.
Having the hash function potentially redefined is a bit too much
flexibility. If actually needed, this should be done using a patch, not
using the C preprocessor.
Converting the macro to a function made the control flow easier to
understand. It also revealed that the variable p was unnecessary in
both Hash_FindEntry and Hash_CreateEntry.
target partition). Instead introduce a new PTI_INSTALL_TARGET per partition
flag and deal with it in the partitioning backends.
Honour pm->ptstart when allocating new partitions - it is supposed to be
the first sector usable by NetBSD.
a "bootinfo" structure for us. Qemu does, however, place a Linux kernel
parameter block at kernel_text[] - 0x6000 that contains Linux-style kernel
command line arguments. So, add a prom_qemu_getenv() that allows us to
look for specific things passed along to the kernel from there, and use
them as follows:
- Support specifying the root device in the forms "root=/dev/wd0a",
"root=wd0a", or "rootdev=wd0".
- Support SRM-like -flags ... in the form of "flags=AD". In the case of
Qemu, we also assume that no flags=... is the same as "flags=A", i.e.
perform an auto-boot.
Also allow an alternate delay() function to be specified, if the platform
wishes to provide one.
It's not the primary task of make to handle procedure calls with
parameters, combined with lexical scoping, therefore the code does not
look as straight-forward or clean as in other programming languages. It
feels more like squeezing a programming problem from the imperative
world into the world of declarative dependencies.
A more idiomatic way of implementing this puzzle should be as a
dependency graph since that's both the natural structure of the puzzle
and the primary domain of make. Something like having a main target
"hanoi-5" that depends on intermediate targets of the form
"move-1.2.3.4.5-_._._._._-_._._._._", each representing a single
configuration of the stacks. These targets could be generated
dynamically. A benefit of this implementation would be that the puzzle
could be resumed from an arbitrary configuration, just just from the
initial configuration.
This is only intended for the unit tests, to selectively enable and
disable debug logging as needed. Previously the tests for debug logging
required complicated postprocessing that was not obvious when looking at
the test .mk file alone, but was specified externally in
unit-tests/Makefile.
This is the simplest possible implementation. Another variant would
have been to selectively disable individual debug logging options, but
that would have made the code more complicated.
The -dL option is not affected by -d0 since that is not really a debug
option, even if it is implemented as one.