在文本文件中使用整数算术扩展 C 预处理器宏?

sdb*_*bbs 2 c macros variable-expansion c-preprocessor

在我的系统上,我有一个/usr/include目录,curl/options.h其中有一个文件,其中包含 CURLOT_FLAG_ALIAS 的预处理器定义。

如果我有以下 test.txt:

#include "curl/options.h"

curlot flag alias is: CURLOT_FLAG_ALIAS
Run Code Online (Sandbox Code Playgroud)

然后我可以这样做来扩展文本文件中的宏:

$ gcc -E -P -x c -I/usr/include test.txt
typedef enum {
  CURLOT_LONG,
  CURLOT_VALUES,
  CURLOT_OFF_T,
  CURLOT_OBJECT,
  CURLOT_STRING,
  CURLOT_SLIST,
  CURLOT_CBPTR,
  CURLOT_BLOB,
  CURLOT_FUNCTION
} curl_easytype;
struct curl_easyoption {
  const char *name;
  CURLoption id;
  curl_easytype type;
  unsigned int flags;
};
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_name(const char *name);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_id(CURLoption id);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_next(const struct curl_easyoption *prev);
curlot flag alias is: (1<<0)
Run Code Online (Sandbox Code Playgroud)

然而,这种方法也转储了 ; 中的所有函数定义curl/options.h。最终,为了只处理文本文件,这会给出一个更“干净”的结果 - 必须test.txt是:

curlot flag alias is: CURLOT_FLAG_ALIAS
Run Code Online (Sandbox Code Playgroud)

...然后使用-imacrosswitch (并通过管道grep删除空行):

$ gcc -E -P -x c -I/usr/include -imacros curl/options.h test.txt | grep -v '^[[:space:]]*$'
curlot flag alias is: (1<<0)
Run Code Online (Sandbox Code Playgroud)

太棒了 - 除了,我真的不想要(1<<0)文本输出 - 我想要它的扩展整数十进制值,1; 换句话说,我希望文本输出为:

curlot flag alias is: 1
Run Code Online (Sandbox Code Playgroud)

我想一种方法是,保留原始和修改后的文本文件,识别修改后的文件中从原始文件更改的部分的字符范围,(1<<0)然后将该字符串输入某个计算器,然后将其替换为计算器的输出。然而, while(1<<0)可以被计算器解析,比如wcalc- 我怀疑许多常见的习语(1u<<32)可以被它解析,所以即使像这样的字符串也必须经过编译器,我猜,而 C 编译器不是 REPL,所以它不能“只是”为输入提供一个值,例如(1<<0)...

现在,我知道除了条件之外,C 预处理器不执行算术运算(C 预处理器可以执行整数算术吗?),所以也许我想要实现的目标对于 C 预处理器(可能还有编译器)来说是不可能的 - 如果这是那么,是否有其他工具可以帮助我在文本文件中实现用整数运算替换和扩展 C 宏?

Nat*_*dge 5

一种常见的方法是实际编译并执行代码,而不是仅仅对其进行预处理。有一个make_test.c包含以下内容的文件:

#include <stdio.h>
#include "curl/options.h"

int main(void) {
    printf("curlot flag alias is: %d\n", CURLOT_FLAG_ALIAS);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后让您的构建过程编译并执行该程序。

gcc -o make_test -I /usr/include make_test.c
./make_test
Run Code Online (Sandbox Code Playgroud)