KEIL 添加格式化 批量格式化

在写代码时,通常都离不开格式化更具。运用格式化工具能使我们的代码更加的美观。

然而KEIL 没有内置格式化工具。因此我们需要自己为其添加格式化工具。之前我使用的是 AStyle ,效果还不错,网上一般也是建议使用这个工具。

但是本人更加钟爱 vscodeC/C++ 格式化工具:clang-format 。这个工具可配置性更高,格式化出来的效果比 AStyle 好。

比如变量定义初始化时,可以等号对齐,宏定义时,可以宏定义对齐。注释也支持对齐。显然,这样格式化出来的代码更加美观。

在这里插入图片描述
在这里插入图片描述
直接将宏定义的代码块转换函数格式,这个功能简直不要太好。
在这里插入图片描述

使用教程:

1. 使用 clang-format

直接去官网下载。因为我vscode里面下载了这个插件的。因此直接在vscode插件目录下找到这个软件。

C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin

执行:

.\clang-format.exe -style=LLVM -i main.cpp 

即可对 main.cpp 进行格式化。

通过以下命令,可以导出默认配置,通过修改配置,可以实现我们自定义格式化效果。

.\clang-format.exe  -style=llvm -dump-config > .clang-format

将配置输出到 .clang-format 中。上面的命令如果是在 powershell中运行的话,会导致输出编码格式不正确,需要将文件转成UTF-8 编码格式。建议使用CMD。

使用配置,则通过以下方式:

.\clang-format.exe -style=file .\.clang-format -i main.cpp

即可使用我们修改过的配置文件。上面的命令如果是在powershell中运行的话,clang-format.exe读取file后,会导致file文件格式混乱,从而无法再此使用。因此,我们每次都需要建立一个file的副本,来确保powershell运行这个命令不会出错。建议使用CMD。

默认导出的配置还达不到vscode的默认效果,因此需要进行修改。
将缩进设置为4个字符,并且将 {} 设置为前后换行。这是我比较喜欢的配置,代码更加清晰。
然后还有变量初始化对齐和宏定义对齐,不允许小块代码写在一行。

AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveBitFields: true
AlignConsecutiveDeclarations: true
AllowShortFunctionsOnASingleLine: false
IndentWidth:     4
BreakBeforeBraces: Allman

简单配置即可达到图片的效果。

2. KEIL 配置格式化工具

在KEIL 中配置格式化工具。
在这里插入图片描述

这里将Comand设置为格式化工具路径。然后Arguments设置为 -style=file C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\.clang-format -i !E 。这个设置表示,使用配置文件格式来 格式化当前文件,即编辑器的当前文件。

在这里插入图片描述

当需要格式化整个文件夹的文件时,按如下配置。按理来说,比如 AStyle 会在Arguments里面配置 $E*.c $E*.h 。由于 clang-format 的bug,这样设置会导致报错。因为这两个模糊输入是在同一个文件夹,因此设置为 -i "$E*.c" ,只格式化目录下的所有 .c 文件。

当然Arguments参数前面还是加上我们自定义的格式配置文件 -style=file C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\.clang-format。即再 -i 前面补上这个参数。
在这里插入图片描述
当格式化所有 *.c 文件时,任然存在bug。bug表现为:当工作目录和需要格式化的文件不在同一个目录时,格式化的配置参数会部分失效。比如我软件运行在.\test\diraa\ 下,但是文件在 .\test\dirbb\ 会导致宏定义格式化不对其。当软件运行目录也在 .\testdirbb\ 下时,格式化是正常的。因此这里配置了,任然到不到完美的效果。

所以我对 clang-format 进行了功能扩充修改。当输入为目录时,我们直接切换工作路径,然后格式化这个路径下的所有 .c 和 .h 文件,来解决上面提出的两个bug。源代码附于文章末尾。

因此,只需要将KEIL,进行如下配置,即可完美格式化。Command配置为:

C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\clang_format_custom.exe

在这里插入图片描述

或者这样:
在这里插入图片描述

但是抽风的KEIL参数,还是会导致bug。
如果以上面的参数设置,会得到一个路径,但是KEIL在处理路径时,直接字符串参数传给命令行,这时最后一个"将变成\",好了,这将导致一个错误。因此需要将 "$E" 修改为 "$E\" 。或者直接去掉 "" 即可。

但是这还没完,程序运行任然报错。上面两个不同的设置将导致不同的错误,我也是非常的郁闷。但是格式化结果是完美的,因此忽略这个错误了。这里的 invalid argument 错误应该是KEIL报告的。从第一行的命令来看,格式是没有任何问题的。

C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\clang_format_custom.exe -i "E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\\"
invalid argument
-i
E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\
full_path: C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\clang-format.exe -i E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\
format_file: C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\.clang-format
work path: E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\
C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\clang_format_custom.exe -i E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\
invalid argument
-i
E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\
full_path: C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\clang-format.exe -i E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\
format_file: C:\Users\28328\.vscode\extensions\ms-vscode.cpptools-1.3.1\LLVM\bin\.clang-format
work path: E:\Projects\2020\Railway_Finder\Finder_terminal\Railway_Finder\examples\ble_peripheral\Railway_Finder_terminal\pca10040e\s112\user_app_src\

可以修改源码来解决上报面的报错。不过既然格式没有问题了,我也不管KEIL参数的bug了。

另外很重要的一点。KEIL支持对配置的tool设置快捷键,这样,我们可以通过设置 shift + alt + F 来实现和vscode一样的快捷键格式化,完美。

在这里插入图片描述

源码如下,格式配置参见gitee。(下面的代码就是通过格式化工具格式的):

#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <windows.h>

#define TOOL_PATH_LEN 1024
#define FULL_PATH_LEN 16384
#define LOG_INFO(...) printf(__VA_ARGS__)

char tool_path[FULL_PATH_LEN] = "C:\\Users\\28328\\.vscode\\extensions\\ms-vscode.cpptools-1.3.1\\LLVM\\bin\\";
char tool_name[128]           = "clang-format.exe";
char format_file_name[]       = ".clang-format";

static int path_index = 0;

static int   get_format_file(char *file_path);
static int   rm_format_file(void);
static int   hj_copy_file(char *old_file, char *new_file);
static _Bool is_dir(char *name);

int main(int argv, char *argc[])
{
    char full_path[FULL_PATH_LEN]   = {0};
    char format_file[TOOL_PATH_LEN] = {0};

    memcpy(full_path, tool_path, TOOL_PATH_LEN);
    memcpy(format_file, tool_path, TOOL_PATH_LEN);

    strncat(full_path, tool_name, FULL_PATH_LEN - strlen(tool_path));

    strncat(format_file, format_file_name, TOOL_PATH_LEN - strlen(tool_path));

    for (int i = 1; i < argv; i++)
    {
        LOG_INFO("%s\n", argc[i]);
        strncat(full_path, " ", FULL_PATH_LEN - strlen(tool_path));
        strncat(full_path, argc[i], FULL_PATH_LEN - strlen(tool_path));

        if (0 == strncmp(argc[i], "-i", 2))
        {
            path_index = i + 1;
        }
    }

    LOG_INFO("full_path: %s\n", full_path);
    LOG_INFO("format_file: %s\n", format_file);

    /* 格式化目录下的所有.c .h 文件 */
    if (is_dir(argc[path_index]))
    {
        char work_path[256] = {0};
        strcat(work_path, argc[path_index]);

        if (work_path[strlen(work_path) - 1] != '\\')
        {
            strcat(work_path, "\\");
        }

        LOG_INFO("work path: %s\n", work_path);
        int ret = chdir(work_path);
        if (ret)
        {
            LOG_INFO("%s:%d: chdir error: %d\n", __func__, __LINE__, ret);
            return 0;
        }

        char temp[FULL_PATH_LEN] = {0};
        memcpy(temp, full_path, FULL_PATH_LEN);
        strcat(temp, "*.c");

        get_format_file(format_file);
        system(temp);
        rm_format_file();

        memcpy(temp, full_path, FULL_PATH_LEN);
        strcat(temp, "*.h");

        get_format_file(format_file);
        system(temp);
        rm_format_file();
    }
    else
    {/* 格式化单个文件 */
        get_format_file(format_file);
        system(full_path);
        rm_format_file();
    }

    return 0;
}

static int get_format_file(char *file_path)
{
    int ret = hj_copy_file(file_path, format_file_name);
    if (ret)
    {
        LOG_INFO("%s:%d: copy file error: %d\n", __func__, __LINE__, ret);
        return ret;
    }

    return ret;
}

static int rm_format_file(void)
{
    uint32_t ret = remove(format_file_name);
    if (ret)
    {
        LOG_INFO("%s:%d: remove format file error: %d\n", __func__, __LINE__, ret);
    }

    return ret;
}

static int hj_copy_file(char *old_file, char *new_file)
{
    if (!old_file || !new_file)
    {
        return 1;
    }
#define BUFFER_LEN 16384

    FILE *fp                 = NULL;
    FILE *fp_out             = NULL;
    char  buffer[BUFFER_LEN] = {0};
    int   ret                = 0;

    fp = fopen(old_file, "rb");
    if (!fp)
    {
        LOG_INFO("%s:%d: open file error.\n", __func__, __LINE__);
        return 2;
    }

    ret = fread(buffer, sizeof(char), BUFFER_LEN, fp);
    if (ret <= 0)
    {
        LOG_INFO("%s:%d: read file error.\n", __func__, __LINE__);
        return 3;
    }

    fclose(fp);

    fp_out = fopen(new_file, "wb");
    if (!fp_out)
    {
        LOG_INFO("%s:%d: open file error.\n", __func__, __LINE__);
        return 4;
    }

    ret = fwrite(buffer, sizeof(char), ret, fp_out);
    if (ret <= 0)
    {
        LOG_INFO("%s:%d: write file error.\n", __func__, __LINE__);
        return 5;
    }

    fclose(fp_out);

    return 0;
}

static _Bool is_dir(char *name)
{
    struct _stat buf;
    int          result = 0;
    result              = _stat(name, &buf);
    if (_S_IFDIR & buf.st_mode)
    {
        return TRUE;
    }
    else if (_S_IFREG & buf.st_mode)
    {
        return FALSE;
    }
}
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Keil5是一款广泛用于嵌入式系统开发的集成开发环境(IDE),实现了从编码、编译到调试和仿真等一系列开发步骤的集成化。Keil5支持多种编程语言,包括C语言和汇编语言,并具有丰富的代码编辑和调试功能。 在Keil5中,格式化代码是一项非常重要的工作,它可以使代码结构清晰、易读,方便开发人员理解和维护代码。Keil5提供了方便快捷的代码格式化工具,可以帮助开发人员自动调整代码的缩进、空格、换行等格式。 要下载Keil5的代码格式化工具,可以按以下步骤进行操作: 1. 首先,进入Keil官方网站(www.keil.com)。 2. 在网站的导航栏中找到"Downloads"(下载)选项,点击进入下载页面。 3. 在下载页面中,可以根据自己的需求选择合适版本的Keil5软件进行下载。确保选择的版本支持代码格式化功能。 4. 下载完成后,运行安装程序并按照指示完成软件的安装过程。 5. 安装完成后,打开Keil5软件。 6. 在Keil5的菜单栏中找到"Edit"(编辑)选项,并点击下拉菜单中的"Format Code"(格式化代码)选项。 7. 弹出的代码格式化对话框中,可以设置代码的缩进、空格和换行等格式化选项。 8. 根据自己的需求,调整格式化选项,并点击确认按钮。 9. Keil5将自动根据设置的格式化选项对打开的代码进行格式化调整。 通过以上步骤,你就可以下载并使用Keil5的代码格式化工具了。记得根据实际需要选择合适的Keil5版本,并在安装和使用时仔细遵循相应的操作指导。祝你顺利使用Keil5进行嵌入式系统开发!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值