有没有一个工具可以让我的 C 源文件保持有序?

发布于 2024-09-12 19:12:04 字数 358 浏览 4 评论 0原文

我有一些正在慢慢扩展的 C 源文件。我倾向于将原型和文档按顺序保存在 .h 文件中,并使用 #pragma mark 将其分组为相关函数和类型。代码的编写和记录方式需要同时读取 .h 文件和 .c 文件。我希望以有利于此的方式对文件进行排序。

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

可能的?

I have some C source files that are slowly expanding. I tend to keep the prototypes with documentation in the .h file in good order, grouped into relevant functions and types with #pragma mark. The code is written and documented in a way that requires reading the .h file alongside the .c file. I'd like the files to be ordered in a way that facilitates this.

Is there a way to keep the function declarations in the .c file in the same order as their prototypes in the .h file? I'm looking for a tool to read the .h file (with #pragma marks if possible) and re-order the .c file correspondingly.

Possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寄人书 2024-09-19 19:12:04

我以前做过代码粉碎。
你能得到的最接近的东西就是写一个(据我所知)。使用静态分析 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. 继续处理数据库中的其余文件。

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

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

如果您有更多兴趣,请告诉我,我们可以私下线下交谈。

I've done code shredding before.
The closest thing you could get is to write one (As far as I know). Using a static analysis API, you could parse your source code, and then based off on the code in each header file organize all files in a corresponding .c file.

A company called SciTools ships a source code analyzer called 'understand 4 c++' that has a C API that makes this pretty easy. But you would probably have to write the tool yourself. As it is, I wrote a managed API that sits on top of their C API. My managed is found on codeplex here: http://understandapi.codeplex.com/

Here is how I would structure the program.

  1. First you have to create a database of all your source code. You can do this using a batch script if you want, or a powershell script, or you can manually do it yourself. It's usually as simple as pointing to a directory and in effect saying 'make a database of all the files in there'. You can determine if you want *.c, *.h, or *.cpp files in your database.

  2. Then using the API you can browse all files with the .h file extension.

  3. For each header file, you verify there is a corresponding .c file. This is done by taking a string of the filename, replacing the file extension (.NET makes this easy), and checking if the file exists. If it does exist, then on to the next step.

  4. Then the program should iterate through all defined entities in the .h file.

  5. For each entity, it then finds a reference to it's definition (not declaration), and see's if it exists in the corresponding .c file. If it's there, it finds the line numbers of the code definition, and opens the file for reading, and reads the necessary lines of code (and comments too) and writes them out to a temporary file.

  6. When completed, overwrite the .c file with the temporary file.

  7. Proceed to the rest of the files in the database.

Now it's not that easy. You may run into trouble along the way in the form of:
1. Conditionally compiled code, in which case it will make it harder to parse, though it's possible. Understand 4 c++ does parse conditional compilation directives and differentiates between inactive and active code. But just handling this would make it really difficult.
2. Namespaces - This would complicate matters.

However if you are only interested in organizing code between certain #pragma directives than it could simplify matters again.

Let me know if you are interested more, and we an talk offline privately.

定格我的天空 2024-09-19 19:12:04
  • 使用一个好的IDE...不需要保持头文件/c文件中的顺序对齐。

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

    PS 我相信http://www.dmoz.org/ 的说法::

     人类做得更好
    
  • Use a good IDE... There will not be any need to keep the order in header file/c file aligned.

  • If that still does not suite you... Keep all declarations and definitions in
    alphabetical order. When you add a new function, you know where to insert the
    new function.

    P.S. I believe in the http://www.dmoz.org/ saying::

      Humans Do it better
    
青衫负雪 2024-09-19 19:12:04

我怀疑您是否会找到这样的现成工具。因此,您需要一个自定义工具。你不
想要尝试使用一些字符串黑客方法(例如 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 对其进行解析。您必须提供所有相同的信息
    您提供编译器,因此它可以找到头文件等。DMS
  2. 为您的编译单元和所有头文件生成 AST。
  3. 遍历 AST 以提取标头和编译单元中声明的顺序。
  4. 根据 3)
  5. Prettyprint 生成的编译单元 AST 的

顺序重构编译单元树[使用 DMS 而不是 Scientific Toolworks 执行此操作的原因是 DMS 旨在
解析/转换/重新生成代码,而 SciTool IMHO 实际上仅设计用于解析
并分析。 DMS 提供对转换所需的详细信息的访问,
SciTools 没有,至少我上次查看时没有]。

由于条件、宏、命名空间等,复杂性会随之而来,但你将决定策略
以获得解决方案。例如,如果头文件有 #if ... #else .... #endif 和声明
then 子句中的顺序与 else 子句中的顺序不同,所需的顺序是什么?
如果函数定义是由标头中的宏创建的怎么办?但是,这一切都使得
构建一个真正的工具,呃,很有趣。

我个人的观点是,为了达到您所获得的效果,这似乎需要做很多工作。如果你
完成所有这些,您的软件工程流程会好多少?我们通常使用DMS
检查编码错误,或者以人们无法做到的方式更改代码(例如,插入运行时检测
暂时或类似 AOP 的建议),很明显机械引擎有回报。

I doubt you'll find a tool like this off-the-shelf. So, you'd need a custom tool. You don't
want to try doing this with some string hacking method (e.g., Perl) because the details of accurately
parsing C and C++ are far beyond what you can reliably do this way. If you don't mind
string hacking damaging your files sometimes, maybe you can get away with this.

My company's DMS Software Reengineering Toolkit could be used to do this reliably modulo a caveat.

DMS is generic engine for parsing, analyzing, and transforming source code using compiler technology parameterized by explicit langauge definitions. DMS has robust langauge definitions for many languages,
including C and C++ in variety of dialects. Using the DMS C or C++ front ends, you can parse the source
code, build compiler data structures called ASTs, carry out analyses over the code, transform the ASTs,
and then regenerate compilable code including comments and all the prepreprocessor directives.

The caveat has to do with parsing source code containing preprocessor directives:
they have to be well-structured [eg. #ifdef #endif needs to nest around other statements just like regular
if, etc. as opposed to being used across a statement boundary. This happens some in C code; much
less in C++ code. Our experience is that if you are willing to modify your C code little bit,
you can make this particular issue go away.

For your specific task, you do pretty much as the answer for Scientific Toolworks described:

  1. Choose a compilation unit, and parse it using DMS. You have to provide all the same information
    you provide the compiler, so it can locate the header files, etc.
  2. DMS produces an AST for both your compilation unit and for all header files.
  3. Walk the ASTs to extract the order of declarations in the headers and the compilation unit.
  4. Restructure the compilation unit tree according to the order derived from 3)
  5. Prettyprint the resulting compilation unit AST

[A reason to do this with DMS rather than Scientific Toolworks is that DMS is designed to
parse/transform/regenerate code, whereas SciTool IMHO is really only designed to parse
and analyze. DMS provides access to the fine detail required for transformation that
SciTools does not, at least not the last time I looked].

Complications will ensue because of conditionals, macros, namespaces, ... but you'll have decide policy
for resolution. For instance, if a header file has a #if ... #else .... #endif, and declarations
in the then clause have a different order than they do in the else clause, what's the desired order?
What if a function definition is created by a macro in the header? But, all this is what makes
building a real tool, er, fun.

My personal opinion is this seems like rather a lot of work for the effect you are getting. If you
do all of this, how much better will your software engineering process be? We normally use DMS
to check for coding errors, or change the code in ways that people can't (e.g., insert runtime instrumentation
temporarily or AOP-like advice), where its clear that a mechanical engine has payoff.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文