有没有工具来保持我的C源文件的顺序?

时间:2010-07-31 14:29:47

标签: c header-files

我有一些缓慢扩展的C源文件。我倾向于将原型与.h文件中的文档保持良好的顺序,并使用#pragma mark分组为相关的函数和类型。代码的编写和记录方式需要在.h文件旁边读取.c文件。我希望以一种方便的方式订购文件。

有没有办法让.c文件中的函数声明与.h文件中的原型保持相同的顺序?我正在寻找一个工具来阅读.h文件(如果可能的话#pragma mark)并相应地重新排序.c文件。

可能的?

3 个答案:

答案 0 :(得分:1)

之前我已经完成了代码粉碎。 你能得到的最接近的是写一个(据我所知)。使用静态分析API,您可以解析源代码,然后根据每个头文件中的代码组织相应的.c文件中的所有文件。

一家名为SciTools的公司发布了一个名为'understand 4 c ++'的源代码分析器,该分析器具有一个C API,使这很容易。但您可能必须自己编写该工具。实际上,我编写了一个位于其C API之上的托管API。我的托管服务在codeplex上找到:http://understandapi.codeplex.com/

以下是我将如何构建程序。

  1. 首先,您必须创建所有源代码的数据库。您可以根据需要使用批处理脚本或PowerShell脚本执行此操作,也可以自己手动执行此操作。它通常就像指向一个目录一样简单,实际上就是说“制作一个包含所有文件的数据库”。您可以确定数据库中是否需要* .c,*。h或* .cpp文件。

  2. 然后使用API​​,您可以浏览.h文件扩展名的所有文件。

  3. 对于每个头文件,验证是否存在相应的.c文件。这是通过获取文件名的字符串,替换文件扩展名(.NET使这很容易),并检查文件是否存在来完成的。如果确实存在,则继续下一步。

  4. 然后程序应该迭代.h文件中的所有已定义实体。

  5. 对于每个实体,它然后找到对它的定义(不是声明)的引用,并查看它是否存在于相应的.c文件中。如果它在那里,它会找到代码定义的行号,并打开文件进行读取,并读取必要的代码行(以及注释)并将它们写入临时文件。

  6. 完成后,使用临时文件覆盖.c文件。

  7. 继续执行数据库中的其余文件。

  8. 现在不是那么容易。您可能会遇到以下形式遇到麻烦: 1.有条件地编译代码,在这种情况下,它将使解析更难,尽管它是可能的。理解4 c ++确实解析条件编译指令并区分非活动代码和活动代码。但是处理这个问题会让事情变得非常困难。 2.命名空间 - 这会使问题复杂化。

    但是,如果您只对在某些#pragma指令之间组织代码感兴趣,那么它可能会再次简化问题。

    如果您对此感兴趣,请告诉我,我们会私下离线谈谈。

答案 1 :(得分:1)

  • 使用一个好的IDE ...不需要保持头文件/ c文件中的顺序对齐。

  • 如果仍然不适合你...保留所有声明和定义 按字母顺序。添加新功能时,您知道在哪里插入 新功能。

    P.S。我相信http://www.dmoz.org/说::

      Humans Do it better
    

答案 2 :(得分:1)

我怀疑你会找到这样一个现成的工具。所以,你需要一个自定义工具。你没有 想要尝试使用一些字符串黑客方法(例如,Perl),因为准确的细节 解析C和C ++远远超出了你可以这样做的可靠性。如果你不介意的话 字符串黑客有时会破坏你的文件,也许你可以逃脱这个。

我公司的DMS Software Reengineering Toolkit可以用来可靠地模拟警告。

DMS是使用由显式语言定义参数化的编译器技术来解析,分析和转换源代码的通用引擎。 DMS为许多语言提供了强大的语言定义, 包括各种方言的C和C ++。使用DMS C或C ++前端,您可以解析源代码 代码,构建称为AST的编译器数据结构,对代码进行分析,转换AST, 然后重新生成可编译的代码,包括注释和所有预处理器指令。

警告与解析包含预处理器指令的源代码有关: 他们必须结构良好[例如。 #ifdef #endif需要像常规一样嵌套在其他语句周围 if等等,而不是在语句边界使用。这在C代码中发生了一些;许多 更少的C ++代码。我们的经验是,如果您愿意稍微修改您的C代码, 你可以让这个问题消失。

对于您的具体任务,您几乎就像Scientific Toolworks所描述的那样:

  1. 选择一个编译单元,并使用DMS进行解析。您必须提供所有相同的信息   你提供编译器,所以它可以找到头文件等。
  2. DMS为您的编译单元和所有头文件生成AST。
  3. 遍历AST以提取标题和编译单元中的声明顺序。
  4. 根据从3)
  5. 派生的顺序重构编译单元树
  6. Prettyprint生成的编译单元AST
  7. [使用DMS而非Scientific Toolworks执行此操作的原因是DMS旨在实现 解析/转换/重新生成代码,而SciTool IMHO实际上只是为解析而设计的 并分析。 DMS提供对转换所需的精细细节的访问 SciTools没有,至少不是我最后一次看。]

    由于条件,宏,名称空间等原因会产生并发症,但您将决定策略 解决。例如,如果头文件有#if ... #else .... #endif和声明 在then子句中有一个不同于else子句中的顺序,所需的顺序是什么? 如果函数定义是由标头中的宏创建的,该怎么办?但是,所有这一切都是成功的 建立一个真正的工具,呃,好玩。

    我个人认为,对于你所获得的效果来说,这似乎是相当多的工作。如果你 做到这一切,你的软件工程过程会有多好?我们通常使用DMS 检查编码错误,或以人们不能的方式更改代码(例如,插入运行时检测 暂时或类似AOP的建议),明确表示机械发动机有回报。