For doing as you describe, avoiding strings and run-time comparisons, I can only think of a pre-preprocessor. Would it be for just a quick hacking around, in a Unix environment I'd try a simple wrapper for the preprocessor using a bash script that in turn uses sed or awk to replace the functions and arguments mentioned and then calling the real cpp preprocessor. I'd consider this just as a quick hack.
Update: In linux and gcc, it seems easier to do a post-preprocessor, because we can replace the generated .i file (but we can't generally do that with the original .c file). For doing that, we can make a cc1 wrapper.
Warning: this is another dangerous and ugly hack. Also see Custom gcc preprocessor
This is a cc1 wrapper for doing that. It's a bash script for linux and gcc 4.6:
#!/bin/bash
# cc1 that does post preprocessing on generated .i files, replacing function calls
#
# note: doing post preprocessing is easier than pre preprocessing, because in post preprocessing we can replace the temporary .i file generated by the preprocessor (in case of doing pre preprocessing, we should change the original .c file -this is unacceptable-; or generate a new temp .c file with our preprocessing before calling the real preprocessor, but then eventual error messages are now referring to the temp .c file..)
convert ()
{
local i=$1
local o=$2
ascript=$(cat <<- 'EOAWK'
{
FUNCT=$1;
ARGS=$2;
RESULT=$3;
printf "s/%s[ \\t]*([ \\t]*%s[ \\t]*)/%s/g\n", FUNCT, ARGS, RESULT;
}
EOAWK
)
seds=$(awk -F '|' -- "$ascript" << EOFUNCS
FUNC_A|"ABCD"|0
FUNC_A|"EFGH"|1
FUNC_A|X|0xFF
EOFUNCS
)
sedfile=$(mktemp --tmpdir prepro.sed.XXX)
echo -n "$seds" > "$sedfile"
sed -f "$sedfile" "$i" > "$o"
rc=$?
rm "$sedfile"
return $rc
}
for a
do
if [[ $a = -E ]]
then
isprepro=1
elif [[ $isprepro && $a = -o ]]
then
getfile=1
elif [[ $isprepro && $getfile && $a =~ ^[^-].*[.]i ]]
then
ifile=$a
break
fi
done
#echo "args:$@"
#echo "getfile=$getfile"
#echo "ifile=$ifile"
realcc1=/usr/lib/gcc/i686-linux-gnu/4.6/cc1
$realcc1 "$@"
rc=$?
if [[ $rc -eq 0 && $isprepro && $ifile ]]
then
newifile=$(mktemp --tmpdir prepro.XXX.i)
convert "$ifile" "$newifile" && mv "$newifile" "$ifile"
fi
exit $rc
How to use it: call gcc using flags -B (directory where cc1 wrapper resides) and --no-integrated-cpp