Commit | Line | Data |
---|---|---|
3c3d11e7 | 1 | ;;; cc-defs.el --- compile time definitions for CC Mode |
785eecbb | 2 | |
bbfbe5ec | 3 | ;; Copyright (C) 1985,1987,1992-2000 Free Software Foundation, Inc. |
785eecbb | 4 | |
bbfbe5ec GM |
5 | ;; Authors: 2000- Martin Stjernholm |
6 | ;; 1998-1999 Barry A. Warsaw and Martin Stjernholm | |
0ec8351b | 7 | ;; 1992-1997 Barry A. Warsaw |
785eecbb RS |
8 | ;; 1987 Dave Detlefs and Stewart Clamen |
9 | ;; 1985 Richard M. Stallman | |
0ec8351b | 10 | ;; Maintainer: bug-cc-mode@gnu.org |
785eecbb | 11 | ;; Created: 22-Apr-1997 (split from cc-mode.el) |
81eb2ff9 | 12 | ;; Version: See cc-mode.el |
785eecbb RS |
13 | ;; Keywords: c languages oop |
14 | ||
15 | ;; This file is part of GNU Emacs. | |
16 | ||
17 | ;; GNU Emacs is free software; you can redistribute it and/or modify | |
18 | ;; it under the terms of the GNU General Public License as published by | |
19 | ;; the Free Software Foundation; either version 2, or (at your option) | |
20 | ;; any later version. | |
21 | ||
22 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
23 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | ;; GNU General Public License for more details. | |
26 | ||
27 | ;; You should have received a copy of the GNU General Public License | |
28 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | |
29 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
30 | ;; Boston, MA 02111-1307, USA. | |
31 | ||
0ec8351b BW |
32 | ;; Get all the necessary compile time definitions. |
33 | (require 'custom) | |
0ec8351b BW |
34 | (require 'derived) ;only necessary in Emacs 20 |
35 | ||
36 | ;; cc-mode-19.el contains compatibility macros that should be compiled | |
37 | ;; in if needed. | |
38 | (if (or (not (fboundp 'functionp)) | |
39 | (not (condition-case nil | |
40 | (progn (char-before) t) | |
41 | (error nil))) | |
42 | (not (condition-case nil | |
43 | (progn (char-after) t) | |
44 | (error nil))) | |
45 | (not (fboundp 'when)) | |
46 | (not (fboundp 'unless))) | |
47 | (require 'cc-mode-19)) | |
48 | ||
49 | \f | |
51f606de | 50 | (defmacro c-point (position) |
785eecbb RS |
51 | ;; Returns the value of point at certain commonly referenced POSITIONs. |
52 | ;; POSITION can be one of the following symbols: | |
53 | ;; | |
54 | ;; bol -- beginning of line | |
55 | ;; eol -- end of line | |
56 | ;; bod -- beginning of defun | |
0ec8351b | 57 | ;; eod -- end of defun |
785eecbb RS |
58 | ;; boi -- back to indentation |
59 | ;; ionl -- indentation of next line | |
60 | ;; iopl -- indentation of previous line | |
61 | ;; bonl -- beginning of next line | |
62 | ;; bopl -- beginning of previous line | |
63 | ;; | |
64 | ;; This function does not modify point or mark. | |
51f606de GM |
65 | `(save-excursion |
66 | ,(if (and (eq (car-safe position) 'quote) | |
67 | (symbolp (eval position))) | |
68 | (let ((position (eval position))) | |
69 | (cond | |
70 | ((eq position 'bol) `(beginning-of-line)) | |
71 | ((eq position 'eol) `(end-of-line)) | |
72 | ((eq position 'boi) `(back-to-indentation)) | |
73 | ((eq position 'bonl) `(forward-line 1)) | |
74 | ((eq position 'bopl) `(forward-line -1)) | |
75 | ((eq position 'bod) `(c-beginning-of-defun-1)) | |
76 | ((eq position 'eod) `(c-end-of-defun-1)) | |
77 | ((eq position 'iopl) `(progn | |
78 | (forward-line -1) | |
79 | (back-to-indentation))) | |
80 | ((eq position 'ionl) `(progn | |
81 | (forward-line 1) | |
82 | (back-to-indentation))) | |
83 | (t (error "unknown buffer position requested: %s" position)))) | |
84 | ;;(message "c-point long expansion") | |
85 | `(let ((position ,position)) | |
86 | (cond | |
87 | ((eq position 'bol) (beginning-of-line)) | |
88 | ((eq position 'eol) (end-of-line)) | |
89 | ((eq position 'boi) (back-to-indentation)) | |
90 | ((eq position 'bonl) (forward-line 1)) | |
91 | ((eq position 'bopl) (forward-line -1)) | |
92 | ((eq position 'bod) (c-beginning-of-defun-1)) | |
93 | ((eq position 'eod) (c-end-of-defun-1)) | |
94 | ((eq position 'iopl) (progn | |
95 | (forward-line -1) | |
96 | (back-to-indentation))) | |
97 | ((eq position 'ionl) (progn | |
98 | (forward-line 1) | |
99 | (back-to-indentation))) | |
100 | (t (error "unknown buffer position requested: %s" position))))) | |
101 | (point))) | |
785eecbb | 102 | |
0ec8351b | 103 | \f |
785eecbb RS |
104 | (defmacro c-safe (&rest body) |
105 | ;; safely execute BODY, return nil if an error occurred | |
51f606de GM |
106 | `(condition-case nil |
107 | (progn ,@body) | |
108 | (error nil))) | |
109 | ||
110 | (defsubst c-beginning-of-defun-1 () | |
111 | ;; Wrapper around beginning-of-defun. | |
112 | ;; | |
113 | ;; NOTE: This function should contain the only explicit use of | |
114 | ;; beginning-of-defun in CC Mode. Eventually something better than | |
115 | ;; b-o-d will be available and this should be the only place the | |
116 | ;; code needs to change. Everything else should use | |
117 | ;; (c-beginning-of-defun-1) | |
118 | (if (and (fboundp 'buffer-syntactic-context-depth) | |
119 | c-enable-xemacs-performance-kludge-p) | |
120 | ;; XEmacs only. This can improve the performance of | |
121 | ;; c-parse-state to between 3 and 60 times faster when | |
122 | ;; braces are hung. It can also degrade performance by | |
123 | ;; about as much when braces are not hung. | |
124 | (let (pos) | |
125 | (while (not pos) | |
126 | (save-restriction | |
127 | (widen) | |
128 | (setq pos (scan-lists (point) -1 | |
129 | (buffer-syntactic-context-depth) | |
130 | nil t))) | |
131 | (cond | |
132 | ((bobp) (setq pos (point-min))) | |
133 | ((not pos) | |
134 | (let ((distance (skip-chars-backward "^{"))) | |
135 | ;; unbalanced parenthesis, while illegal C code, | |
136 | ;; shouldn't cause an infloop! See unbal.c | |
137 | (when (zerop distance) | |
138 | ;; Punt! | |
139 | (beginning-of-defun) | |
140 | (setq pos (point))))) | |
141 | ((= pos 0)) | |
142 | ((not (eq (char-after pos) ?{)) | |
143 | (goto-char pos) | |
144 | (setq pos nil)) | |
145 | )) | |
146 | (goto-char pos)) | |
147 | ;; Emacs, which doesn't have buffer-syntactic-context-depth | |
148 | (beginning-of-defun)) | |
149 | ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at the | |
150 | ;; open brace. | |
151 | (and defun-prompt-regexp | |
152 | (looking-at defun-prompt-regexp) | |
153 | (goto-char (match-end 0)))) | |
154 | ||
155 | (defsubst c-end-of-defun-1 () | |
156 | ;; Replacement for end-of-defun that use c-beginning-of-defun-1. | |
bbfbe5ec GM |
157 | (let ((start (point))) |
158 | ;; Skip forward into the next defun block. Don't bother to avoid | |
159 | ;; comments, literals etc, since beginning-of-defun doesn't do that | |
160 | ;; anyway. | |
161 | (skip-chars-forward "^}") | |
162 | (c-beginning-of-defun-1) | |
163 | (if (eq (char-after) ?{) | |
164 | (c-forward-sexp)) | |
165 | (if (< (point) start) | |
166 | (goto-char (point-max))))) | |
785eecbb | 167 | |
0ec8351b BW |
168 | (defmacro c-forward-sexp (&optional arg) |
169 | ;; like forward-sexp except | |
170 | ;; 1. this is much stripped down from the XEmacs version | |
171 | ;; 2. this cannot be used as a command, so we're insulated from | |
172 | ;; XEmacs' losing efforts to make forward-sexp more user | |
173 | ;; friendly | |
174 | ;; 3. Preserves the semantics most of CC Mode is based on | |
175 | (or arg (setq arg 1)) | |
176 | `(goto-char (or (scan-sexps (point) ,arg) | |
177 | ,(if (numberp arg) | |
178 | (if (> arg 0) `(point-max) `(point-min)) | |
179 | `(if (> ,arg 0) (point-max) (point-min)))))) | |
180 | ||
181 | (defmacro c-backward-sexp (&optional arg) | |
182 | ;; See c-forward-sexp and reverse directions | |
183 | (or arg (setq arg 1)) | |
184 | `(c-forward-sexp ,(if (numberp arg) (- arg) `(- ,arg)))) | |
185 | ||
51f606de GM |
186 | (defsubst c-beginning-of-macro (&optional lim) |
187 | ;; Go to the beginning of a cpp macro definition. Leaves point at | |
188 | ;; the beginning of the macro and returns t if in a cpp macro | |
189 | ;; definition, otherwise returns nil and leaves point unchanged. | |
190 | ;; `lim' is currently ignored, but the interface requires it. | |
191 | (let ((here (point))) | |
192 | (beginning-of-line) | |
193 | (while (eq (char-before (1- (point))) ?\\) | |
194 | (forward-line -1)) | |
195 | (back-to-indentation) | |
196 | (if (and (<= (point) here) | |
197 | (eq (char-after) ?#)) | |
198 | t | |
199 | (goto-char here) | |
200 | nil))) | |
201 | ||
202 | (defsubst c-forward-comment (count) | |
203 | ;; Insulation from various idiosyncrasies in implementations of | |
204 | ;; `forward-comment'. Note: Some emacsen considers incorrectly that | |
205 | ;; any line comment ending with a backslash continues to the next | |
206 | ;; line. I can't think of any way to work around that in a reliable | |
207 | ;; way without changing the buffer though. Suggestions welcome. ;) | |
208 | (let ((here (point))) | |
209 | (if (>= count 0) | |
210 | (when (forward-comment count) | |
211 | ;; Emacs includes the ending newline in a b-style | |
212 | ;; (c++) comment, but XEmacs don't. We depend on the | |
213 | ;; Emacs behavior (which also is symmetric). | |
214 | (if (and (eolp) (nth 7 (parse-partial-sexp here (point)))) | |
215 | (condition-case nil (forward-char 1))) | |
216 | t) | |
217 | ;; When we got newline terminated comments, | |
218 | ;; forward-comment in all supported emacsen so far will | |
219 | ;; stop at eol of each line not ending with a comment when | |
220 | ;; moving backwards. The following corrects for it when | |
221 | ;; count is -1. The other common case, when count is | |
222 | ;; large and negative, works regardless. It's too much | |
223 | ;; work to correct for the rest of the cases. | |
224 | (skip-chars-backward " \t\n\r\f") | |
225 | (if (bobp) | |
226 | ;; Some emacsen return t when moving backwards at bob. | |
227 | nil | |
228 | (re-search-forward "[\n\r]" here t) | |
229 | (if (forward-comment count) | |
230 | (if (eolp) (forward-comment -1) t)))))) | |
231 | ||
785eecbb RS |
232 | (defmacro c-add-syntax (symbol &optional relpos) |
233 | ;; a simple macro to append the syntax in symbol to the syntax list. | |
234 | ;; try to increase performance by using this macro | |
51f606de | 235 | `(setq syntax (cons (cons ,symbol ,relpos) syntax))) |
785eecbb | 236 | |
51f606de GM |
237 | (defmacro c-add-class-syntax (symbol classkey) |
238 | ;; The inclass and class-close syntactic symbols are added in | |
239 | ;; several places and some work is needed to fix everything. | |
240 | ;; Therefore it's collected here. | |
241 | `(save-restriction | |
242 | (widen) | |
243 | (let ((symbol ,symbol) | |
244 | (classkey ,classkey)) | |
245 | (goto-char (aref classkey 1)) | |
246 | (if (and (eq symbol 'inclass) (= (point) (c-point 'boi))) | |
247 | (c-add-syntax symbol (point)) | |
248 | (c-add-syntax symbol (aref classkey 0)) | |
249 | (if (and c-inexpr-class-key (c-looking-at-inexpr-block)) | |
250 | (c-add-syntax 'inexpr-class)))))) | |
251 | ||
785eecbb RS |
252 | (defsubst c-intersect-lists (list alist) |
253 | ;; return the element of ALIST that matches the first element found | |
254 | ;; in LIST. Uses assq. | |
255 | (let (match) | |
256 | (while (and list | |
257 | (not (setq match (assq (car list) alist)))) | |
258 | (setq list (cdr list))) | |
259 | match)) | |
260 | ||
261 | (defsubst c-lookup-lists (list alist1 alist2) | |
262 | ;; first, find the first entry from LIST that is present in ALIST1, | |
263 | ;; then find the entry in ALIST2 for that entry. | |
264 | (assq (car (c-intersect-lists list alist1)) alist2)) | |
265 | ||
266 | (defsubst c-langelem-col (langelem &optional preserve-point) | |
267 | ;; convenience routine to return the column of langelem's relpos. | |
268 | ;; Leaves point at the relpos unless preserve-point is non-nil. | |
bbfbe5ec GM |
269 | (if (cdr langelem) |
270 | (let ((here (point))) | |
271 | (goto-char (cdr langelem)) | |
272 | (prog1 (current-column) | |
273 | (if preserve-point | |
274 | (goto-char here)) | |
275 | )) | |
276 | 0)) | |
785eecbb | 277 | |
51f606de | 278 | (defmacro c-update-modeline () |
785eecbb | 279 | ;; set the c-auto-hungry-string for the correct designation on the modeline |
51f606de GM |
280 | `(progn |
281 | (setq c-auto-hungry-string | |
282 | (if c-auto-newline | |
283 | (if c-hungry-delete-key "/ah" "/a") | |
284 | (if c-hungry-delete-key "/h" nil))) | |
285 | (force-mode-line-update))) | |
785eecbb RS |
286 | |
287 | (defsubst c-keep-region-active () | |
288 | ;; Do whatever is necessary to keep the region active in XEmacs. | |
289 | ;; Ignore byte-compiler warnings you might see. This is not needed | |
290 | ;; for Emacs. | |
291 | (and (boundp 'zmacs-region-stays) | |
292 | (setq zmacs-region-stays t))) | |
293 | ||
0ec8351b BW |
294 | (defsubst c-region-is-active-p () |
295 | ;; Return t when the region is active. The determination of region | |
296 | ;; activeness is different in both Emacs and XEmacs. | |
297 | (cond | |
298 | ;; XEmacs | |
299 | ((and (fboundp 'region-active-p) | |
51f606de | 300 | (boundp 'zmacs-regions) |
0ec8351b BW |
301 | zmacs-regions) |
302 | (region-active-p)) | |
303 | ;; Emacs | |
304 | ((boundp 'mark-active) mark-active) | |
305 | ;; fallback; shouldn't get here | |
306 | (t (mark t)))) | |
307 | ||
308 | (defsubst c-major-mode-is (mode) | |
309 | (eq (derived-mode-class major-mode) mode)) | |
310 | ||
51f606de GM |
311 | (defmacro c-with-syntax-table (table &rest code) |
312 | ;; Temporarily switches to the specified syntax table in a failsafe | |
313 | ;; way to execute code. | |
314 | `(let ((c-with-syntax-table-orig-table (syntax-table))) | |
315 | (unwind-protect | |
316 | (progn | |
317 | (set-syntax-table ,table) | |
318 | ,@code) | |
319 | (set-syntax-table c-with-syntax-table-orig-table)))) | |
320 | (put 'c-with-syntax-table 'lisp-indent-function 1) | |
321 | ||
785eecbb RS |
322 | \f |
323 | (provide 'cc-defs) | |
324 | ;;; cc-defs.el ends here |