I once learned a lot about m4; more than twenty years ago. I remember all the features it has, like redefining the delimiters for macros, diversions, for loops and all that jazz.
So it's not due to lack of familiarity that I won't use it; it is simply atrocious.
Recently I needed a preprocessor (featuring just simple if/ifdef/elif/endif) in a Linux distro build system (Yocto). I didn't want to add anything new.
To avoid inflicting m4 on myself and everyone who has to interact with this in the future, I wrote a simple awk script wrapped around cpp.
The tiny awk script implements this pipeline, which involves encoding and decoding the input so that cpp never sees the syntax of the file:
this is our 1 1 this is our
original 2 2 --> [dec] original
@ifdef FOO --[enc]--> #ifdef FOO --[cpp]--> 6 file
input 4
@endif #endif
file 6
this works with nearly any textual input. Your input can contain broken C tokens and comments and whatnot.
I switched the # to @ to remind people that this isn't the C preprocessor, and because # is a comment character in the preprocessed language, which could look confusing.