Gtags 解决 UnicodeEncodeError 问题
背景
Gtags
是 GNU global 的一个组件, 可以支持多个语言的符号生成, 索引等, 号称为最快的, 支持语言最多的符号索引工作, 可以在多个平台集成使用. Gtags 同时也支持源码变动的增量更新, 大大缩短了符号生成的时间. 目前最近的版本是 6.6.8
, 版本变更相关的信息可以查看 https://www.gnu.org/software/global/whatsnew.html
Gtags 可以使用通过 --gtagslabel
配置不同的源码解析器以便支持不同的语言及格式 , 主要的解析器有:
default
不配置时默认使用的内置 parser,只支持 asm, c/c++, java, php, yacc 语言.
ctags
使用 exuberant-ctags 作为语言 parser,支持 40+ 种语言,只能生成定义索引不能生成引用索引。
new-ctags
使用 universal-ctags 作为语言 parser,支持 100+ 种语言,只能生成定义索引不能生成引用索引。虽然貌似 universal-ctags 已经支持生成引用 tags,但是依然不能配合 gtags 工作(见这里),我也试了各种操作都没成功,也许是因为这个 PR 没有被 merge。
pygments
使用 pygments 作为语言 parser,号称支持 300+种语言。
native-pygments
对于原生支持的 6 种语言使用内置 parser,其他语言使用 pygments 作为 parser。
当我们使用默认解析器或 pygments 解析器时, 在有些情况下解析会报错终止, 导致符号生成失败, 错误如下.
Traceback (most recent call last):
File "/usr/local/Cellar/global/6.6.8/share/gtags/script/pygments_parser.py", line 264, in <module>
main()
File "/usr/local/Cellar/global/6.6.8/share/gtags/script/pygments_parser.py", line 261, in main
handle_requests(langmap, parser_options)
File "/usr/local/Cellar/global/6.6.8/share/gtags/script/pygments_parser.py", line 228, in handle_requests
print(typ, tag, lnum, path, image)
UnicodeEncodeError: 'latin-1' codec can't encode characters in position 8-15: ordinal not in range(256)
gtags: unexpected EOF.
解决
通过上述的堆栈信息找到 pygments_parser.py
文件中的 228 行, 发现报错的地方是一个打印语句.
如果正常打印到控制台应该是不会错误, 应该是 gtags 中读取控制台的输出的数据解析出错了. 通过在上方增加一个调试代码, 把输出控制台的数据输出到文件中看看.
通过输出的临时文件分析, 可以确定的是如果源码的路径参数(path 字段)存在非 ascii 字符时, 解析就会报错停止. 于是把原来的打印语句中的 path
参数进行 utf-8 编码.
进行以上修改后, 路径中存在非 ascii 字符时解析也能成功了.
本来还想着提交一个 pr 到 global , 但是看了下 global 的源码并不在 github 上管理. 如果要提交修改需要发邮件申请 contributor, 先作罢吧.
参考
版权声明: 本文为 InfoQ 作者【alps2006】的原创文章。
原文链接:【http://xie.infoq.cn/article/7523ccf859b2e0ba1b7573167】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论