The handling of %? in multi-line macros was broken when the macro name
was preceeded by a label; it would expand to the label instead of the
macro name. This was particularly serious since this was used in
the macro implementation of INCBIN.
The dependency list tail pointer wasn't actually updated correctly.
Fix that. We may want to make this a structure of some sort to make
the code a bit cleaner, but this seems to be the cleanest hack for
now.
Ownership of the filename string was a bit fuzzy, with the result that
we were freeing it even though it was retained for use by __FILE__.
Clean up a number of other memory management issues with the new
quoting code, and change the stdscan implementation to one pass over
the string.
Introduce new preprocessor directives %depend and %pathsearch, and
make incbin a standard macro using these filenames. This lets us
remove the code that makes incbin search the path.
Call expand_smacros() early instead of expand_smacros_in_string()
late. expand_smacros_in_string() seems like a prodigiously bad idea
and a sheer brainfart in my opinion.
Add the -MP option to emit phony targets. Since this means each
header file has to be visited more than once, change the
implementation to use an internal list of all the dependencies, and
centralize the emission of the dependency files.
Implement the dependency options:
-MF: set the file to which dependencies are written.
-MD: generate dependencies in parallel with compilation.
-MT: set the name of the dependency target.
-MQ: same as -MT, but *attempt* to quote it for Makefile safety.
struct hash_table, a fixed-sized structure, is now allocated by the
caller. This lets us integrate it into the Context structure, thus
avoiding an additional dynamically allocated object for no good
reason.
Add some minor code collapsing: make it more obvious that all that
differs is a pointer value, rather than relying on the compiler to do
tail merging.
The compiler is free to store enum pp_token_type into any size integer
small enough to contain all the values up to 2^n-1 for the smallest n
which contains all the values. Force it to size it to integer size,
since we use it to hold macro positional parameters.
%? - substitute the macro name as invoked
%?? - substitute the macro name as defined
In particular:
%idefine keyword $%?
... can be used to make a new keyword "disappear".
Normally, contexts aren't used with a large number of macros, but in
case someone does, do use hash tables for those as well. This
simplifies the code somewhat, since *all* handling of macros is now
done via hash tables.
Future note: consider if it wouldn't be better to allow struct
hash_table to be allocated by the caller, instead of being allocated
by the hash table routine.
Fix buffer overflow in preproc.c due to an incorrect test. In the
code:
for (r = p, s = ourcopy; *r; r++) {
if (r >= p+MAX_KEYWORD)
return tokval->t_type = TOKEN_ID; /* Not a keyword */
*s++ = tolower(*r);
}
*s = '\0';
... the test really needs to be >= since for the pass where there are
equal:
a) a nonzero byte means we have > MAX_KEYWORD characters, and
b) s = ourcopy+MAX_KEYWORD; but if the test doesn't trigger,
we can write one more character *plus* the null byte, overflowing
ourcopy.
First cut at AVX machinery support. The only instruction implemented
is VPERMIL2PS, and it's probably buggy. I'm checking this in with the
hope that other people can start helping out with (a) testing this,
and (b) adding instructions.
NDISASM support is not there yet.
Correct the implementation of %arg and %local.
It's questionable how much they make sense for 64-bit mode; even in
32-bit mode one normally make references off the stack pointer instead
of the base pointer (frame pointer), but that requires keeping track
of the stack pointer offset.
Correct the handling of floating-point tokens in the preprocessor.
The preprocessor scanner and the main scanner really are painfully
divergent for no good reason.
Proper use of bool and enum makes code easier to debug. Do more of
it. In particular, we really should stomp out any residual uses of
magic constants that aren't enums or, in some cases, even #defines.
Per the comment:
* In a MMacro describing a `%rep' block, the `in_progress' field
* isn't merely boolean, but gives the number of repeats left to
* run.
This fixes the "global" directive not getting recognized, since it
repeats over all its arguments.
Both C and C++ have "bool", "true" and "false" in lower case; C
requires <stdbool.h> for this, in C++ it is an inherent type built
into the compiler. Use those instead of the old macros; emulate with
a simple typedef enum if unavailable.
Concentrate compiler dependencies to compiler.h; make sure compiler.h
is included first in every .c file (since some prototypes may depend
on the presence of feature request macros.)
Actually use the conditional inclusion of various functions (totally
broken in previous releases.)
The parent-pointer-based freeing loop in %undef should not advance the
parent pointer when a node is freed, since that will result accessing
freed memory.
Implement the -MG option, to generate dependencies in the presence of
generated files. In the end, we probably need to support the full
gamut of GCC-like dependency-generation options.
Document that %+ needs a space after it due to collision with %+1
syntax for multiline macro arguments; make it issue an error message
rather than crashing.