- 论坛徽章:
- 0
|
最近迷上了emacs,看代码时使用的gnu global的gtags插件,毕竟是自家产的,配合起来使用还是挺舒服的,在输入要查找的函数变量定义时可以用tab补齐,
可是发现查找内核代码中使用SYSCALL_DEFINE定义的系统调用时没什么好的办法,最初只能用- $ 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系列宏的定义,然后再删除掉不匹配的行,使用起来速度是非常快的,再定一个快捷键,以后就不为这个发愁了。
- (add-hook 'gtags-mode-hook
- (lambda ()
- (define-key gtags-mode-map (kbd "M-.") 'gtags-find-tag)
- (define-key gtags-mode-map (kbd "M-, s") 'gtags-find-symbol)
- (define-key gtags-mode-map (kbd "M-, r") 'gtags-find-rtag)
- (define-key gtags-mode-map (kbd "M-, f") 'gtags-find-file)
- (define-key gtags-mode-map (kbd "M-, p") 'gtags-find-pattern)
- (define-key gtags-mode-map (kbd "M-, k") 'sec-gtags-find-kernel-syscall)
- (define-key gtags-mode-map (kbd "M-*") 'gtags-pop-stack)
- (setq gtags-path-style 'absolute)))
- (defun sec-gtags-find-kernel-syscall (&optional other-win)
- "*Find linux kernel system call quickly.
- However, you can use `gtags-find-pattern' with regexp `^SYSCALL_DEFINE[0-6]*\(XXX.*\) to find the
- syscall which defined with `SYSCALL_DEFINE' family macro, but this is very slow.
- In this function, we use a efficiency way to do this job:
- -- 1. find the define of all the `SYSCALL_DEFINE' family macro, and put them in a buffer, this only
- waste little time.
- -- 2. kill the lines which not match our regexp."
- (interactive)
- (let (tagname prompt input)
- ;; Get the tagname we want to find.
- (setq tagname (gtags-current-token))
- (if tagname
- (setq prompt (concat "Find syscall: (default " tagname ") "))
- (setq prompt "Find syscall: "))
- (setq input (completing-read prompt 'gtags-completing-gsyms
- nil nil nil gtags-history-list))
- (if (not (equal "" input)) (setq tagname input))
- (gtags-push-context)
- ;; Find begin.
- (let (option save prefix buffer lines)
- (setq save (current-buffer))
- ;; Use always ctags-x format.
- (setq option "-x")
- (setq prefix "(SYSCALL)")
- ;; Load tag
- (if gtags-select-buffer-single
- (progn
- ;; Delete "*GTAGS SELECT*" buffer info from gtags-buffer-stack and gtags-point-stack.
- (let (now-gtags-buffer-stack now-buffer now-gtags-point-stack now-point)
- (setq now-gtags-buffer-stack (reverse gtags-buffer-stack))
- (setq now-gtags-point-stack (reverse gtags-point-stack))
- (setq gtags-buffer-stack nil)
- (setq gtags-point-stack nil)
- (while now-gtags-buffer-stack
- (setq now-buffer (car now-gtags-buffer-stack))
- (setq now-point (car now-gtags-point-stack))
- (if (and (buffer-name now-buffer) (not (string-match "*GTAGS SELECT*" (buffer-name now-buffer))))
- (progn
- (setq gtags-buffer-stack (cons now-buffer gtags-buffer-stack))
- (setq gtags-point-stack (cons now-point gtags-point-stack))))
- (setq now-gtags-buffer-stack (cdr now-gtags-buffer-stack))
- (setq now-gtags-point-stack (cdr now-gtags-point-stack))))
- ;; Kill "*GTAGS SELECT*" buffer.
- (let (now-buffer-list now-buffer)
- (setq now-buffer-list (buffer-list))
- (while now-buffer-list
- (setq now-buffer (car now-buffer-list))
- (if (string-match "*GTAGS SELECT*" (buffer-name now-buffer))
- (kill-buffer now-buffer))
- (setq now-buffer-list (cdr now-buffer-list))))))
- ;; Select "*GTAGS SELECT*" buffer.
- (setq buffer (generate-new-buffer (generate-new-buffer-name (concat "*GTAGS SELECT* " prefix tagname))))
- (set-buffer buffer)
- ;; Path style is defined in gtags-path-style:
- ;; - root : relative from the root of the project (Default)
- ;; - relative : relative from the current directory
- ;; - absolute : absolute (relative from the system root directory)
- (cond
- ((equal gtags-path-style 'absolute)
- (setq option (concat option "a")))
- ((equal gtags-path-style 'root)
- (let (rootdir)
- (if gtags-rootdir
- (setq root-dir gtags-rootdir)
- (setq rootdir (gtags-get-rootpath)))
- (if rootdir (cd rootdir)))))
- (message "Searching %s ..." tagname)
- (if (not (= 0 (call-process "global" nil t nil option "SYSCALL_DEFINE[0-6]*")))
- ;; Some error occured.
- (progn (message (buffer-substring (point-min)(1- (point-max))))
- (gtags-pop-context))
- ;; Call process success.
- (keep-lines (concat "^.*SYSCALL_DEFINE[0-6]*\(" tagname ".*\)$") (point-min) (point-max))
- (goto-char (point-min))
- (setq lines (count-lines (point-min) (point-max)))
- (cond
- ((= 0 lines)
- (message "%s: syscall not found" tagname)
- (gtags-pop-context)
- (kill-buffer buffer)
- (set-buffer save))
- ((= 1 lines)
- (message "Searching %s ... Done" tagname)
- (gtags-select-it t other-win))
- (t
- (if (null other-win)
- (switch-to-buffer buffer)
- (switch-to-buffer-other-window buffer))
- (gtags-select-mode)))))))
复制代码 |
评分
-
查看全部评分
|