简单“修正”了一下 AStyle 中的一个重复缩进的问题
GitHub 地址: https://github.com/wudicgi/astyle-modified
效果对比脚本: https://github.com/wudicgi/astyle-modified/tree/master/bin
修改后程序下载: https://github.com/wudicgi/astyle-modified/blob/master/bin/AStyle.exe

1. 发现问题

上周我在对 ffmpeg 的 transcoding.c 示例程序进行代码风格美化时,发现 AStyle 在很多处不需要改动的地方添加了额外的缩进:

// 处理前
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
        args, NULL, filter_graph);

// 处理后
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                args, NULL, filter_graph);

其实以前也遇到过这个问题,但这次出现得比较集中、比较多,就准备解决一下了。打开 AStyle 的 VS2017 项目进行调试,发现对于我使用的选项

indent=spaces=4
indent-after-parens
indent-continuation=2

AStyle 在遇到赋值运算符 '=' 时为后续行添加 2 级缩进,而当继续处理遇到左括号 '(' 时又添加了 2 级缩进,于是后续行就拥有了多余的 2 级缩进。

2. 修改问题

我使用了一个简单粗暴的方式进行修改,就是在 ASBeautifier 类的 registerContinuationIndent() 方法中添加一个条件判断,使它在已经因为 '=' 添加了后续行缩进的情况下,不再因为其后出现的第一个 '(' 再添加缩进。

void ASBeautifier::registerContinuationIndent(const string& line, int i, int spaceIndentCount_,
                                              int tabIncrementIn, int minIndent, bool updateParenStack)
{
    assert(>= -1);
    int remainingCharNum = line.length() - i;
    int nextNonWSChar = getNextProgramCharDistance(line, i);

    // if indent is around the last char in the line OR indent-after-paren is requested,
    // indent with the continuation indent
    if (nextNonWSChar == remainingCharNum || shouldIndentAfterParen)
    {
        // added by Wudi
        bool noDuplicatedIndentForFirstParen = updateParenStack // current indentation is for opening paren '('
                && !continuationIndentStack->empty()            // previously indented for an assignment '='
                && parenIndentStack->empty()                    // current '(' is the first opening paren needs to add indentation
                && (!= 0);                                    // current '(' must not be the first char, otherwise there is no '=' ahead

        int previousIndent = spaceIndentCount_;
        if (!continuationIndentStack->empty())
            previousIndent = continuationIndentStack->back();

        int currIndent = continuationIndent * indentLength + previousIndent;

        // added by Wudi
        if (noDuplicatedIndentForFirstParen) {
            currIndent = previousIndent;
        }

        if (currIndent > maxContinuationIndent && line[i] != '{')
            currIndent = indentLength * 2 + spaceIndentCount_;
        continuationIndentStack->emplace_back(currIndent);
        if (updateParenStack)
            parenIndentStack->emplace_back(previousIndent);
        return;
    }

    // ...

3. 修改前后效果对比

对代码

int ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
        args, NULL, filter_graph);

int (*enc_func_2)(AVCodecContext *, AVPacket *, const AVFrame *, int *) = (ifmt_ctx->streams[stream_index]->codecpar->codec_type ==
     AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;

ret = func(a, b, another_func(1, 2,
                3),
        c, d);

进行代码风格美化时,原版 AStyle 的输出为:

int ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                args, NULL, filter_graph);

int (*enc_func_2)(AVCodecContext *, AVPacket *, const AVFrame *, int *) = (ifmt_ctx->streams[stream_index]->codecpar->codec_type ==
                AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;

ret = func(a, b, another_func(1, 2,
                        3),
                c, d);

修改后版本的输出为:

int ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
        args, NULL, filter_graph);

int (*enc_func_2)(AVCodecContext *, AVPacket *, const AVFrame *, int *) = (ifmt_ctx->streams[stream_index]->codecpar->codec_type ==
        AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;

ret = func(a, b, another_func(1, 2,
                3),
        c, d);

4. 修改的副作用

标题中的“修正”带引号是因为这并不一定是个 bug, 同时现在所做的这个修改会有一些副作用。对于一些极端情况的代码,例如:

int ret = func(a, b, another_func(1, 2,
3, 4, 5),
c, d)
/ 123;

原版 AStyle 能保留所有缩进等级,输出结果为:

int ret = func(a, b, another_func(1, 2,
                        3, 4, 5),
                c, d)
        / 123;

而该修改版本的输出为:

int ret = func(a, b, another_func(1, 2,
                3, 4, 5),
        c, d)
        / 123;

最外层在缩进等级上没有与内层区分开来。但像这样的代码并不常见,所以为方便自己日常使用,“修正”一下还是有必要的。

附: AStyle 原版链接

AStyle 的官方项目地址为 http://astyle.sourceforge.net/
Current language: 中文 (简体)
Released an open source clipboard utility - Clipboard Auto Processor
View on GitHub: https://github.com/wudicgi/clipboard-auto-processor

Here are the readme contents:

1. Introduction

Clipboard Auto Processor is a utility to process the text in clipboard automatically. Unlike other clipboard enhancement softwares which could only manage the history contents, this tool can execute any script to process the content automatically.



The script can be written in any language that you are familiar with, such as PHP, Python or JavaScript. It only needs to implement the conversion from original text to desired result. Other works will be all done by Clipboard Auto Processor.

2. Usage

Download the latest release version, and extract it to any location that have write permission. Generally any folder except Windows, Program Files and C drive root is OK.

When the ClipboardAutoProcessor.exe is running for the first time, it will create the config.ini file based on the current system language. And then you can edit this file to set script interpreter, display font and other options.

You can manually create the shortcut, and put it into start menu or on desktop. But it is more recommended to use a launcher, such as Launchy, Wox and Keypirinha, to quickly open and use at any time.



3. Sample scripts

Convert the backslashes in copied path list (js, php, python)



Adjust the text format copied from PDF document (php)



Generate array define code from hex string (php)



AStyle coding style beautifier (ini)


Current language: English · 其他语言: 中文 (简体)
已经成功将 Spleeter 引入到了 BeatShow 的音频处理过程中
经过两个周末的努力,已经成功将 Spleeter 引入到 BeatShow 中,用于音频文件的预处理。现在像《东风破》这样节奏比较慢,人声分离度不是很高的音乐也可以处理了。


在优酷上观看: https://v.youku.com/v_show/id_XNDc2ODIyOTM1Mg==.html

不过要看效果的话,还是得节奏欢快一点的音乐才好看。现在相比之前,人声和乐器轨的效果更好了一些。


在优酷上观看: https://v.youku.com/v_show/id_XNDc2ODIzMDY1Ng==.html
Current language: 中文 (简体)
发现了一个开源的人声和乐器音轨分离软件 Spleeter
用郭德纲的话说就是“晴天霹雳,kucha一声”,看看这《双截棍》的分离效果。


在优酷上观看: https://v.youku.com/v_show/id_XNDc2ODEyMjM4NA==.html

我每隔一段时间就会搜一遍音乐节拍识别、人声和乐器分离以及小型灯光秀设备相关的东西,这次搜出大问题了。去年 11 月,一法国公司开源了 spleeter 程序及已训练好的模型,效果和售价 1000 多刀的 RX7 软件中的 Music Rebalance 功能一样好。考虑之后把这个类库作为前置处理环节引入 BeatShow 了,这样流行音乐就也能处理了。
Current language: 中文 (简体)
FFmpeg 的 Windows build 现在有了 LGPL 版本

Current language: 中文 (简体)
Added filtering devices by name feature in the open source C# USB library Device.Net
The modified Device.Net library on Github:
https://github.com/wudicgi/Device.Net-display-name-filtering-enhanced
Current language: English · 其他语言: 中文 (简体)
More entries: [1] [2] [3] [4] [5] [6] ... [26]
« Previous page · Next page »