用CEDET浏览和编辑C++代码(续) – 使用Emacs 23.2内置的CEDET
作者: Meteor Liu

1 前言
今天,emacs-23.2发布了,最大的改变就是集成进了CEDET,所以有了这个续, 介绍下build in CEDET和offical CEDET的区别,以及内置CEDET缺少某些功能的替代方案。
PS1:虽然现在官方release版本是1.0pre7,内置的CEDET用cedet-version命令看输入也是1.0pre7,可我总感觉内置的CEDET用起来比官方版本慢很多,我猜想内置的CEDET可能没升级到1.0pre7的release。
PS2:内置CEDET不支持emacs-lisp语言了,没想明白是为什么。
2 semantic配置
2.1 基本配置
官方的CEDET通过semantic-load-enable-minimum-features等几个函数来启动,而内置的CEDET增加了一个单独的minor mode,即semantic-mode,可以通过(semantic-mode)命令来Enable或Disable。
(semantic-mode)是通过semantic-default-submodes这个变量来决定启用哪些minor mode,默认的semantic-default-submodes包含了下面两个minor mode:
- global-semantic-idle-scheduler-mode
- global-semanticdb-minor-mode
根据(semantic-mode)的文档,semantic-default-submodes里可以设置下面这些minor mode:
- global-semanticdb-minor-mode
- global-semantic-idle-scheduler-mode
- global-semantic-idle-summary-mode
- global-semantic-idle-completions-mode
- global-semantic-decoration-mode
- global-semantic-highlight-func-mode
- global-semantic-stickyfunc-mode
- global-semantic-mru-bookmark-mode
可以根据自己的需要设置,比如我开启了下面4个minor mode:
1 2 3 4 5 | (setq semantic-default-submodes '(global-semantic-idle-scheduler-mode global-semanticdb-minor-mode global-semantic-idle-summary-mode global-semantic-mru-bookmark-mode)) (semantic-mode 1) |
另外,emacs-23.2的Tools菜单下下新增了”Source Code Parsers (Semantic)”菜单项,可以通过这个菜单项来Enable和Disable semantic-mode,和命令(semantic-mode)的功能是一样的。
此外,官方CEDET里还有其它一些minor mode,现在基本上都还可以用,比如我还打开了下面几个:
1 2 3 | (global-semantic-highlight-edits-mode (if window-system 1 -1)) (global-semantic-show-unmatched-syntax-mode 1) (global-semantic-show-parser-state-mode 1) |
关于system-include-dir的设置,还和以前一样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | (defconst user-include-dirs (list ".." "../include" "../inc" "../common" "../public" "../.." "../../include" "../../inc" "../../common" "../../public")) (defconst win32-include-dirs (list "C:/MinGW/include" "C:/MinGW/include/c++/3.4.5" "C:/MinGW/include/c++/3.4.5/mingw32" "C:/MinGW/include/c++/3.4.5/backward" "C:/MinGW/lib/gcc/mingw32/3.4.5/include" "C:/Program Files/Microsoft Visual Studio/VC98/MFC/Include")) (let ((include-dirs user-include-dirs)) (when (eq system-type 'windows-nt) (setq include-dirs (append include-dirs win32-include-dirs))) (mapc (lambda (dir) (semantic-add-system-include dir 'c++-mode) (semantic-add-system-include dir 'c-mode)) include-dirs)) |
2.2 代码跳转
代码跳转和官方版本一样还是用semantic-ia-fast-jump命令,不过在emacs-23.2里直接用这个命令可能会报下面的错误:
semantic-ia--fast-jump-helper: Symbol's function definition is void: semantic-analyze-tag-references |
这可能是emacs的bug,semantic-analyze-tag-references这个函数是定义在semantic/analyze/refs.el这个文件中的,而semantic/ia.el里写的是(eval-when-compile (require ’semantic/analyze/refs)),所以运行时这个feature没被load进来,我们需要自己load一下:
(require 'semantic/analyze/refs) |
另外,官方CEDET里semantic-ia-fast-jump后可以通过命令semantic-mrub-switch-tags来回到曾经跳转过的地方,不过在emacs-23.2里会提示:
Semantic Bookmark ring is currently empty
这是因为semantic-ia-fast-jump会用函数push-mark把跳过的地方放到mark ring里去,官方CEDET通过定义push-mark的advice把它也放到了semantic-mru-bookmark-ring里去,semantic-mrub-switch-tags就是从semantic-mru-bookmark-ring来找位置的,但build in的CEDET里把push-mark的advice去掉了,所以semantic-mru-bookmark-ring总是空的,我的办法是把官方CEDET里对push-mark的device拷贝到我的.emacs中来:
1 2 3 4 5 6 7 8 | (defadvice push-mark (around semantic-mru-bookmark activate) "Push a mark at LOCATION with NOMSG and ACTIVATE passed to `push-mark'. If `semantic-mru-bookmark-mode' is active, also push a tag onto the mru bookmark stack." (semantic-mrub-push semantic-mru-bookmark-ring (point) 'mark) ad-do-it) |
这样,我以前写的semantic-ia-fast-jump-back函数也能用了:
1 2 3 4 5 6 7 8 9 10 | (defun semantic-ia-fast-jump-back () (interactive) (if (ring-empty-p (oref semantic-mru-bookmark-ring ring)) (error "Semantic Bookmark ring is currently empty")) (let* ((ring (oref semantic-mru-bookmark-ring ring)) (alist (semantic-mrub-ring-to-assoc-list ring)) (first (cdr (car alist)))) (if (semantic-equivalent-tag-p (oref first tag) (semantic-current-tag)) (setq first (cdr (car (cdr alist))))) (semantic-mrub-switch-tags first))) |
对这个函数需要说明一下:网友fangzhzh提过可以用C-u C-space来跳回原来的mark,ahei说可以用C-x C-x来跳回,可我测试这两个按键好像跳得都有点乱,不能和semantic-ia-fast-jump的位置对应。我估计是这两个key是跳回push-mark函数mark的位置,而push-mark不光CEDET用。我的需求是只跳回semantic-ia-fast-jump曾经到过的地方,所以仍然保留了这个函数。
我的习惯还是绑定到F12上:
1 2 3 4 5 6 7 8 | (defun semantic-ia-fast-jump-or-back (&optional back) (interactive "P") (if back (semantic-ia-fast-jump-back) (semantic-ia-fast-jump (point)))) (define-key semantic-mode-map [f12] 'semantic-ia-fast-jump-or-back) (define-key semantic-mode-map [C-f12] 'semantic-ia-fast-jump-or-back) (define-key semantic-mode-map [S-f12] 'semantic-ia-fast-jump-back) |
这儿多出来个semantic-ia-fast-jump-or-back函数,是因为我有时候在putty里操作远程的emacs,putty里用不了S-f12这个key,所以我把f12绑定到semantic-ia-fast-jump-or-back上,这样我可以在putty里通过C-u f12来跳回。
以前的semantic-analyze-proto-impl-toggle命令还能用:
(define-key semantic-mode-map [M-S-f12] 'semantic-analyze-proto-impl-toggle) |
2.3 代码补全
官方版本里可以用命令semantic-ia-complete-symbol-menu弹出semantic的补全菜单,不过这个命令在内置的CEDET里不存在了(可能是因为emacs官方版本认为这个命令只在GUI下能用,不够通用吧)。
不过,内置的CEDET倒是可以通过命令complete-symbol(默认绑定到ESC-TAB)在另一个buffer里显示可能补全的内容,像这样:
如果还希望能使用补全菜单,可以使用其它插件,比如auto-complete或company-mode:company-mode-0.5已经可以支持emacs内置的CEDET了;auto-complete-1.2对内置CEDET的支持还有些问题,关于如何配置auto-complete-1.2让它支持内置的CEDET,我准备另外写文章介绍。
3 EDE配置
ede和官方版本没有区别,仍然用(global-ede-mode t)启用就行了;不过emacs-23.3的Tools菜单下新增了”Project support (EDE)”菜单项,可以完成global-ede-mode一样的功能。
4 其它
4.1 可视化书签
官方CEDET里的visual-studio-bookmarks在内置的CEDET里没有了,所以我现在使用bm了。
4.2 pulse
pulse的功能在内置CEDET里还存在,不过官方CEDET里可以用pulse-toggle-integration-advice函数来切换pulse,在内置CEDET里这个函数消失了,现在的办法是设置pulse-command-advice-flag变量来切换:
(setq pulse-command-advice-flag (if window-system 1 nil)) |
另外,官方版本里对下面这些函数设置了pulse的device:
- goto-line
- exchange-point-and-mark
- find-tag
- tags-search
- tags-loop-continue
- pop-tag-mark
- imenu-default-goto-function
内置版本里这些device都没了,所以我直接把官方版本里的advice拷贝过来了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | (defadvice goto-line (after pulse-advice activate) "Cause the line that is `goto'd to pulse when the cursor gets there." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice exchange-point-and-mark (after pulse-advice activate) "Cause the line that is `goto'd to pulse when the cursor gets there." (when (and pulse-command-advice-flag (interactive-p) (> (abs (- (point) (mark))) 400)) (pulse-momentary-highlight-one-line (point)))) (defadvice find-tag (after pulse-advice activate) "After going to a tag, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice tags-search (after pulse-advice activate) "After going to a hit, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice tags-loop-continue (after pulse-advice activate) "After going to a hit, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice pop-tag-mark (after pulse-advice activate) "After going to a hit, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice imenu-default-goto-function (after pulse-advice activate) "After going to a tag, pulse the line the cursor lands on." (when pulse-command-advice-flag (pulse-momentary-highlight-one-line (point)))) |
另外,我还喜欢对下面这些函数定义pulse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | (defadvice cua-exchange-point-and-mark (after pulse-advice activate) "Cause the line that is `goto'd to pulse when the cursor gets there." (when (and pulse-command-advice-flag (interactive-p) (> (abs (- (point) (mark))) 400)) (pulse-momentary-highlight-one-line (point)))) (defadvice switch-to-buffer (after pulse-advice activate) "After switch-to-buffer, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice previous-buffer (after pulse-advice activate) "After previous-buffer, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice next-buffer (after pulse-advice activate) "After next-buffer, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice ido-switch-buffer (after pulse-advice activate) "After ido-switch-buffer, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) (defadvice beginning-of-buffer (after pulse-advice activate) "After beginning-of-buffer, pulse the line the cursor lands on." (when (and pulse-command-advice-flag (interactive-p)) (pulse-momentary-highlight-one-line (point)))) |
4.3 h/cpp切换
官方CEDET里的eassist.el没有了,所以eassist-switch-h-cpp也没了,现在我用sourcepair代替,sourcepair比eassist-switch-h-cpp更好用。
4.4 代码折叠
semantic-tag-folding.el没有了,可我没找到其它更好的替代方案,所以我把官方CEDET里的semantic-tag-folding.el拷过来了,只需要把文件中(require ’semantic-decorate-mode)替换成(require ’semantic/decorate/mode)就能像以前一样用了。
以前的senator-fold-tag功能还可以使用。
最后插播个广告,我关于内置CEDET的配置(最后那部分):http://github.com/meteor1113/dotemacs/blob/master/init-basic.el

loading...
我发现windows下的23.2居然打不开jpg和pdf了
[回复]
ahei 回复:
五月 12th, 2010 at 9:58 上午
@, 惨,不过我一直用的未打过patch的windows emacs,所以一直打不开图片,:)
[回复]
匿名 回复:
五月 13th, 2010 at 4:55 上午
@ahei, 我从原来的emacs下拷贝了jpeg62.dll,libimage.dll,libpng12.dll
libungif4.dll等dll就OK了,但不知道为什么emacs一直是打不开bmp图片,linux下也一样。
[回复]
ahei 回复:
五月 13th, 2010 at 5:37 上午
@, 我这linux下emacs也打不开bmp图片,可能是它不支持bmp吧。
[回复]
Joyer 回复:
七月 25th, 2010 at 7:36 上午
@,
我写的ppm-gen可以显示24位的.BMP文件。
http://www.emacswiki.org/emacs/ppm-gen.el
方法是:
(ppm-show (ppm-from-bmp “filename.bmp”))
你可以自己再强化~~
[回复]
ahei 回复:
七月 27th, 2010 at 1:32 上午
@Joyer, 厉害厉害,有空一定试试
[回复]
整了一个周末,在win xp下使用emacs23.2, cedet1.07(没有用内置), ecb2.4
配置了system-include, semantic还是无法解析vc9 include的stl, 但是可以解析vc9 include下的.h头文件. 看了解析出来的semanitcdb文件,vector部分就是一个空的文件,没有tag.
试了一下boost,也解析不出来. atl/wtl/mfc 解析起来也是非常的慢
现在只能解析本地自已写的一些代码了.
从网上news groups/emacs wiki 找了一些贴子,似乎老外号称解析vc stl的问题是解决了的.
请问楼主大侠是否在windows下碰到过类似问题?不知道有没有解决办法. 非常感谢!
[回复]
Meteor Liu 回复:
五月 16th, 2010 at 10:24 上午
@sweord,
没用cedet和vc9配合过,我现在是在RHEL5下,对stl支持得还不错,,至少std::vector, std::string都能解析补全,速度也还可以。
我的配置里让它支持了MinGW和VC6只是为了测试CEDET能不能在Windows下用,基本上我只测试了下在MinGW能跳转,stl的补全就没试过了。等明天上班了我去试试能不能用MinGW和VC补全。
另外,你可以查一下是不是有预定义宏没被定义,可以看看http://alexott.net/en/writings/emacs-devenv/EmacsCedet.html里面关于semantic-lex-c-preprocessor-symbol-file的设置,不知道对支持VC9有没有帮助。
[回复]
sweord 回复:
五月 16th, 2010 at 1:06 下午
@Meteor Liu,
高手就是高手呀,我加了这样的设置:
(setq stl-base-dir “C:/Program Files/Microsoft Visual Studio 9.0/VC/include”)
(semantic-add-system-include stl-base-dir ‘c++-mode)
(add-to-list ‘auto-mode-alist (cons stl-base-dir ‘c++-mode))
(add-to-list ’semantic-lex-c-preprocessor-symbol-file (concat stl-base-dir “/crtdefs.h”))
(add-to-list ’semantic-lex-c-preprocessor-symbol-file (concat stl-base-dir “/yvals.h”))
现在可以解析vector了.但是还有个问题, 从semanitcdb里能看到vector的push_back方法,可以用
M-n联想出来的方法没有,只有一个nil,一个reversed_iterator,以及它们的子菜单.
我也装了mingw,试了下解析mingw的vector也是这样.
高手知道这个问题么?谢谢!
[回复]
Meteor Liu 回复:
五月 17th, 2010 at 3:58 上午
@sweord,
搞了一上午,我也搞不定。
我用VC6,没有crtdefs.h这个文件,不管加不加yvals.h,跳转补全都不行。
用MinGW的话跳转时灵时不灵的,补全基本没戏。不过要是用emacs-23.2自带的CEDET,
居然可以补全std::string,用官方release的CEDET-1.0pre7不能补全。至于vector,
一点效果都没有。
不过Linux下vector的跳转补全不用设置确实就挺好用的。不知道老外们怎么解决vc stl的问题的。
[回复]
sweord 回复:
五月 17th, 2010 at 11:29 上午
@Meteor Liu, 还是非常感谢您!!!
似乎看到邮件列表里说,要在1.0版本里能很好的支持windows,可能现在主要目标还是在linux下吧.
真高兴有这么个能讨论的地方
[回复]
sweord 回复:
五月 16th, 2010 at 1:52 下午
@sweord, 哈哈哈哈,从DEA里把cedet取出来,可以jump到push_back上了,但是M-n还是不行,联想出来的菜单是这样的: http://i3.6.cn/cvbnm/fa/ea/6b/dea64fb4b19fe065a413d5c8d823bdec.gif
[回复]
ahei 回复:
五月 16th, 2010 at 1:58 下午
@sweord, 你M-n执行的啥啊?
[回复]
sweord 回复:
五月 16th, 2010 at 2:00 下午
@ahei,
(define-key c-mode-base-map (kbd “M-n”) ’semantic-ia-complete-symbol-menu)
[回复]
Meteor Liu 回复:
六月 12th, 2010 at 1:58 下午
@sweord,
你觉得这个菜单有什么问题呢?里面列的不都是vector的成员么?
[回复]
sweord 回复:
六月 14th, 2010 at 3:33 上午
@Meteor Liu,
只列了这些成员出来,一些常用成员如push_back都没有列出来
[回复]
Meteor Liu 回复:
六月 14th, 2010 at 4:37 上午
@sweord,
两个子菜单呢,后面那个From你没打开来看看?
[回复]
sweord 回复:
六月 14th, 2010 at 5:08 上午
@Meteor Liu,
看了,是些迭带子相关的成员,而且也不全
[回复]
Meteor Liu 回复:
六月 14th, 2010 at 12:49 下午
@sweord,
哦,你这是win32啊,那可能确实不行。
换Linux应该没问题,我试过rhel5和ubuntu都正常
[回复]
我安装好cedet1.pre7,启用了ido,但是每次在.emacs中执行M-x eval-current-buffer时就会出现semantic: connot find source file ido。为何?我也没发现影响使用。我初学,请不吝赐教~~~~
[回复]
Meteor Liu 回复:
六月 12th, 2010 at 1:59 下午
@oucyanzc,
没见过,也想不到semantic和ido有什么关系,你可以把你的.emacs帖出来给大家看看
[回复]
oucyanzc 回复:
六月 12th, 2010 at 3:28 下午
@Meteor Liu,
[回复]
Meteor Liu 回复:
六月 14th, 2010 at 4:55 上午
@oucyanzc,
拿你的配置文件,除了”(global-set-key (kbd “S-”) ’set-mark-command)”这句报错外,
其它都正常,没出现你的问题,也不知道为什么你的有问题。看来你得自己调试下了。
[回复]
oucyanzc 回复:
六月 14th, 2010 at 5:23 上午
@Meteor Liu,
应该是(global-set-key (kbd “S-”) ’set-mark-command)
粘贴的时候出错了吧。
还有,貌似现在好了,也没有怎么修改,不晓得怎么回事,呵呵
谢谢~~~
[回复]
xin_yang 回复:
六月 3rd, 2011 at 12:19 上午
@oucyanzc, 哈哈不好意思,抄你的配置文件了
[回复]
借此贴问一句。楼主大大的svn上面cedet得设置时针对哪个呢?内置的还时你在lisps文件夹下那个cedet的?我是个大菜鸟。。弱弱得问一句。。如果时在lisps下那个cedet。怎么屏蔽调内置得呢?是自动的吗?
楼主大大得emacs配置太多了。。估计时几年得积累。我一下是消化不了的。就只抽出我有用的功能。没用的功能和model就先阉割了。。。多了记不住那些快捷键-= =
[回复]
ahei 回复:
六月 29th, 2010 at 1:33 上午
@SamPeng, 用的是我自己的,把cedet的路径加到load-path前面就可以了
[回复]
用内置的cedet
没有senator菜单,我想使用senator菜单中[Force Tag Refresh]强制它马上解析include目录
怎么办?
谢谢
[回复]
ahei 回复:
八月 25th, 2010 at 1:32 上午
@, 那就别用内置的呗,不用内置cedet的方法参考 http://emacser.com/emacs-23-2-release.htm
[回复]
onixie 回复:
八月 26th, 2010 at 5:13 下午
@ahei,
我有件奇怪的事。使用官方1.0pre07而非内置的时候,对于c/cpp会有不能自动开启senator minor mode的情况出现。第一次打开某个过去的c/cpp文件,senator菜单没有出现,再次打开这个项目中的第二个文件的时候,senator文件又出现了。但是如果新创建一个c/cpp文件,senator都会出现。不知道是不是一个bug。
[回复]
onixie 回复:
八月 26th, 2010 at 5:14 下午
@onixie, 打错了,不是senator文件是senator菜单又出现
[回复]
Meteor Liu 回复:
八月 26th, 2010 at 5:48 下午
@onixie,
我也有这个问题,不知道咋解决
[回复]
Meteor Liu 回复:
八月 25th, 2010 at 1:57 上午
@匿名
内置CEDET的Development菜单下有一项”Reparse Buffer”,功能应该是一样的
[回复]
我安装了emacs23.2.1,但是我在.emacs文件里加入(semantic-mode 1)后,重启emacs出现了错误:
error: Autoloading failed to define function semantic-mode
请问怎样解决?
[回复]
Meteor Liu 回复:
四月 26th, 2011 at 3:01 下午
@SkyHacker,
[回复]
Meteor Liu 回复:
四月 26th, 2011 at 3:01 下午
@SkyHacker,
平台?
怎么安装的?
用emacs -Q启动试试。
除了emacs本身外有没有安装官方的cedet包?
[回复]
abone 回复:
四月 27th, 2011 at 1:03 下午
@Meteor Liu,
这个问题我也遇到了,23.3的版本,自带了 cedet,而且ede管理工程似乎也不是ede-cpp-root-project这个格式的了
[回复]
问一下关于ede的问题,他和semantic那个有关系吧,我看etag或者scope都要有一个索引,然后找一个tag,怎么感觉ede的工程里没有建索引啊,怎么多文件里跳转呢,比如看linux kernel source code的时候,多谢
[回复]
Meteor Liu 回复:
四月 26th, 2011 at 3:06 下午
@abone,
ede用来管理一个project,生成Makefile之类的活,另外还可以给semantic提供头文件路径/预处理宏等,它本身是不生成索引的。
多文件跳转还是得靠semantic自己,或者用etags/cscopt/global之类的工具。
对于一个自定义的工程,我常用的方法是生成一个ede-cpp-root-project类型的工程,把用到的路径都加进去。我觉得看linux kernel source也可以这样定义ede。
另外,ede好像本身有一种ede-linux的project类型,好像就是用来支持linux kernel的。
[回复]
@abone
似乎找到原因了,需要在.emacs文件里
(require ’semantic) 否则是会提示那个错误
[回复]
使用環境:
emacs 23.3
內置的cedet 1.0
windows系統(windows 7 64-bit)
header檔來源:visual studio 2010 professional
描述:
發現利用本文的說明,可以正常使用代碼補全,不過美中不足的地方是在include c++的header檔時會無法parse成功,總顯示unparsed。以std的vector為例:#include 。這樣就會是unparsed,但是如果將header檔改成vector.hpp(hxx…)等等有副檔名的檔名,則又可以正確parse。猜想是在分析header檔時有使用regular expression,而這regular expression只將有傳統header副檔名的文件視為合法。但我看了一下visual studio的std裡的header文件是沒副檔名的,看了一下ubuntu下的也是沒副檔名的,所以應該是cedet本身的問題。找了許久還沒辦法確定regular expression是在哪做判斷的,不知道有沒有人也有這樣的問題,成功解決的?
[回复]
系统winxp,emacs23.3.1
我用的内置的CEDET
.emacs里面
;; (semantic-load-enable-minimum-features)
(semantic-load-enable-code-helpers)
;; (semantic-load-enable-guady-code-helpers)
;; (semantic-load-enable-excessive-code-helpers)
(semantic-load-enable-semantic-debugging-helpers)
但是当我重新打开emacs我得到错误消息:
>
> Symbol’s function definition is void: semantic-load-enable-code-helpers
>
如果在上述代码前加上了(require ’semantic-ia)也会出现上述相应的错误消息
如何解决,已经注释掉、google了很多天了
http://sourceforge.net/mailarchive/forum.php?thread_name=87mxl9lx0w.fsf%40randomsample.de&forum_name=cedet-semantic
万分感谢
[回复]