Description
ImageMagick has an "X macro" named AddMagickCoder
that is defined differently in three different files (MagickCore/{coder,magic,static}.c
) before including a header file (coders/coders-list.h
) that makes many calls to AddMagickCoder
.
The macro expander has a workaround where if it sees several different expansions of the same line, it keeps the original, unexpanded content. This workaround correctly handles most of the calls to AddMagickCoder
. However, there are a few calls for which the coder.c
and magic.c
expansions are blank (due to the behavior of the particular definitions of AddMagickCoder
in those files) but the static.c
expansion is non-blank. In order to correctly handle preprocessor conditionals, the macro expander ignores blank expansions, so it accepts the static.c
expansion of each of those lines as its unique valid expansion and copies it into coders/coders-list.h
. That expansion then shows up in coder.c
and magic.c
, causing the verification to fail.
I don't see an obvious way to adjust the "different expansions" workaround to completely solve the AddMagickCoder
problem without breaking other cases. --undef_macros
doesn't help either because the macros are defined in the main source file (just like the printf
recursive macros in some of the benchmarks in analyse-conv that are currently patched by an ad-hoc sed
command in the makefile). So it seems we need some other way to prevent the AddMagickCoder
calls from expanding. Some ideas:
- Apply ad-hoc patches to the source code before macro expansion. For example, we could have the macro expander define a special macro during its operation (e.g.,
-D_3C_MACRO_EXPANDER
) and then put#ifndef _3C_MACRO_EXPANDER
around problematic constructs. This is probably the most general approach (and users could actually leave those conditionals in their code during porting), but we may prefer a less invasive approach if possible. - Add an option to
convert_project
that excludes a file from macro expansion (in this case,coders/coders-list.h
). - Add a
--hide_macros
option that temporarily deletes anything that looks like a#define
of one of the specified macros during macro expansion and then adds the#define
s back in at the end. This is likely the most work to implement, but it will handle theprintf
wrapper macros as well asAddMagickCoder
, so it might be worth going ahead and doing it.
So: any thoughts?