就像你所描述的那样,避免字符串和运行时比较,我只能想到一个预处理器。在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