c++ 适用于不进行标记化但仍进行串联的预处理器标志

q43xntqr  于 2023-05-30  发布在  其他
关注(0)|答案(1)|浏览(158)

我继承了一些PCL(Patran命令语言)代码,这些代码是用C预处理器预处理的,以便使用宏等。这段代码有许多特性不适用于现代的预处理器,如cpp。目前我使用的是11.3.0版本的gcc -Ecpp
例如,一个问题是由PCL中的连接运算符“//”引起的,但被cpp识别为注解:

$ A.pcc

#define FUNC(X) ui_write(X)
string variable
FUNC("text "//variable//" more text")

所需的结果为

string variable
ui_write("text "//variable//" more text")

我可以使用以下命令成功地预处理它

cpp -traditional A.pcc

其中-traditional表示使用不标记的旧式cpp,因此注解符号不是问题。如果不使用此标志,预处理器将无法匹配FUNC(X)中的参数X,并在注解处结束令牌搜索时出错。
在同一个文件(以及许多其他文件)中,还使用了令牌连接/令牌粘贴:

$ B.pcc

#define CAT(I,J) command ## I ## J ## s()

CAT(1,2)

所需的结果为

command12s()

但是,通过使用-traditional标志,将关闭令牌连接,因此结果为

command ## 1 ## 2 ## s()

这不是有效的PCL。
有没有合适的标志?这两个问题发生在相同的文件中,所以我无法编译具有不同标志的不同文件。我目前最好的想法是使用sed将注解替换为其他字符,进行预处理,然后将它们放回。
编辑:我已经通过这个答案找到了一个cpp唯一的解决方案(multipass a source code to cpp),所以对我来说这行是

cpp -traditional file.pcc | cpp -C

其中-C标志表示保留注解。我必须在每个文件中添加一个宏,这样在第一次传递时就不会发生标记连接

#define DEF_CAT #define CAT(I,J) command ## I ## J ## ()
DEF_CAT
pftdvrlh

pftdvrlh1#

//预处理为cpp忽略的内容,然后再将其预处理回来。以下是/tmp/mycpp

#!/bin/bash
uuid=06ae45e2-dd08-40db-abeb-1089e89e638f
sed "s@//@$uuid@g" "$@" | cpp -P -xc - | sed "s@$uuid@//@g"

以下shell脚本显示了执行过程:

$ in='
#define FUNC(X) ui_write(X)
string variable
FUNC("text "//variable//" more text")

#define CAT(I,J) command ## I ## J()
CAT(1,2)
'
$ /tmp/mycpp <<<"$in"
string variable                                                                                                                 
ui_write("text "//variable//" more text")
command12()

相关问题