在emacs中生成标签完成表时堆栈溢出
我在Windows上使用GNU Emacs 23.3。 我在一个非常大的代码库中工作,为此我生成一个TAGS文件(使用Emacs提供的etags二进制文件)。 标签文件相当大(通常徘徊在100MB左右)。 我很少需要使用find-tag
之外的任何功能,但有时候我希望能够完成TAGS表格。
调用complete-tag
会导致Emacs自动创建一个完成表。 这个过程需要一段时间,但我的问题不在于花费的时间,而是在最后(大约100%完成)的事实,我得到了堆栈溢出(对于不可打印的字符感到抱歉) ):
Debugger entered--Lisp error: (error "Stack overflow in regexp matcher")
re-search-forward("^(([^]+[^-a-zA-Z0-9_+*$:]+)?([-a-zA-Z0-9_+*$?:]+)[^-a-zA-Z0-9_+*$?:]*)(([^n]+))?([0-9]+)?,([0-9]+)?n" nil t)
etags-tags-completion-table()
byte-code(...)
tags-completion-table()
有没有其他人遇到过这个问题? 知道解决它的方法吗?
编辑:打开debug-on-error
后,堆栈输出
编辑:删除堆栈,因为我现在知道失败的条目是什么样子:
^L
c:pathtosomeheader.h,0
^L
c:pathtosomeotherheader.h,0
我的标签文件包含这种格式的不少条目。 看看所涉及的头文件,很明显,它们不能被etags正确解析。 这很好,但我很惊讶tags-completion-table
在它的正则表达式中没有考虑这种格式。 作为参考,这里是一个真实的条目:
^L
c:pathtosomevalidheader.h,115
class CSomeClass ^?12,345
bool SomeMethod(^?CSomeClass::SomeMethod^A67,890
有问题的正则表达式用于匹配TAGS
文件内的TAGS
条目。 我猜如果文件格式不正确(例如,使用非本地行结束符),或者如果一个条目真的非常大,就会发生错误。 (一个条目通常是一两行,这对正则表达式匹配器来说不应该是个问题。)
跟踪问题的一种方法是转到TAGS缓冲区,并在发生错误后查看点(光标)的位置。 一旦你知道它是哪个功能,并且你可以在没有标签的情况下生存,你可以避免为它生成TAGS条目。
如果问题是由于输入太复杂,我建议您应该向Emacs团队发送错误报告。
如果加载标签表(使用Emacs打开TAGS表,然后bury-buffer
),请尝试Mx dabbrev-expand
(绑定到M-/
)。 如果现在的前缀很常见,那么在达到所需的前缀之前,最终可能会遇到很多可能的完成。
我不使用Windows,但在我使用的Mac和Linux机器上,我没有遇到这个问题。
这看起来像Emacs中的一个错误,请参阅:
我已将建议的修补程序应用于etags-tags-completion-table
(为了您的方便,将其完整地复制到下方)并捕获错误案例。
我用非常长的一行代码(46,000个字符!)触发错误! 我假定有人以编程方式生成该行并将其粘贴到源代码中。 解决方法可能是在ctag构建或加载阶段简单地过滤这些行,只是删除“长”行,无论这可能意味着什么。 可能有500个字符够长!
我也可以考虑在ctags中为我的正则表达式添加最大尺寸,但这并不是一个通用的解决方案,因为许多ctags模式没有这种限制。
(defun etags-tags-completion-table () ; Doc string?
(let ((table (make-vector 511 0))
(progress-reporter
(make-progress-reporter
(format "Making tags completion table for %s..." buffer-file-name)
(point-min) (point-max))))
(save-excursion
(goto-char (point-min))
;; This monster regexp matches an etags tag line.
;; 1 is the string to match;
;; 2 is not interesting;
;; 3 is the guessed tag name; XXX guess should be better eg DEFUN
;; 4 is not interesting;
;; 5 is the explicitly-specified tag name.
;; 6 is the line to start searching at;
;; 7 is the char to start searching at.
(condition-case err
(while (re-search-forward
"^(([^177]+[^-a-zA-Z0-9_+*$:177]+)?
([-a-zA-Z0-9_+*$?:]+)[^-a-zA-Z0-9_+*$?:177]*)177
(([^n 01]+) 01)?([0-9]+)?,([0-9]+)?n"
nil t)
(intern (prog1 (if (match-beginning 5)
;; There is an explicit tag name.
(buffer-substring (match-beginning 5) (match-end 5))
;; No explicit tag name. Best guess.
(buffer-substring (match-beginning 3) (match-end 3)))
(progress-reporter-update progress-reporter (point)))
table))
(error
(message "error happened near %d" (point))
(error (error-message-string err)))))
table))
链接地址: http://www.djcxy.com/p/51639.html
上一篇: Stack overflow while generating tags completion table in emacs