1 ;;; cocci.el --- a major mode for editing semantic patches
3 ;; Copyright (C) 2006-2007 Yoann Padioleau
5 ;; Please imagine a long and boring gnu-style copyright notice
6 ;; appearing just here.
9 ;; Emacs Lisp Archive Entry
10 ;; Author: Padioleau Yoann <yoann.padioleau@gmail.com>,
12 ;; Keywords: coccinelle patch refactoring program transformation
13 ;; URL: http://www.emn.fr/x-info/coccinelle/
18 ;; Copy this file in your ~/.emacs.d directory
20 ;; Add the following lines to your ~/.emacs or equivalent:
21 ;; (load "~/.emacs.d/cocci.el")
22 ;; (setq auto-mode-alist
23 ;; (cons '("\\.cocci$" . cocci-mode) auto-mode-alist))
24 ;; (autoload 'cocci-mode "cocci"
25 ;; "Major mode for editing cocci code." t)
27 ;; You can also use cocci-mode to edit the files containing the
29 ;; (setq auto-mode-alist
30 ;; (cons '("\\.iso$" . cocci-mode) auto-mode-alist))
35 ;; Some cleanups done by Rene Rydhof Hansen
39 (defun join-sep (sep xs
)
40 (mapconcat 'identity xs sep
))
50 (defface cocci-number-face
51 '((((background light
)) (:foreground
"black"))
52 (((background dark
)) (:foreground
"yellow3")))
53 "Used for Cocci numbers")
55 (defface cocci-punctuation-face
56 '((((background light
)) (:foreground
"black"))
57 (((background dark
)) (:foreground
"cyan")))
58 "Used for punctuation")
60 (defface cocci-problem-face
61 '((((background light
)) (:background
"deep pink"))
62 (((background dark
)) (:background
"deep pink")))
63 "Highlighting potential problems")
65 (defface cocci-special-face
66 '((((background light
)) (:foreground
"blue"))
67 (((background dark
)) (:foreground
"red")))
70 (defface cocci-rulename-face
71 '((((background light
)) (:foreground
"DarkSlateGray"))
72 (((background dark
)) (:foreground
"DarkSlateGray4")))
73 "Highlighting the rule names")
75 (defface cocci-minus-face
76 '((((background light
)) (:foreground
"red"))
77 (((background dark
)) (:foreground
"SeaGreen3")))
78 "Highlighting lines to be removed")
80 (defface cocci-plus-face
81 '((((background light
)) (:foreground
"dark green"))
82 (((background dark
)) (:foreground
"salmon")))
83 "Highlighting lines to be added")
85 (defface cocci-match-face
86 '((((background light
)) (:foreground
"violet red"))
87 (((background dark
)) (:foreground
"purple")))
88 "Highlighting lines to be matched (sgrep)")
91 ;; can look in lexer_cocci.mll for new identifiers
93 (defconst cocci-c-keywords-list
94 '("if" "else" "while" "do" "for" "return"
97 "static" "const" "volatile"
102 (defconst cocci-declaration-keywords-list
103 '("identifier" "type" "parameter" "constant" "expression" "statement"
104 "function" "local" "list"
110 "declarer" "iterator"
114 "char" "short" "int" "float" "double" "long"
119 (defconst cocci-iso-keywords-list
120 '("Expression" "Statement" "Type"
121 "Declaration" "TopLevel" "ArgExpression"
126 (defconst c-preprocessor-directives-list
128 "if" "ifdef" "elif" "else" "endif" "ifndef"
135 (setq cocci-font-lock-keywords
138 ; blink possible errors, when - or + is not in first column
139 ("^[ \t]+[-+]" .
'cocci-problem-face
)
142 ("^\\??\\+.*" .
'cocci-plus-face
)
143 ("^\\??-.*" .
'cocci-minus-face
)
145 ("^\\*.*" .
'cocci-match-face
)
146 ;("^\\??\\+.*?//" . 'cocci-plus-face)
152 ("#\\(include\\) *\\(.*\\)"
153 (1 'font-lock-builtin-face
)
154 (2 'font-lock-string-face
)
158 ("//.*" .
'font-lock-comment-face
)
161 ("\"[^\"]*\"" .
'font-lock-string-face
)
164 ("@[ \t]*@" .
'cocci-special-face
)
165 ; this rule may seems redundant with the following one, but
166 ; without it, @@ int x; @@ would color the int x with rulename-face.
167 ; by using this rule, we color the @@ and so prevent the
168 ; next rule to be applied (cf font-lock semantic when have not the
171 ("\\(@\\)\\(.*\\)\\(@\\)"
172 (1 'cocci-special-face
)
173 (2 'cocci-rulename-face
)
174 (3 'cocci-special-face
)
177 ("@.*\\b\\(extends\\|\\(depends[ \t]*on\\)\\)\\b.*@"
178 (1 'cocci-special-face t
))
180 ;old: does not work, not easy to handle the rule1, rule2, rule3 list.
181 ; ("@[ \t]*\\(\\(\\w+\\)[ \t,]*\\)*[ \t]*@"
182 ; ("\\(@\\)[ \t]*\\(\\w+\\)[ \t]*\\(@\\)"
183 ; ("\\(@\\)[ \t]*\\(\\w+\\)[ \t]+\\(extends\\)[ \t]+\\(\\w+\\)[ \t]*\\(@\\)"
184 ; ("\\(@\\)[ \t]*\\(\\w+\\)[ \t]+\\(depends\\)[ \t]+\\(on\\)[ \t]+\\(\\(\\w+\\)[ ,\t]*\\)+\\(@\\)"
187 ; inherited variable, fontifying rulename
189 "\\b\\(" (regexp-opt cocci-declaration-keywords-list
) "\\)\\b"
191 (2 'cocci-rulename-face
))
195 (1 'cocci-rulename-face
))
198 ; just for pad, metavariables in maj
199 ("\\b[A-Z][0-9]?\\b" . font-lock-variable-name-face
)
201 ; todo: do also for other variable, do as in font-lock.el
202 ; with font-lock-match-c-style-declaration-item-and-skip-to-next
204 ; special cocci operators
205 ("\\.\\.\\." .
'font-lock-keyword-face
)
206 ("^[()|]" .
'font-lock-keyword-face
)
208 ; escaped version of cocci operators
209 ("\\\\[()|]" .
'font-lock-keyword-face
)
211 ("\\bwhen[ \t]+!=" .
'font-lock-keyword-face
)
212 ("\\bWHEN[ \t]+!=" .
'font-lock-keyword-face
)
213 ("\\bwhen[ \t]+=" .
'font-lock-keyword-face
)
214 ("\\bWHEN[ \t]+=" .
'font-lock-keyword-face
)
217 ("<=>" .
'font-lock-keyword-face
)
218 ("=>" .
'font-lock-keyword-face
)
220 (,(concat "\\b\\(" (regexp-opt cocci-iso-keywords-list
) "\\)\\b") .
223 ("\\<[0-9]+\\>" .
'cocci-number-face
)
226 (list "(" ")" ";" "," "{" "}" "\\[" "\\]")) .
'cocci-punctuation-face
)
230 (,(concat "\\b\\(" (regexp-opt cocci-c-keywords-list
) "\\)\\b") .
231 'font-lock-keyword-face
)
233 ; cocci declaration keywords
234 (,(concat "\\b\\(" (regexp-opt cocci-declaration-keywords-list
) "\\)\\b") .
235 'font-lock-type-face
)
238 (,(concat "^#[ \t]*\\(" (regexp-opt c-preprocessor-directives-list
)
239 "\\)\\>[ \t!]*\\(\\sw+\\)?")
240 (1 'font-lock-builtin-face
))
243 ; "Expressions to highlight in cocci-mode.")
247 ;; define a mode-specific abbrev table for those who use such things
248 (defvar cocci-mode-abbrev-table nil
249 "Abbrev table used while in cocci mode.")
250 (define-abbrev-table 'cocci-mode-abbrev-table nil
)
253 (defvar cocci-mode-map nil
254 "Keymap used in `cocci-mode'.")
255 (unless cocci-mode-map
256 (setq cocci-mode-map
(make-sparse-keymap))
257 (define-key cocci-mode-map
[(meta control
*)] 'switch-between-cocci-c
)
258 (define-key cocci-mode-map
"%" 'cocci-replace-modifiers
)
260 ;(define-key cocci-mode-map "\C-c" 'compile)
264 (defvar cocci-mode-syntax-table nil
265 "Syntax table used while in cocci mode.")
266 (unless cocci-mode-syntax-table
267 (setq cocci-mode-syntax-table
(make-syntax-table))
269 ; _ is part of a word.
270 (modify-syntax-entry ?\_
"w" cocci-mode-syntax-table
)
272 ; change mode for ", bad interaction with font-lock
273 (modify-syntax-entry ?
\" "w" cocci-mode-syntax-table
)
279 ;; helper functions for the cocci programmer
281 (defun cocci-replace-modifiers (beg end str
)
284 (let ((str (read-string "New modifier string (+, -, space): "
286 (list (region-beginning) (region-end) str
)))
288 ;(interactive "rsNew modifier string (+, -, space): ")
289 (replace-regexp "^[-+]?" str nil beg end
)
292 ;Used internally while developping coccinelle.
293 ;Allow to switch between the corresponding SP and C file.
294 ;todo: handle the _verxxx naming convention.
295 (defun switch-between-cocci-c ()
298 (cond ((string-match ".c$" (buffer-name))
299 (replace-match ".cocci" t t
(buffer-name)))
300 ((string-match ".cocci$" (buffer-name))
301 (replace-match ".c" t t
(buffer-name)))
304 (if (get-buffer target
)
305 (switch-to-buffer target
)
307 (read-file-name "file: " nil nil t target
)))))
309 (eval-after-load "cc-mode"
311 (define-key c-mode-map
[(meta control
*)] 'switch-between-cocci-c
))
317 (defvar cocci-mode-hook nil
318 "Hook called by `cocci-mode'")
322 "Major mode for editing cocci code.
323 Special commands: \\{cocci-mode-map}
324 Turning on cocci-mode runs the hook `cocci-mode-hook'."
326 (kill-all-local-variables)
327 (make-local-variable 'font-lock-defaults
)
328 (make-local-variable 'comment-start
)
329 (make-local-variable 'comment-end
)
330 (make-local-variable 'compile-command
)
332 (use-local-map cocci-mode-map
)
333 (set-syntax-table cocci-mode-syntax-table
)
334 (setq mode-name
"cocci"
335 major-mode
'cocci-mode
336 local-abbrev-table cocci-mode-abbrev-table
337 font-lock-defaults
'(cocci-font-lock-keywords)
341 (easy-menu-add cocci-menu
)
343 (run-hooks 'cocci-mode-hook
)
349 (easy-menu-define cocci-menu cocci-mode-map
"Cocci menu"
351 ["Switch to corresponding C file" switch-between-cocci-c t
]
352 ["Replace modifiers" cocci-replace-modifiers t
]
357 ; put cursor before a parse error coccinelle message and it will
358 ; open the corresponding file and go to corresponding line.
359 (fset 'cocci-goto-next-error
360 [?\C-s ?F ?i ?l ?e right right ?\C- ?\C-s ?
" left ?\M-w ?\C-x ?\C-f S-insert return ?\C-\M-l C-right right C-S-right C-insert ?\C-\M-l ?\M-g S-insert return])
364 (provide 'cocci-mode
)
366 ;;; cocci.el ends here