简单“修正”了一下 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 在很多处不需要改动的地方添加了额外的缩进:
其实以前也遇到过这个问题,但这次出现得比较集中、比较多,就准备解决一下了。打开 AStyle 的 VS2017 项目进行调试,发现对于我使用的选项
AStyle 在遇到赋值运算符 '=' 时为后续行添加 2 级缩进,而当继续处理遇到左括号 '(' 时又添加了 2 级缩进,于是后续行就拥有了多余的 2 级缩进。
2. 修改问题
我使用了一个简单粗暴的方式进行修改,就是在 ASBeautifier 类的 registerContinuationIndent() 方法中添加一个条件判断,使它在已经因为 '=' 添加了后续行缩进的情况下,不再因为其后出现的第一个 '(' 再添加缩进。
3. 修改前后效果对比
对同样的一段代码进行处理,原版 AStyle 的输出为:
修改后版本的输出为:
4. 修改的副作用
标题中的“修正”带引号是因为这并不一定是个 bug, 同时现在所做的这个修改会有一些副作用。对于一些极端情况的代码,例如:
原版 AStyle 能保留所有缩进等级,输出结果为:
而该修改版本的输出为:
最外层在缩进等级上没有与内层区分开来。但像这样的代码并不常见,所以为方便自己日常使用,“修正”一下还是有必要的。
附: AStyle 原版链接
AStyle 的官方项目地址为 http://astyle.sourceforge.net/
效果对比脚本: 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);
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
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(i >= -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
&& (i != 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;
}
// ...
int tabIncrementIn, int minIndent, bool updateParenStack)
{
assert(i >= -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
&& (i != 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. 修改前后效果对比
对同样的一段代码进行处理,原版 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);
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);
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;
3, 4, 5),
c, d)
/ 123;
原版 AStyle 能保留所有缩进等级,输出结果为:
int ret = func(a, b, another_func(1, 2,
3, 4, 5),
c, d)
/ 123;
3, 4, 5),
c, d)
/ 123;
而该修改版本的输出为:
int ret = func(a, b, another_func(1, 2,
3, 4, 5),
c, d)
/ 123;
3, 4, 5),
c, d)
/ 123;
最外层在缩进等级上没有与内层区分开来。但像这样的代码并不常见,所以为方便自己日常使用,“修正”一下还是有必要的。
附: AStyle 原版链接
AStyle 的官方项目地址为 http://astyle.sourceforge.net/
Current language: 中文 (简体)