我想对代码进行一些重构,尤其是文件之间的“包含”关系。它们中有很多,要开始使用,有一个列表,图表甚至是柱状图会很有帮助,这样我就可以一目了然地看到从哪里包含的内容。
(在许多情况下,给定文件包含多个其他文件,因此图形将是DAG,而不是树。没有周期。)
我正在使用TeX(实际上是ConTeXt),但问题似乎适用于任何具有类似于#include
的设施的编程语言。
明显,简单的答案是在相关关键字grep
,\usemodule
的所有.tex文件上执行\input
或“在文件中查找”,以及几个我们定义的其他宏)。这比没有好,但输出很长,而且仍然很难看到包含什么的模式。例如,文件A通常包含在文件B之前吗?文件C是否被同一个文件多次包含?
我想这会带来一个额外但可选的功能:这样的工具可以显示来自特定文件的包含的序列。因此,在这种情况下,DAG可以是一个多图,即从一个文件到另一个文件可能有多个弧。
理想情况下,能够为每个文件添加注释会很好,并简要概述其中的内容。这将构成该文件的图形节点上文本的一部分。
可能这种事情可以通过生成graphviz点语言的脚本来完成。但我想知道它是否已经完成,而不是重新发明轮子。
答案 0 :(得分:2)
正如我国现在星期五那样,我正等着同事去喝啤酒,我以为我会做一些编程。
这里http://www.stud.fit.vutbr.cz/~xpolok00/proj/IncludeGraph.zip您可以下载一个非常简单的实用程序的源代码,该实用程序在一个文件夹中查找所有文件,解析#includes并为其生成.dot文件。
它支持并正确处理相对路径,并且可以在Windows上运行,也可以在linux上运行。它以非常简洁的方式写成。我的dot版本没有解析生成的文件,有一些bug,但我现在真的需要去喝酒,看看你是否可以修复它。我不是常规的点用户,我没有看到它,虽然我确定它非常明显。
享受......
PS - 如果您在编译和/或运行时遇到问题,请告诉我。感谢。
修改强>
好的,我的不好,linux上有一些小问题。点问题是它使用“图形”而不是“有向图”。但现在它的魅力就像魅力一样。这是link。只需键入make,如果是这样,make test应生成程序本身的以下图表:
它忽略了C ++文件中的预处理程序指令,因此它对它没有直接影响(可以通过简单地使用预处理器输出标志调用g ++并处理而不是实际文件来修复)。我今天没有进入正则表达式,但如果您有任何编程经验,您会发现修改DotGraph.cpp并不是很难对包含令牌进行硬编码,也不会更改文件扩展名列表。明天可能会得到正则表达式。
答案 1 :(得分:1)
一个聪明而通用的解决方案是跟踪构建系统(使用类似strace,LD_PRELOAD,修补二进制文件或其他一些调试工具)。
一旦你收集了文件打开/关闭操作的序列,你只需要过滤掉不感兴趣的东西,只要以下假设成立,就应该很容易为任何语言构建依赖树:
不幸的是,编写良好或写得不好的编译器可能会违反这些假设,例如仅在第一次包含文件时打开文件,或者从不关闭任何文件。
也许是因为这些限制,我不知道这个想法的任何实现。
另一方面,聪明的构建系统可能包括自己计算或提取依赖项的功能。 gcc有-M
选项输出依赖关系,javac自己计算出依赖关系(虽然我不知道如何输出它们)。
就TeX而言,我不知道足够的TeX实际实现这一点,但从概念上看,似乎应该可以重新定义低级别包含命令:
然后,您可以从日志输出中构建树。