aka "the memcmp bug", from a patch for gcc-10 in
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95189
Tested on x86_64 by running a full build, install and running it.
Testing that the problem has been fixed with one of the unit tests provided.
Placing null characters all over the line made the code hard to
understand. The null characters were placed for top-level whitespace as
well as the operator.
Working with a read-only line makes it easier to inspect the parsing
state during debugging.
This change involves an additional bmake_malloc for each variable name.
This will be compensated later by extending the API of the Var module to
also accept a pair of pointers (start, end) as the variable name.
- Use the "pool" keyword for obtaining servers from ntp.pool.org.
- Add "tos minclock" and "tos maxclock" to limit the number of servers.
- Add "restrict source" to apply appropriate restrictions to servers.
(Specifically "nopeer" cannot be applied to "pool" servers.)
- A single "pool" entry suffices -- using "2.netbsd.pool.ntp.org" so
that we get both IPv4 and IPv6 addresses. (No addresses are returned
for just "netbsd.pool.ntp.org.")
- Add a comment about "tinker panic 0" -- useful for VMs and laptops.
- Add a comment about "discard minimum" -- useful for some SNTP clients.
- Add an explanation for the "limited" restriction keyword.
- Unify whitespace and comment formatting.
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.