将C Callergraph与Doxygen合并或确定所有呼叫的并集

And*_*ent 4 refactoring code-analysis doxygen graphviz call-graph

我有一个遗留的C代码集合,我正在重构,以便从GUI中分离出C计算代码.由于重度递归的数学核心代码是K&R样式声明,这很复杂.由于嵌套使用了函数参数,我已经放弃了将这些转换为ANSI声明的尝试(只是无法获得最后4个编译器错误).

我需要将一些文件移动到一个纯DLL中,并确定要公开的最小接口,这需要编写包装函数来发布一个类型化的接口.

我已经使用Doxygen @callergraph标记标记了关键源文件,因此为各个函数生成了信息图.除此之外我想做的是合并这些图,这样我就可以确定暴露于外部世界的最窄函数边界.

原始头文件没有用 - 它们将所有内容公开为非类型化C函数.

有数百个函数如此简单地检查生成的调用程序图是很痛苦的.

我正在考虑编写某种DOT合并工具 - 设置DOT_CLEANUP = NO使Doxygen离开中间的DOT文件而不是保留他们生成的png文件.

我并不痴迷于这是一个图形解决方案 - 如果有人能够建议使用Doxygen的XML输出来实现相同目标的替代分析工具(免费或相对便宜)或技术,我会很高兴.

在文件级别合并的调用图确实对客户端文档有一定的吸引力,而不是简单的列表:-)

Har*_*d L 5

在你的Doxyfile中,设置

GENERATE_XML = YES
Run Code Online (Sandbox Code Playgroud)

然后你可以在XML文件中找到你的调用图.对于使用调用者图标记的每个函数,您将<referencedby>在输出中找到可以使用的元素.这是我的一个C文件中的示例:

  <memberdef kind="function" id="spfs_8c_1a3"
             prot="public" static="yes" const="no" explicit="no"
             inline="no" virt="non-virtual">
    <type>svn_error_t *</type>
    <definition>svn_error_t * init_apr</definition>
    <argsstring>(apr_pool_t **ppool, int *argc, char const *const **argv)</argsstring>
    <name>init_apr</name>
    <!-- param and description elements clipped for brevity ... -->
    <location file="src/spfs.c" line="26" bodystart="101" bodyend="120"/>
    <referencedby refid="spfs_8c_1a13" compoundref="spfs_8c"
                  startline="45" endline="94">main</referencedby>
  </memberdef>
Run Code Online (Sandbox Code Playgroud)

因此,对于每个memberdef/referencedby对,您都有一个调用者 - 被调用者关系,您可以通过XSLT获取:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="text"/>

    <xsl:template match="/">
        <xsl:apply-templates select="//memberdef[@kind eq 'function']"/>
    </xsl:template>

    <xsl:template match="memberdef">
        <xsl:variable name="function-name"
                      select="concat(definition, argsstring)"/>
        <xsl:for-each select="referencedby">
            <xsl:value-of select="concat(./text(), ' calls ', $function-name, '&#xA;')"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

这给你一个每个来电者 - 被调用者一行,如下所示:

main calls svn_error_t * init_apr(apr_pool_t **ppool, int *argc, char const *const **argv)
Run Code Online (Sandbox Code Playgroud)

您需要调整XSLT,然后以切割最少边缘的方式对有向图进行分区.呜呜,NP完全问题!幸运的是,有很多关于这个主题的论文,有些是在这里:http://www.sandia.gov/~bahendr/partitioning.html