Release coccinelle-0.1.4
[bpt/coccinelle.git] / emacs / cocci.el
CommitLineData
34e49164
C
1;;; cocci.el --- a major mode for editing semantic patches
2
3;; Copyright (C) 2006-2007 Yoann Padioleau
4
5;; Please imagine a long and boring gnu-style copyright notice
6;; appearing just here.
7
8
9;; Emacs Lisp Archive Entry
10;; Author: Padioleau Yoann <yoann.padioleau@gmail.com>,
11;; Version: 0.2
12;; Keywords: coccinelle patch refactoring program transformation
13;; URL: http://www.emn.fr/x-info/coccinelle/
14
15
16;;; Usage
17
1be43e12
C
18;; Copy this file in your ~/.emacs.d directory
19;;
34e49164 20;; Add the following lines to your ~/.emacs or equivalent:
1be43e12 21;; (load "~/.emacs.d/cocci.el")
34e49164
C
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)
26;;
27;; You can also use cocci-mode to edit the files containing the
28;; isomorphisms with:
29;; (setq auto-mode-alist
30;; (cons '("\\.iso$" . cocci-mode) auto-mode-alist))
31;;
32
33;;; History
34
35;; Some cleanups done by Rene Rydhof Hansen
36
37;;; Utilities
38
39(defun join-sep (sep xs)
40 (mapconcat 'identity xs sep))
41
42
43;;; Variables
44
45(defvar cocci-menu)
46
47
48;; new (color) faces
49
50(defface cocci-number-face
51 '((((background light)) (:foreground "black"))
52 (((background dark)) (:foreground "yellow3")))
53 "Used for Cocci numbers")
54
55(defface cocci-punctuation-face
56 '((((background light)) (:foreground "black"))
57 (((background dark)) (:foreground "cyan")))
58 "Used for punctuation")
59
60(defface cocci-problem-face
61 '((((background light)) (:background "deep pink"))
62 (((background dark)) (:background "deep pink")))
63 "Highlighting potential problems")
64
65(defface cocci-special-face
66 '((((background light)) (:foreground "blue"))
67 (((background dark)) (:foreground "red")))
68 "")
69
70(defface cocci-rulename-face
71 '((((background light)) (:foreground "DarkSlateGray"))
72 (((background dark)) (:foreground "DarkSlateGray4")))
73 "Highlighting the rule names")
74
75(defface cocci-minus-face
76 '((((background light)) (:foreground "dark green"))
77 (((background dark)) (:foreground "SeaGreen3")))
78 "Highlighting lines to be removed")
79
80(defface cocci-plus-face
81 '((((background light)) (:foreground "red"))
82 (((background dark)) (:foreground "salmon")))
83 "Highlighting lines to be added")
84
85(defface cocci-match-face
86 '((((background light)) (:foreground "violet red"))
87 (((background dark)) (:foreground "purple")))
88 "Highlighting lines to be matched (sgrep)")
89
90
91;; can look in lexer_cocci.mll for new identifiers
92
93(defconst cocci-c-keywords-list
94 '("if" "else" "while" "do" "for" "return"
95 "sizeof"
96 "struct" "union"
97 "static" "const" "volatile"
98 "break" "continue"
99 "switch" "case"
100 ))
101
102(defconst cocci-declaration-keywords-list
103 '("identifier" "type" "parameter" "constant" "expression" "statement"
104 "function" "local" "list"
105 "fresh"
106 "position"
107 "idexpression"
108
109 "typedef"
110 "declarer" "iterator"
111 "pure"
112 ;"error" "words"
113
114 "char" "short" "int" "float" "double" "long"
115 "void"
116 "signed" "unsigned"
117 ))
118
119(defconst cocci-iso-keywords-list
120 '("Expression" "Statement" "Type"
121 "Declaration" "TopLevel" "ArgExpression"
122 ))
123
124
125
126(defconst c-preprocessor-directives-list
127 '("define" "undef"
128 "if" "ifdef" "elif" "else" "endif" "ifndef"
129 "include"
130 "error" "pragma"
131 "file" "line"
132 ))
133
134
135(setq cocci-font-lock-keywords
136 `(
137
138 ; blink possible errors, when - or + is not in first column
139 ("^[ \t]+[-+]" . 'cocci-problem-face)
140
141 ; modifiers
142 ("^\\??\\+.*" . 'cocci-plus-face)
143 ("^\\??-.*" . 'cocci-minus-face)
144
145 ("^\\*.*" . 'cocci-match-face)
146 ;("^\\??\\+.*?//" . 'cocci-plus-face)
147 ; ! \\+
148
149 ; --- +++
150
151 ; #cpp
152 ("#\\(include\\) *\\(.*\\)"
153 (1 'font-lock-builtin-face)
154 (2 'font-lock-string-face)
155 )
156
157 ; comments
158 ("//.*" . 'font-lock-comment-face)
159
160 ; strings
161 ("\"[^\"]*\"" . 'font-lock-string-face)
162
163 ; rule header
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
169 ; OVERRIDE flag).
170
171 ("\\(@\\)\\(.*\\)\\(@\\)"
172 (1 'cocci-special-face)
173 (2 'cocci-rulename-face)
174 (3 'cocci-special-face)
175 )
176
177 ("@.*\\b\\(extends\\|\\(depends[ \t]*on\\)\\)\\b.*@"
178 (1 'cocci-special-face t))
179
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]*\\)+\\(@\\)"
185
186
187 ; inherited variable, fontifying rulename
188 (,(concat "^"
189 "\\b\\(" (regexp-opt cocci-declaration-keywords-list) "\\)\\b"
190 ".*?\\(\\w+\\)\\.")
191 (2 'cocci-rulename-face))
192
193 ;rule1.T *a;
194 ("^\\(\\w+\\)\\."
195 (1 'cocci-rulename-face))
196
197
198 ; just for pad, metavariables in maj
199 ("\\b[A-Z][0-9]?\\b" . font-lock-variable-name-face)
200
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
203
204 ; special cocci operators
205 ("\\.\\.\\." . 'font-lock-keyword-face)
206 ("^[()|]" . 'font-lock-keyword-face)
207
208 ; escaped version of cocci operators
209 ("\\\\[()|]" . 'font-lock-keyword-face)
210
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)
215
216 ; used in iso files
217 ("<=>" . 'font-lock-keyword-face)
218 ("=>" . 'font-lock-keyword-face)
219
220 (,(concat "\\b\\(" (regexp-opt cocci-iso-keywords-list) "\\)\\b") .
221 'cocci-special-face)
222
223 ("\\<[0-9]+\\>" . 'cocci-number-face)
224
225 (,(join-sep "\\|"
226 (list "(" ")" ";" "," "{" "}" "\\[" "\\]")) . 'cocci-punctuation-face)
227 ; . -> * + etc
228
229 ; c keywords
230 (,(concat "\\b\\(" (regexp-opt cocci-c-keywords-list) "\\)\\b") .
231 'font-lock-keyword-face)
232
233 ; cocci declaration keywords
234 (,(concat "\\b\\(" (regexp-opt cocci-declaration-keywords-list) "\\)\\b") .
235 'font-lock-type-face)
236
237 ; cpp directives
238 (,(concat "^#[ \t]*\\(" (regexp-opt c-preprocessor-directives-list)
239 "\\)\\>[ \t!]*\\(\\sw+\\)?")
240 (1 'font-lock-builtin-face))
241
242 ))
243; "Expressions to highlight in cocci-mode.")
244
245
246
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)
251
252
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)
259
260 ;(define-key cocci-mode-map "\C-c" 'compile)
261 )
262
263
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))
268
269 ; _ is part of a word.
270 (modify-syntax-entry ?\_ "w" cocci-mode-syntax-table)
271
272 ; change mode for ", bad interaction with font-lock
273 (modify-syntax-entry ?\" "w" cocci-mode-syntax-table)
274 )
275
276
277;;; Code
278
279;; helper functions for the cocci programmer
280
281(defun cocci-replace-modifiers (beg end str)
282 "TODO"
283 (interactive
284 (let ((str (read-string "New modifier string (+, -, space): "
285 nil 'my-history)))
286 (list (region-beginning) (region-end) str)))
287
288 ;(interactive "rsNew modifier string (+, -, space): ")
289 (replace-regexp "^[-+]?" str nil beg end)
290 )
291
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 ()
296 (interactive)
297 (let ((target
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)))
302 (t
303 "none"))))
304 (if (get-buffer target)
305 (switch-to-buffer target)
306 (find-file
307 (read-file-name "file: " nil nil t target)))))
308
309(eval-after-load "cc-mode"
310 '(progn
311 (define-key c-mode-map [(meta control *)] 'switch-between-cocci-c))
312 )
313
314
315
316
317(defvar cocci-mode-hook nil
318 "Hook called by `cocci-mode'")
319
320;;;###autoload
321(defun cocci-mode ()
322 "Major mode for editing cocci code.
323Special commands: \\{cocci-mode-map}
324Turning on cocci-mode runs the hook `cocci-mode-hook'."
325 (interactive)
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)
331
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)
338 comment-start "//"
339 comment-end ""
340 )
341 (easy-menu-add cocci-menu)
342
343 (run-hooks 'cocci-mode-hook)
344)
345
346
347;; Menu
348
349(easy-menu-define cocci-menu cocci-mode-map "Cocci menu"
350 '("Cocci"
351 ["Switch to corresponding C file" switch-between-cocci-c t]
352 ["Replace modifiers" cocci-replace-modifiers t]
353 ))
354
355
356
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])
361;"
362
363;; Provide
364(provide 'cocci-mode)
365
366;;; cocci.el ends here