あなたが説明したように、文字列と実行時の比較を回避するために、私はプリプリプロセッサしか考えられません。Unix 環境では、sed または awk を使用して前述の関数と引数を置き換え、実際の cpp プリプロセッサを呼び出す bash スクリプトを使用して、プリプロセッサの単純なラッパーを試してみます。これは簡単なハックだと思います。
更新: Linux と gcc では、生成された .i ファイルを置き換えることができるため、ポスト プリプロセッサを実行する方が簡単なようです (ただし、通常、元の .c ファイルでそれを行うことはできません)。そのために、cc1 ラッパーを作成できます。
警告: これは別の危険で醜いハックです。カスタム gcc プリプロセッサも参照してください
これは、それを行うための cc1 ラッパーです。Linux および gcc 4.6 用の bash スクリプトです。
#!/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
使用方法: フラグ-B (cc1 ラッパーが存在するディレクトリ) および--no-integrated-cppを使用して gcc を呼び出します。