就像你所描述的那樣,避免字符串和運行時比較,我只能想到一個預處理器。在Unix環境下,我會嘗試使用bash腳本對預處理器進行簡單的包裝,然後使用sed或awk替換所提及的函數和參數,然後調用真正的cpp預處理器。我認爲這只是一個快速入侵。
更新:在linux和gcc中,執行後處理器似乎更容易,因爲我們可以替換生成的.i文件(但我們通常不能用原始的.c文件來做)。爲此,我們可以製作一個cc1封裝。
警告:這是另一個危險和醜陋的破解。另見Custom gcc preprocessor
這是一個用於做這件事的cc1包裝。這是Linux下的bash腳本和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:[email protected]"
#echo "getfile=$getfile"
#echo "ifile=$ifile"
realcc1=/usr/lib/gcc/i686-linux-gnu/4.6/cc1
$realcc1 "[email protected]"
rc=$?
if [[ $rc -eq 0 && $isprepro && $ifile ]]
then
newifile=$(mktemp --tmpdir prepro.XXX.i)
convert "$ifile" "$newifile" && mv "$newifile" "$ifile"
fi
exit $rc
如何使用它:使用標誌調用gcc的-B(目錄,其中CC1包裝居住)和--no集成-CPP
對宏的參數是字符串是重要的嗎?難道不就是'FUNC_A(ABCD); FUNC_A(EFGH);'用令牌而不是字符串? –
是啊,不幸的是我需要使用除預處理器無法處理的字母之外的符號(例如。==,>
schuess
我能想到的唯一的事情就是在編譯之前替換它們的自定義分析器,但我真的不想更改信息來源 – schuess