【问题标题】:Expand pragma to a comment (for doxygen)将 pragma 扩展为评论(对于 doxygen)
【发布时间】:2018-09-27 13:43:06
【问题描述】:

注释通常在预处理器运行之前转换为单个空格。但是,有一个引人注目的用例。

#pragma once   

#ifdef DOXYGEN
  #define DALT(t,f) t
#else
  #define DALT(t,f) f
#endif

#define MAP(n,a,d) \
  DALT ( COMMENT(| n | a | d |) \
       , void* mm_##n = a \
       )

/// Memory map table
/// | name | address | description |
/// |------|---------|-------------|
MAP (reg0  , 0       , foo         )
MAP (reg1  , 8       , bar         )

在本例中,当设置了DOXYGEN 标志时,我想从宏生成 doxygen 标记。如果不是,我想生成变量。在这种情况下,所需的行为是在宏中生成 cmets。有什么想法吗?

我已经尝试过/##/ 和另一个具有更多间接性的示例

#define COMMENT SLASH(/)
#define SLASH(s) /##s

都不行。

【问题讨论】:

  • 如果预处理器会生成 cmets,这些在编译前不会被删除。它会失败。
  • Doxygen 不会预处理文件,对吧,所以它不会看到你的宏生成的 cmets。
  • DALT 定义是否正确,看起来像是参数('t' 和 'f')的混合,但可能不是这里的问题。
  • ///**/ 都不是有效的预处理令牌,因此它们不能由 ## 运算符创建。考虑 3 行源代码:#define CAT(x,y) x##yCAT(/,/) CommentCAT(/,*) Comment CAT(*,/) — 预处理器 witts error: pasting "/" and "/" does not give a valid preprocessing token(其他组合也类似)。如果 Doxygen 不允许这样做——据我所知,它可能不只是运行普通的 C 预处理器(因为这会去掉所有的 cmets)——那么你就被卡住了。考虑一个单独的代码/注释生成阶段。
  • 不需要预先运行文档,您可以在 doxygen 中将其作为 INPUT_FILTER 执行(参见 Doxyfile)。

标签: c c-preprocessor doxygen


【解决方案1】:

在 doxygen 中,可以在源代码输入 doxygen 内核之前在源代码上运行命令。在 Doxyfile 中有一些 FILTER 可能性。在这种情况下:INPUT_FILTER 该行应为:

INPUT_FILTER = "sed -e 's%^ *MAP *(\([^,]*\),\([^,]*\),\([^)]*\))%/// | \1 | \2 | \3 |%'"

此外,整个 #if 结构可能会消失,并且可能只需要:

#define MAP(n,a,d) void* mm_##n = a

【讨论】:

    【解决方案2】:

    ISO C 标准将预处理器的输出描述为 预处理标记 流,而不是文本。评论不是预处理标记;在标记化发生之前,它们会从输入中删除。因此,在该语言的标准设施内,预处理输出基本上不可能包含 cmets 或任何类似的内容。

    特别是考虑

    #define EMPTY
    #define NOT_A_COMMENT_1(text) /EMPTY/EMPTY/ text
    #define NOT_A_COMMENT_2(text) / / / text
    NOT_A_COMMENT_1(word word word)
    NOT_A_COMMENT_2(word word word)
    

    翻译阶段4之后,上面的第四行和第五行都会变成六记号序列

    [/][/][/][word][word][word]
    

    其中方括号表示标记边界。没有任何诸如// 令牌之类的东西,因此您无法让预处理器生成一个。

    现在,ISO C 标准没有指定 doxygen 的行为。但是,如果 doxygen 正在重用某人的 C 编译器附带的预处理器,那么编写该预处理器的人可能认为文本预处理器输出首先应该是“适当的编译器”将接收的标记序列的准确反映。这意味着它将在必要时强制插入空格以使单独的标记保持分开。比如上面的例子test.c

    $ gcc -E test.c
    ...
    / / / word word word
    / / / word word word
    

    (我在我们感兴趣的输出上方省略了一些不相关的闲聊。)

    如果有办法解决这个问题,您最有可能在 doxygen 手册中找到它。例如,可能有一些配置选项告诉它应该理解某些宏来定义符号,这些是什么符号,它们应该有什么文档。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多