'heaputil' is producing a lot of complaints. This fixes one of them,
about freeing memory that was never allocated. In this case, it's
when removing an overview annotation for a level. The annotation
is using dupstr_n() and not being recorded due to dupstr_n() being
placed after MONITOR_HEAP undefines the macro that overrides alloc().
There's only one use of dupstr_n(), and its length checking isn't
needed there, so just switch to dupstr() and comment out the
implementation of dupstr_n(). I left the prototype in extern.h;
that's harmless.
If dupstr_n() needs to be resurrected, a second MONITOR_HEAP-aware
version should be implemented, with corresponding macro to choose
which one to use.
Verifying that strlen(string) isn't too long, then allocating and
copying strlen(string)+1 draws a complaint about strcpy() overflowing
its output buffer.
Not an issue for regular play, but could matter for config file and
sysconf manipulation.
new .h files: hacklib.h selvar.h stairs.h
new .c files: calendar.c, getpos.c, report.c, selvar.c, stairs.c,
strutil.c, wizcmds.c
cleanup of hacklib.c and mdlib.c
hacklib contains functions that do not have to link with the core
relocate wiz commands from cmd.c to wizcmds.c
relocate CRASHREPORT stuff to report.c
relocate getpos stuff from do_name.c to getpos.c
remove temporary struct definition from extern.h
cross-compile PRE-section split into cross-pre1.370 and cross-pre2.370
Windows sys/windows/Makefile.nmake and sys/windows/Makefile.mingw32 and
visual studio project file updates
Unix sys/unix/Makefile.src, sys/unix/Makefile.utl
populate selvar.c and selvar.h
build on MS-DOS (not cross-compile) Makefile updates
for sys/msdos/Makefile.GCC (untested)
vms updates for above (untested)
Restore its ability to reject a string longer than will fit within
size_t that was lost by moving away from strnlen(). Determine the
length inline rather than using strlen().
Move it from hacklib.c to alloc.c so that utility programs have easy
access, and remove the copy of it from dlb_main.c.
Fix a logic bug in str_start_is(). If a string was considered to
be too long, it exited the loop when n was 0 but also performed
post-decrement. So after the loop, n would be -1 and the 'if (n==0)'
test would fail. panic() would occur if the initial string matched
and happened to be LARGEST_INT-1 characters long.
Have alloc() treat a request for 0 bytes as if it was one for
'sizeof (long)' bytes so that the issue of malloc(0) maybe yielding
NULL becomes moot.
I think instances of attempting to allocate 0 bytes should probably
still be checked for and made to avoid calling alloc(0). Assuming
that alloc() will clean up requests for nothing feels sloppy.
gcc-13.1 static analyzer complains that alloc() returns long *
without guaranteeing to allocate an integral number of longs. Fix
by rounding the requested amount up to the next long when dividing
the amount by 'sizeof (long)' yields a remainder. Surprisingly--to
me, at least--the analyzer recognizes that this extra argument
manipulation will always produce a viable amount no matter what
alloc()'s caller passes in.
Also, the declarations for alloc() and re_alloc() in alloc.c didn't
match the ones in global.h for the MONITOR_HEAP config. I guess
nobody has tested that since NONNULL got introduced.
A year ago the two FITSxxx routines were moved from hacklib.c to
alloc.c so that they could easily be linked into various programs
instead of being replicated in each, but the declarations for them
weren't moved from hacklib.c section in extern.h to alloc.c one.
I assumed that the complaint about macro refinition was for the two
in alloc.c replacing two from hack.h from another file, but it could
be that those being defined by alloc.c were interferring with the
regular hack.h ones. alloc.c doesn't need them, and was also skipping
an opportunity to use one of them.
Mark alloc()--also dupstr() and re_alloc()--for gcc and clang as
always returning non-Null. This should silence some of the static
analysis complaints.
Almost all the monster and object naming functions (anything that
returns an mbuf or an obuf) should be marked this way too but I'll
leave that for somebody else to deal with.
I didn't attempt to mark alloc() with the 'malloc' attribute because
macro definitions could end up causing trouble. Specifying its
deallocator would probably be useful but is at even bigger risk of
macro interference.
I'm not sure whether gcc 3 is really the right test for whether the
returns_nonnull attribute setting is available.
realloc(NULL, size) is legitimate usage and nhrealloc() shouldn't
log a "< 0x00000000 __FILE__ __LINE__" entry for it. heaputil
would complain about freeing Null.
Add new routine 're_alloc()' that functions as MONITOR_HEAP-aware
libc realloc(). 'nhrealloc()' is the version that passes source
file and line info if built with MONITOR_HEAP enabled. The heaplog
data might now contain '<' (freed by realloc), '>' (replacement
allocation by realloc), and '*' (resized by realloc) entries in
addition to the previous '+' (allocated) and '-' (freed) entries.
heaputil has already been updated in the NHinternal repository.
Move FITSint_() and FITSuint_() from hacklib.c to alloc.c so that
they can be accessed by miscellaneous utility programs.
Remove three or four copies of FITSint_() that were duplicated in
utility programs like dlb and tile2bmp due to those not having
access to src/hacklib.o. They do have access to src/alloc.o (and
util/panic.o).
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
Add dupstr() as a substitute for strdup() so that out-of-memory
handling will be consistent with the rest of nethack, and make it aware
of nethack's heap logging. It's treated like alloc() so that its caller
can be logged for NH_HEAPLOG.
I put it into use in a few places, but there are lots more candidates
besides the existing calls to strdup() that should be replaced.
Hide pointer formatting in alloc.c by eliminating the need for callers
to know how big a buffer is required. I generally prefer the caller to
pass in its own buffer for this sort of thing, but in this case the usage
is almost entirely for debugging so using static buffers results in less
clutter in the rest of the code.