将内联注释的格式从//更改为/ * * /

时间:2019-05-14 07:23:17

标签: regex sed

我有一个C文件,其中包含多个以//。开头的内联注释。
例如,

    u32 Status;                                                              

    // Read foo peripherals status                                   
    Status =  foo_periph_status(foo_Instance);

    // Check if foo is ready to turn right                                  
    if ((Status) & (FOO_STATUS_TURN_RIGHT_MASK)) {                          

        // Get FOO current state                                            
        foo_Instance->CurrentState = Foo_GetCurrentState(incoming_data);

        // Get FOO format                                                   
        foo_Instance->CurrentState.metadata.Format = Foo_GetFormat(incoming_data)  

在上面的代码中,我想将所有// inline comments从其当前格式更改为/* Inline comments */格式。

我曾经尝试过,
s/\([^.*]\)\(\/\/\)\(.*\)\($\)/\1\/\*\3 \*\//
现在对我有用。

我想知道是否有更好的方法?

1 个答案:

答案 0 :(得分:4)

#include <stddef.h>
#include <stdio.h>
#include <string.h>


#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define ARRAY_SSIZE(arr) ((ptrdiff_t)ARRAY_SIZE(arr))


// Read line from file
fgets(buff, BUFSIZ, fp_r);

// Find "//" comment
p = strstr(buff, "//");
if (!p)
        continue;

// If comment is at the very end of the buffer, and wouldn't fit, remove it.
if ((p - &buff[0] + strlen("/**/\n") + 1) > ARRAY_SSIZE(buff)) {
        sprintf(p, "\n");
        continue;
}

// Remove "*/" that would break the new comment format
do {
        q = strstr(p, "*/");
        if (q)
                memmove(q, q + strlen("*/"), strlen(q + strlen("*/")) + 1);
} while (q);

// Write the new comment begining
sprintf(p, "/*");

// Find end of line
p = strrchr(buff, '\n');

// Check that the closing "*/" fits in the buffer
while ((p - &buff[0] + strlen("*/\n") + 1) > ARRAY_SSIZE(buff))
        p--;

// Write closing "*/"
sprintf(p, "*/\n");

// Write line to file
fputs(buff, fp_w);

这将修复一行。您只需要添加代码即可遍历整个文件。您需要打开两个文件:正在读取的文件(fp_r)和一个新文件(fp_w)。您必须先删除旧文件,然后删除第一个文件,然后使用相同的名称重命名新文件,以使结果被覆盖。

这将删除*/之后//的所有出现。

问题:

  • 它将不会处理以“ /**/”格式编写注释并且注释中包含//的情况,因为这不太可能且难以解决(请参见以下示例)。如果发生这种情况,结果可能是无效的注释。 例子:
a = 7; /* // this will mess everything */
a = /*7*/b; /* // hello, this too */ c=a; // another comment

这是一行,而且已经很复杂。试想在多行注释中处理它...

  • 如果在字符串文字中找到//,则会发生与上述相同的情况。它也有类似的困难,而且可能性也不大,所以我不会去解决它。如果您需要它,则取决于您:)。结果也将是无效代码 (感谢@EdMorton发现了这一点。)

  • 如果注释太长以至于在缓冲区末尾结束,它将截断一行。但是,结果注释将是有效的。

针对这些问题的建议:

在实际将其写入文件之前,如果在要修改的行中检测到/**/"时提示用户,请向用户显示原始内容和修改内容(您需要保留原始行的副本),然后让他决定是喜欢旧行还是新行。并且在完成大部分工作后,让用户手动修改这些行;-)

多行注释(或多行字符串文字,bot是独角兽)的问题仍然存在,但也许您可以在其中找到另一种模式,例如, *行的开头。无论如何,代码不会是无效的。注释中只会发生一些不需要的更改。

另一种解决方案可能是在每次更改时提示用户。