免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5828 | 回复: 4
打印 上一主题 下一主题

[C] 分享个emacs中查找SYSCALL_DEFINE定义的系统调用的函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-02-28 22:55 |只看该作者 |倒序浏览
最近迷上了emacs,看代码时使用的gnu global的gtags插件,毕竟是自家产的,配合起来使用还是挺舒服的,在输入要查找的函数变量定义时可以用tab补齐,

可是发现查找内核代码中使用SYSCALL_DEFINE定义的系统调用时没什么好的办法,最初只能用
  1. $ find . -name "*.[ch]" | xargs grep -E "^SYSCALL_DEFINE[0-6]*\(socketcall.*\)$"
复制代码
之类的grep,但是总是先grep后打开也不是长久之计,而且速度真的很慢。

后来直接在emacs中使用gtags-find-pattern来使用正则表达式查找,这倒是能在emacs中直接定位了,但是内部还是调用的grep,所以速度还是很慢,
而直接使用gtags-find-tag查找SYSCALL_DEFINE0,SYSCALL_DEFINE1之类的定义非常快,因为它使用的已建立好的tag文件,根据这个想法写了一个函数,
原理就是先查找SYSCALL_DEFINE系列宏的定义,然后再删除掉不匹配的行,使用起来速度是非常快的,再定一个快捷键,以后就不为这个发愁了。

  1. (add-hook 'gtags-mode-hook
  2.           (lambda ()
  3.             (define-key gtags-mode-map (kbd "M-.")   'gtags-find-tag)
  4.             (define-key gtags-mode-map (kbd "M-, s") 'gtags-find-symbol)
  5.             (define-key gtags-mode-map (kbd "M-, r") 'gtags-find-rtag)
  6.             (define-key gtags-mode-map (kbd "M-, f") 'gtags-find-file)
  7.             (define-key gtags-mode-map (kbd "M-, p") 'gtags-find-pattern)
  8.             (define-key gtags-mode-map (kbd "M-, k") 'sec-gtags-find-kernel-syscall)
  9.             (define-key gtags-mode-map (kbd "M-*")   'gtags-pop-stack)
  10.             (setq gtags-path-style 'absolute)))

  11. (defun sec-gtags-find-kernel-syscall (&optional other-win)
  12.   "*Find linux kernel system call quickly.
  13. However, you can use `gtags-find-pattern' with regexp `^SYSCALL_DEFINE[0-6]*\(XXX.*\) to find the
  14. syscall which defined with `SYSCALL_DEFINE' family macro, but this is very slow.
  15. In this function, we use a efficiency way to do this job:
  16.   -- 1. find the define of all the `SYSCALL_DEFINE' family macro, and put them in a buffer, this only
  17.         waste little time.
  18.   -- 2. kill the lines which not match our regexp."
  19.   (interactive)
  20.   (let (tagname prompt input)
  21.     ;; Get the tagname we want to find.
  22.     (setq tagname (gtags-current-token))
  23.     (if tagname
  24.         (setq prompt (concat "Find syscall: (default " tagname ") "))
  25.       (setq prompt "Find syscall: "))
  26.     (setq input (completing-read prompt 'gtags-completing-gsyms
  27.                                  nil nil nil gtags-history-list))
  28.     (if (not (equal "" input)) (setq tagname input))
  29.     (gtags-push-context)
  30.     ;; Find begin.
  31.     (let (option save prefix buffer lines)
  32.       (setq save (current-buffer))
  33.       ;; Use always ctags-x format.
  34.       (setq option "-x")
  35.       (setq prefix "(SYSCALL)")
  36.       ;; Load tag
  37.       (if gtags-select-buffer-single
  38.           (progn
  39.             ;; Delete "*GTAGS SELECT*" buffer info from gtags-buffer-stack and gtags-point-stack.
  40.             (let (now-gtags-buffer-stack now-buffer now-gtags-point-stack now-point)
  41.               (setq now-gtags-buffer-stack (reverse gtags-buffer-stack))
  42.               (setq now-gtags-point-stack (reverse gtags-point-stack))
  43.               (setq gtags-buffer-stack nil)
  44.               (setq gtags-point-stack nil)
  45.               (while now-gtags-buffer-stack
  46.                 (setq now-buffer (car now-gtags-buffer-stack))
  47.                 (setq now-point (car now-gtags-point-stack))
  48.                 (if (and (buffer-name now-buffer) (not (string-match "*GTAGS SELECT*" (buffer-name now-buffer))))
  49.                     (progn
  50.                       (setq gtags-buffer-stack (cons now-buffer gtags-buffer-stack))
  51.                       (setq gtags-point-stack (cons now-point gtags-point-stack))))
  52.                 (setq now-gtags-buffer-stack (cdr now-gtags-buffer-stack))
  53.                 (setq now-gtags-point-stack (cdr now-gtags-point-stack))))
  54.             ;; Kill "*GTAGS SELECT*" buffer.
  55.             (let (now-buffer-list now-buffer)
  56.               (setq now-buffer-list (buffer-list))
  57.               (while now-buffer-list
  58.                 (setq now-buffer (car now-buffer-list))
  59.                 (if (string-match "*GTAGS SELECT*" (buffer-name now-buffer))
  60.                     (kill-buffer now-buffer))
  61.                 (setq now-buffer-list (cdr now-buffer-list))))))
  62.       ;; Select "*GTAGS SELECT*" buffer.
  63.       (setq buffer (generate-new-buffer (generate-new-buffer-name (concat "*GTAGS SELECT* " prefix tagname))))
  64.       (set-buffer buffer)
  65.       ;; Path style is defined in gtags-path-style:
  66.       ;; - root     : relative from the root of the project (Default)
  67.       ;; - relative : relative from the current directory
  68.       ;; - absolute : absolute (relative from the system root directory)
  69.       (cond
  70.        ((equal gtags-path-style 'absolute)
  71.         (setq option (concat option "a")))
  72.        ((equal gtags-path-style 'root)
  73.         (let (rootdir)
  74.           (if gtags-rootdir
  75.               (setq root-dir gtags-rootdir)
  76.             (setq rootdir (gtags-get-rootpath)))
  77.           (if rootdir (cd rootdir)))))
  78.       (message "Searching %s ..." tagname)
  79.       (if (not (= 0 (call-process "global" nil t nil option "SYSCALL_DEFINE[0-6]*")))
  80.           ;; Some error occured.
  81.           (progn (message (buffer-substring (point-min)(1- (point-max))))
  82.                  (gtags-pop-context))
  83.         ;; Call process success.
  84.         (keep-lines (concat "^.*SYSCALL_DEFINE[0-6]*\(" tagname ".*\)$") (point-min) (point-max))
  85.         (goto-char (point-min))
  86.         (setq lines (count-lines (point-min) (point-max)))
  87.         (cond
  88.          ((= 0 lines)
  89.           (message "%s: syscall not found" tagname)
  90.           (gtags-pop-context)
  91.           (kill-buffer buffer)
  92.           (set-buffer save))
  93.          ((= 1 lines)
  94.           (message "Searching %s ... Done" tagname)
  95.           (gtags-select-it t other-win))
  96.          (t
  97.           (if (null other-win)
  98.               (switch-to-buffer buffer)
  99.             (switch-to-buffer-other-window buffer))
  100.           (gtags-select-mode)))))))
复制代码

评分

参与人数 1可用积分 +1 收起 理由
lenky0401 + 1 支持分享

查看全部评分

论坛徽章:
0
2 [报告]
发表于 2011-03-02 09:28 |只看该作者
(x)cscope+emacs
不用这么多配置,好使的很!

论坛徽章:
0
3 [报告]
发表于 2011-03-02 09:48 |只看该作者
cscope足矣

论坛徽章:
0
4 [报告]
发表于 2011-03-02 09:54 |只看该作者
回复 2# logicBaby


cscope也不能直接定位SYSCALL_DEFINE定义的系统调用函数吧,当时用vim+cscope的时候也是靠:cs f e 加正则搜索的,另外如果用emacs,建议试一下global,它在查找时的tab补全是很方便的。比如要查找个函数,只记得函数名是以br开头的了,输入后tab一下就会提示出所有以br开头的可供选择的函数了,还有一些特性是相当不错的。

论坛徽章:
0
5 [报告]
发表于 2011-03-02 09:55 |只看该作者
回复 3# crazyshell

cscope可以直接定位这样的定义么
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP