cc-mode.el 68 KB
Newer Older
1
;;; cc-mode.el --- major mode for editing C and similar languages
Richard M. Stallman's avatar
Richard M. Stallman committed
2

3
;; Copyright (C) 1985, 1987, 1992-2013 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
4

5 6 7
;; Authors:    2003- Alan Mackenzie
;;             1998- Martin Stjernholm
;;             1992-1999 Barry A. Warsaw
8 9
;;             1987 Dave Detlefs
;;             1987 Stewart Clamen
Richard M. Stallman's avatar
Richard M. Stallman committed
10
;;             1985 Richard M. Stallman
Barry A. Warsaw's avatar
Barry A. Warsaw committed
11
;; Maintainer: bug-cc-mode@gnu.org
Richard M. Stallman's avatar
Richard M. Stallman committed
12
;; Created:    a long, long, time ago. adapted from the original c-mode.el
13
;; Keywords:   c languages
Richard M. Stallman's avatar
Richard M. Stallman committed
14 15 16

;; This file is part of GNU Emacs.

17
;; GNU Emacs is free software: you can redistribute it and/or modify
Richard M. Stallman's avatar
Richard M. Stallman committed
18
;; it under the terms of the GNU General Public License as published by
19 20
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
Richard M. Stallman's avatar
Richard M. Stallman committed
21 22 23 24 25 26 27

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
28
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Richard M. Stallman's avatar
Richard M. Stallman committed
29

30
;;; Commentary:
Gerd Moellmann's avatar
Gerd Moellmann committed
31 32 33

;; NOTE: Read the commentary below for the right way to submit bug reports!
;; NOTE: See the accompanying texinfo manual for details on using this mode!
34
;; Note: The version string is in cc-defs.
Richard M. Stallman's avatar
Richard M. Stallman committed
35 36

;; This package provides GNU Emacs major modes for editing C, C++,
37 38 39 40
;; Objective-C, Java, CORBA's IDL, Pike and AWK code.  As of the
;; latest Emacs and XEmacs releases, it is the default package for
;; editing these languages.  This package is called "CC Mode", and
;; should be spelled exactly this way.
Barry A. Warsaw's avatar
Barry A. Warsaw committed
41 42

;; CC Mode supports K&R and ANSI C, ANSI C++, Objective-C, Java,
43 44 45 46 47
;; CORBA's IDL, Pike and AWK with a consistent indentation model
;; across all modes.  This indentation model is intuitive and very
;; flexible, so that almost any desired style of indentation can be
;; supported.  Installation, usage, and programming details are
;; contained in an accompanying texinfo manual.
Richard M. Stallman's avatar
Richard M. Stallman committed
48 49 50 51 52

;; CC Mode's immediate ancestors were, c++-mode.el, cplus-md.el, and
;; cplus-md1.el..

;; To submit bug reports, type "C-c C-b".  These will be sent to
Barry A. Warsaw's avatar
Barry A. Warsaw committed
53 54 55 56
;; bug-gnu-emacs@gnu.org (mirrored as the Usenet newsgroup
;; gnu.emacs.bug) as well as bug-cc-mode@gnu.org, which directly
;; contacts the CC Mode maintainers.  Questions can sent to
;; help-gnu-emacs@gnu.org (mirrored as gnu.emacs.help) and/or
Gerd Moellmann's avatar
Gerd Moellmann committed
57 58
;; bug-cc-mode@gnu.org.  Please do not send bugs or questions to our
;; personal accounts; we reserve the right to ignore such email!
Richard M. Stallman's avatar
Richard M. Stallman committed
59 60 61 62 63 64 65 66

;; Many, many thanks go out to all the folks on the beta test list.
;; Without their patience, testing, insight, code contributions, and
;; encouragement CC Mode would be a far inferior package.

;; You can get the latest version of CC Mode, including PostScript
;; documentation and separate individual files from:
;;
67
;;     http://cc-mode.sourceforge.net/
Barry A. Warsaw's avatar
Barry A. Warsaw committed
68 69 70
;;
;; You can join a moderated CC Mode announcement-only mailing list by
;; visiting
Richard M. Stallman's avatar
Richard M. Stallman committed
71
;;
72
;;    http://lists.sourceforge.net/mailman/listinfo/cc-mode-announce
Richard M. Stallman's avatar
Richard M. Stallman committed
73 74 75

;;; Code:

76 77 78 79
;; For Emacs < 22.2.
(eval-and-compile
  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))

Gerd Moellmann's avatar
Gerd Moellmann committed
80 81
(eval-when-compile
  (let ((load-path
Gerd Moellmann's avatar
Gerd Moellmann committed
82 83 84
	 (if (and (boundp 'byte-compile-dest-file)
		  (stringp byte-compile-dest-file))
	     (cons (file-name-directory byte-compile-dest-file) load-path)
Gerd Moellmann's avatar
Gerd Moellmann committed
85
	   load-path)))
86
    (load "cc-bytecomp" nil t)))
Gerd Moellmann's avatar
Gerd Moellmann committed
87 88 89

(cc-require 'cc-defs)
(cc-require 'cc-vars)
90
(cc-require-when-compile 'cc-langs)
Gerd Moellmann's avatar
Gerd Moellmann committed
91
(cc-require 'cc-engine)
92
(cc-require 'cc-styles)
Gerd Moellmann's avatar
Gerd Moellmann committed
93 94
(cc-require 'cc-cmds)
(cc-require 'cc-align)
95
(cc-require 'cc-menus)
96
(cc-require 'cc-guess)
Gerd Moellmann's avatar
Gerd Moellmann committed
97

98
;; Silence the compiler.
99 100
(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
(cc-bytecomp-defun run-mode-hooks)	; Emacs 21.1
Gerd Moellmann's avatar
Gerd Moellmann committed
101

102 103 104 105 106
;; We set these variables during mode init, yet we don't require
;; font-lock.
(cc-bytecomp-defvar font-lock-defaults)
(cc-bytecomp-defvar font-lock-syntactic-keywords)

Gerd Moellmann's avatar
Gerd Moellmann committed
107 108
;; Menu support for both XEmacs and Emacs.  If you don't have easymenu
;; with your version of Emacs, you are incompatible!
109 110
(cc-external-require 'easymenu)

111 112
;; Autoload directive for emacsen that doesn't have an older CC Mode
;; version in the dist.
113
(autoload 'subword-mode "subword"
114 115
  "Mode enabling subword movement and editing keys." t)

116 117
;; Load cc-fonts first after font-lock is loaded, since it isn't
;; necessary until font locking is requested.
118 119 120
; (eval-after-load "font-lock" ; 2006-07-09: font-lock is now preloaded.
;   '
(require 'cc-fonts) ;)
121

122 123 124 125 126 127

;; Other modes and packages which depend on CC Mode should do the
;; following to make sure everything is loaded and available for their
;; use:
;;
;; (require 'cc-mode)
128 129 130
;;
;; And in the major mode function:
;;
131 132 133 134
;; (c-initialize-cc-mode t)
;; (c-init-language-vars some-mode)
;; (c-common-init 'some-mode) ; Or perhaps (c-basic-common-init 'some-mode)
;;
135 136 137 138 139 140 141 142 143 144
;; If you're not writing a derived mode using the language variable
;; system, then some-mode is one of the language modes directly
;; supported by CC Mode.  You can then use (c-init-language-vars-for
;; 'some-mode) instead of `c-init-language-vars'.
;; `c-init-language-vars-for' is a function that avoids the rather
;; large expansion of `c-init-language-vars'.
;;
;; If you use `c-basic-common-init' then you might want to call
;; `c-font-lock-init' too to set up CC Mode's font lock support.
;;
145 146 147
;; See cc-langs.el for further info.  A small example of a derived mode
;; is also available at <http://cc-mode.sourceforge.net/
;; derived-mode-ex.el>.
148

149 150 151
(defun c-leave-cc-mode-mode ()
  (setq c-buffer-is-cc-mode nil))

152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
(defun c-init-language-vars-for (mode)
  "Initialize the language variables for one of the language modes
directly supported by CC Mode.  This can be used instead of the
`c-init-language-vars' macro if the language you want to use is one of
those, rather than a derived language defined through the language
variable system (see \"cc-langs.el\")."
  (cond ((eq mode 'c-mode)    (c-init-language-vars c-mode))
	((eq mode 'c++-mode)  (c-init-language-vars c++-mode))
	((eq mode 'objc-mode) (c-init-language-vars objc-mode))
	((eq mode 'java-mode) (c-init-language-vars java-mode))
	((eq mode 'idl-mode)  (c-init-language-vars idl-mode))
	((eq mode 'pike-mode) (c-init-language-vars pike-mode))
	((eq mode 'awk-mode)  (c-init-language-vars awk-mode))
	(t (error "Unsupported mode %s" mode))))

167
;;;###autoload
168 169 170 171
(defun c-initialize-cc-mode (&optional new-style-init)
  "Initialize CC Mode for use in the current buffer.
If the optional NEW-STYLE-INIT is nil or left out then all necessary
initialization to run CC Mode for the C language is done.  Otherwise
172 173 174
only some basic setup is done, and a call to `c-init-language-vars' or
`c-init-language-vars-for' is necessary too (which gives more
control).  See \"cc-mode.el\" for more info."
175

176
  (setq c-buffer-is-cc-mode t)
177

Barry A. Warsaw's avatar
Barry A. Warsaw committed
178 179 180 181 182
  (let ((initprop 'cc-mode-is-initialized)
	c-initialization-ok)
    (unless (get 'c-initialize-cc-mode initprop)
      (unwind-protect
	  (progn
Gerd Moellmann's avatar
Gerd Moellmann committed
183 184
	    (put 'c-initialize-cc-mode initprop t)
	    (c-initialize-builtin-style)
Barry A. Warsaw's avatar
Barry A. Warsaw committed
185
	    (run-hooks 'c-initialization-hook)
Gerd Moellmann's avatar
Gerd Moellmann committed
186 187
	    ;; Fix obsolete variables.
	    (if (boundp 'c-comment-continuation-stars)
188 189
		(setq c-block-comment-prefix
		      (symbol-value 'c-comment-continuation-stars)))
190
	    (add-hook 'change-major-mode-hook 'c-leave-cc-mode-mode)
Barry A. Warsaw's avatar
Barry A. Warsaw committed
191 192
	    (setq c-initialization-ok t))
	;; Will try initialization hooks again if they failed.
193 194 195
	(put 'c-initialize-cc-mode initprop c-initialization-ok))))

  (unless new-style-init
196
    (c-init-language-vars-for 'c-mode)))
197

Richard M. Stallman's avatar
Richard M. Stallman committed
198

199 200
;;; Common routines.

Gerd Moellmann's avatar
Gerd Moellmann committed
201 202 203 204 205
(defvar c-mode-base-map ()
  "Keymap shared by all CC Mode related modes.")

(defun c-make-inherited-keymap ()
  (let ((map (make-sparse-keymap)))
206 207 208
    ;; Necessary to use `cc-bytecomp-fboundp' below since this
    ;; function is called from top-level forms that are evaluated
    ;; while cc-bytecomp is active when one does M-x eval-buffer.
Gerd Moellmann's avatar
Gerd Moellmann committed
209
    (cond
210
     ;; Emacs
211
     ((cc-bytecomp-fboundp 'set-keymap-parent)
Gerd Moellmann's avatar
Gerd Moellmann committed
212
      (set-keymap-parent map c-mode-base-map))
213
     ;; XEmacs
214
     ((fboundp 'set-keymap-parents)
215
      (set-keymap-parents map c-mode-base-map))
Gerd Moellmann's avatar
Gerd Moellmann committed
216 217 218 219
     ;; incompatible
     (t (error "CC Mode is incompatible with this version of Emacs")))
    map))

220
(defun c-define-abbrev-table (name defs &optional doc)
221 222
  ;; Compatibility wrapper for `define-abbrev' which passes a non-nil
  ;; sixth argument for SYSTEM-FLAG in emacsen that support it
223
  ;; (currently only Emacs >= 21.2).
224
  (let ((table (or (and (boundp name) (symbol-value name))
225 226 227 228 229
		   (progn (condition-case nil
                              (define-abbrev-table name nil doc)
                            (wrong-number-of-arguments ;E.g. Emacs<23.
                             (eval `(defvar ,name nil ,doc))
                             (define-abbrev-table name nil)))
230
			  (symbol-value name)))))
231 232 233 234 235 236
    (while defs
      (condition-case nil
	  (apply 'define-abbrev table (append (car defs) '(t)))
	(wrong-number-of-arguments
	 (apply 'define-abbrev table (car defs))))
      (setq defs (cdr defs)))))
237
(put 'c-define-abbrev-table 'lisp-indent-function 1)
238

239 240 241 242 243 244 245 246
(defun c-bind-special-erase-keys ()
  ;; Only used in Emacs to bind C-c C-<delete> and C-c C-<backspace>
  ;; to the proper keys depending on `normal-erase-is-backspace'.
  (if normal-erase-is-backspace
      (progn
	(define-key c-mode-base-map (kbd "C-c C-<delete>")
	  'c-hungry-delete-forward)
	(define-key c-mode-base-map (kbd "C-c C-<backspace>")
247
	  'c-hungry-delete-backwards))
248
    (define-key c-mode-base-map (kbd "C-c C-<delete>")
249
      'c-hungry-delete-backwards)
250 251 252
    (define-key c-mode-base-map (kbd "C-c C-<backspace>")
      'c-hungry-delete-forward)))

Gerd Moellmann's avatar
Gerd Moellmann committed
253 254
(if c-mode-base-map
    nil
255

Gerd Moellmann's avatar
Gerd Moellmann committed
256
  (setq c-mode-base-map (make-sparse-keymap))
257

Gerd Moellmann's avatar
Gerd Moellmann committed
258 259 260 261 262 263 264 265 266 267 268 269 270
  ;; Separate M-BS from C-M-h.  The former should remain
  ;; backward-kill-word.
  (define-key c-mode-base-map [(control meta h)] 'c-mark-function)
  (define-key c-mode-base-map "\e\C-q"    'c-indent-exp)
  (substitute-key-definition 'backward-sentence
			     'c-beginning-of-statement
			     c-mode-base-map global-map)
  (substitute-key-definition 'forward-sentence
			     'c-end-of-statement
			     c-mode-base-map global-map)
  (substitute-key-definition 'indent-new-comment-line
			     'c-indent-new-comment-line
			     c-mode-base-map global-map)
271
  (substitute-key-definition 'indent-for-tab-command
272 273 274
			     ;; XXX Is this the right thing to do
			     ;; here?
			     'c-indent-line-or-region
275
			     c-mode-base-map global-map)
276 277 278 279 280 281
  (when (fboundp 'comment-indent-new-line)
    ;; indent-new-comment-line has changed name to
    ;; comment-indent-new-line in Emacs 21.
    (substitute-key-definition 'comment-indent-new-line
			       'c-indent-new-comment-line
			       c-mode-base-map global-map))
282

Gerd Moellmann's avatar
Gerd Moellmann committed
283
  ;; RMS says don't make these the default.
284
  ;; (April 2006): RMS has now approved these commands as defaults.
285 286 287
  (unless (memq 'argumentative-bod-function c-emacs-features)
    (define-key c-mode-base-map "\e\C-a"    'c-beginning-of-defun)
    (define-key c-mode-base-map "\e\C-e"    'c-end-of-defun))
288

Gerd Moellmann's avatar
Gerd Moellmann committed
289 290 291
  (define-key c-mode-base-map "\C-c\C-n"  'c-forward-conditional)
  (define-key c-mode-base-map "\C-c\C-p"  'c-backward-conditional)
  (define-key c-mode-base-map "\C-c\C-u"  'c-up-conditional)
292 293 294 295 296 297 298

  ;; It doesn't suffice to put `c-fill-paragraph' on
  ;; `fill-paragraph-function' since `c-fill-paragraph' must be called
  ;; before any fill prefix adaption is done.  E.g. `filladapt-mode'
  ;; replaces `fill-paragraph' and does the adaption before calling
  ;; `fill-paragraph-function', and we have to mask comments etc
  ;; before that.  Also, `c-fill-paragraph' chains on to
Paul Eggert's avatar
Paul Eggert committed
299
  ;; `fill-paragraph' and the value on `fill-paragraph-function' to
300
  ;; do the actual filling work.
Gerd Moellmann's avatar
Gerd Moellmann committed
301 302 303 304 305 306
  (substitute-key-definition 'fill-paragraph 'c-fill-paragraph
			     c-mode-base-map global-map)
  ;; In XEmacs the default fill function is called
  ;; fill-paragraph-or-region.
  (substitute-key-definition 'fill-paragraph-or-region 'c-fill-paragraph
			     c-mode-base-map global-map)
307

308 309 310 311 312
  ;; We bind the forward deletion key and (implicitly) C-d to
  ;; `c-electric-delete-forward', and the backward deletion key to
  ;; `c-electric-backspace'.  The hungry variants are bound to the
  ;; same keys but prefixed with C-c.  This implies that C-c C-d is
  ;; `c-hungry-delete-forward'.  For consistency, we bind not only C-c
313 314 315 316 317
  ;; <backspace> to `c-hungry-delete-backwards' but also
  ;; C-c C-<backspace>, so that the Ctrl key can be held down during
  ;; the whole sequence regardless of the direction.  This in turn
  ;; implies that we bind C-c C-<delete> to `c-hungry-delete-forward',
  ;; for the same reason.
318

319 320 321 322 323 324
  ;; Bind the electric deletion functions to C-d and DEL.  Emacs 21
  ;; automatically maps the [delete] and [backspace] keys to these two
  ;; depending on window system and user preferences.  (In earlier
  ;; versions it's possible to do the same by using `function-key-map'.)
  (define-key c-mode-base-map "\C-d" 'c-electric-delete-forward)
  (define-key c-mode-base-map "\177" 'c-electric-backspace)
325
  (define-key c-mode-base-map "\C-c\C-d"     'c-hungry-delete-forward)
326 327
  (define-key c-mode-base-map [?\C-c ?\d]    'c-hungry-delete-backwards)
  (define-key c-mode-base-map [?\C-c ?\C-\d] 'c-hungry-delete-backwards)
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
  (define-key c-mode-base-map [?\C-c deletechar] 'c-hungry-delete-forward) ; C-c <delete> on a tty.
  (define-key c-mode-base-map [?\C-c (control deletechar)] ; C-c C-<delete> on a tty.
    'c-hungry-delete-forward)
  (when (boundp 'normal-erase-is-backspace)
    ;; The automatic C-d and DEL mapping functionality doesn't extend
    ;; to special combinations like C-c C-<delete>, so we have to hook
    ;; into the `normal-erase-is-backspace' system to bind it directly
    ;; as appropriate.
    (add-hook 'normal-erase-is-backspace-hook 'c-bind-special-erase-keys)
    (c-bind-special-erase-keys))

  (when (fboundp 'delete-forward-p)
    ;; In XEmacs we fix the forward and backward deletion behavior by
    ;; binding the keysyms for the [delete] and [backspace] keys
    ;; directly, and use `delete-forward-p' to decide what [delete]
    ;; should do.  That's done in the XEmacs specific
    ;; `c-electric-delete' and `c-hungry-delete' functions.
345
    (define-key c-mode-base-map [delete]    'c-electric-delete)
346 347 348
    (define-key c-mode-base-map [backspace] 'c-electric-backspace)
    (define-key c-mode-base-map (kbd "C-c <delete>") 'c-hungry-delete)
    (define-key c-mode-base-map (kbd "C-c C-<delete>") 'c-hungry-delete)
349 350 351 352
    (define-key c-mode-base-map (kbd "C-c <backspace>")
      'c-hungry-delete-backwards)
    (define-key c-mode-base-map (kbd "C-c C-<backspace>")
      'c-hungry-delete-backwards))
353 354 355 356

  (define-key c-mode-base-map "#"         'c-electric-pound)
  (define-key c-mode-base-map "{"         'c-electric-brace)
  (define-key c-mode-base-map "}"         'c-electric-brace)
Gerd Moellmann's avatar
Gerd Moellmann committed
357
  (define-key c-mode-base-map "/"         'c-electric-slash)
358 359 360 361 362 363 364
  (define-key c-mode-base-map "*"         'c-electric-star)
  (define-key c-mode-base-map ";"         'c-electric-semi&comma)
  (define-key c-mode-base-map ","         'c-electric-semi&comma)
  (define-key c-mode-base-map ":"         'c-electric-colon)
  (define-key c-mode-base-map "("         'c-electric-paren)
  (define-key c-mode-base-map ")"         'c-electric-paren)

Gerd Moellmann's avatar
Gerd Moellmann committed
365
  (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region)
366
  (define-key c-mode-base-map "\C-c\C-a"  'c-toggle-auto-newline)
Gerd Moellmann's avatar
Gerd Moellmann committed
367 368
  (define-key c-mode-base-map "\C-c\C-b"  'c-submit-bug-report)
  (define-key c-mode-base-map "\C-c\C-c"  'comment-region)
369
  (define-key c-mode-base-map "\C-c\C-l"  'c-toggle-electric-state)
Gerd Moellmann's avatar
Gerd Moellmann committed
370
  (define-key c-mode-base-map "\C-c\C-o"  'c-set-offset)
371
  (define-key c-mode-base-map "\C-c\C-q"  'c-indent-defun)
Gerd Moellmann's avatar
Gerd Moellmann committed
372
  (define-key c-mode-base-map "\C-c\C-s"  'c-show-syntactic-information)
373
  ;; (define-key c-mode-base-map "\C-c\C-t"  'c-toggle-auto-hungry-state)  Commented out by ACM, 2005-03-05.
Gerd Moellmann's avatar
Gerd Moellmann committed
374 375 376
  (define-key c-mode-base-map "\C-c."     'c-set-style)
  ;; conflicts with OOBR
  ;;(define-key c-mode-base-map "\C-c\C-v"  'c-version)
377
  ;; (define-key c-mode-base-map "\C-c\C-y"  'c-toggle-hungry-state)  Commented out by ACM, 2005-11-22.
378
  (define-key c-mode-base-map "\C-c\C-w" 'subword-mode)
Gerd Moellmann's avatar
Gerd Moellmann committed
379 380 381 382 383
  )

;; We don't require the outline package, but we configure it a bit anyway.
(cc-bytecomp-defvar outline-level)

384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
(defun c-mode-menu (modestr)
  "Return a menu spec suitable for `easy-menu-define' that is exactly
like the C mode menu except that the menu bar item name is MODESTR
instead of \"C\".

This function is provided for compatibility only; derived modes should
preferably use the `c-mode-menu' language constant directly."
  (cons modestr (c-lang-const c-mode-menu c)))

;; Ugly hack to pull in the definition of `c-populate-syntax-table'
;; from cc-langs to make it available at runtime.  It's either this or
;; moving the definition for it to cc-defs, but that would mean to
;; break up the syntax table setup over two files.
(defalias 'c-populate-syntax-table
  (cc-eval-when-compile
    (let ((f (symbol-function 'c-populate-syntax-table)))
      (if (byte-code-function-p f) f (byte-compile f)))))

402 403 404 405 406 407 408
;; CAUTION: Try to avoid installing things on
;; `before-change-functions'.  The macro `combine-after-change-calls'
;; is used and it doesn't work if there are things on that hook.  That
;; can cause font lock functions to run in inconvenient places during
;; temporary changes in some font lock support modes, causing extra
;; unnecessary work and font lock glitches due to interactions between
;; various text properties.
409
;;
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
;; (2007-02-12): The macro `combine-after-change-calls' ISN'T used any
;; more.

(defun c-unfind-enclosing-token (pos)
  ;; If POS is wholly inside a token, remove that id from
  ;; `c-found-types', should it be present.  Return t if we were in an
  ;; id, else nil.
  (save-excursion
    (let ((tok-beg (progn (goto-char pos)
			  (and (c-beginning-of-current-token) (point))))
	  (tok-end (progn (goto-char pos)
			  (and (c-end-of-current-token) (point)))))
      (when (and tok-beg tok-end)
	(c-unfind-type (buffer-substring-no-properties tok-beg tok-end))
	t))))

(defun c-unfind-coalesced-tokens (beg end)
  ;; unless the non-empty region (beg end) is entirely WS and there's at
  ;; least one character of WS just before or after this region, remove
  ;; the tokens which touch the region from `c-found-types' should they
  ;; be present.
  (or (c-partial-ws-p beg end)
      (save-excursion
	(progn
	  (goto-char beg)
	  (or (eq beg (point-min))
	      (c-skip-ws-backward (1- beg))
	      (/= (point) beg)
	      (= (c-backward-token-2) 1)
	      (c-unfind-type (buffer-substring-no-properties
			      (point) beg)))
	  (goto-char end)
	  (or (eq end (point-max))
	      (c-skip-ws-forward (1+ end))
	      (/= (point) end)
	      (progn (forward-char) (c-end-of-current-token) nil)
	      (c-unfind-type (buffer-substring-no-properties
			      end (point))))))))

;; c-maybe-stale-found-type records a place near the region being
450
;; changed where an element of `found-types' might become stale.  It
451 452 453
;; is set in c-before-change and is either nil, or has the form:
;;
;;   (c-decl-id-start "foo" 97 107  " (* ooka) " "o"), where
454
;;
455 456
;; o - `c-decl-id-start' is the c-type text property value at buffer
;;   pos 96.
457
;;
458 459 460
;; o - 97 107 is the region potentially containing the stale type -
;;   this is delimited by a non-nil c-type text property at 96 and
;;   either another one or a ";", "{", or "}" at 107.
461
;;
462 463 464 465 466 467 468 469
;; o - " (* ooka) " is the (before change) buffer portion containing
;;   the suspect type (here "ooka").
;;
;; o - "o" is the buffer contents which is about to be deleted.  This
;;   would be the empty string for an insertion.
(defvar c-maybe-stale-found-type nil)
(make-variable-buffer-local 'c-maybe-stale-found-type)

470 471 472 473 474 475 476 477 478 479 480 481 482
(defun c-basic-common-init (mode default-style)
  "Do the necessary initialization for the syntax handling routines
and the line breaking/filling code.  Intended to be used by other
packages that embed CC Mode.

MODE is the CC Mode flavor to set up, e.g. 'c-mode or 'java-mode.
DEFAULT-STYLE tells which indentation style to install.  It has the
same format as `c-default-style'.

Note that `c-init-language-vars' must be called before this function.
This function cannot do that since `c-init-language-vars' is a macro
that requires a literal mode spec at compile time."

483 484
  (setq c-buffer-is-cc-mode mode)

Gerd Moellmann's avatar
Gerd Moellmann committed
485 486 487 488 489
  ;; these variables should always be buffer local; they do not affect
  ;; indentation style.
  (make-local-variable 'comment-start)
  (make-local-variable 'comment-end)
  (make-local-variable 'comment-start-skip)
Juanma Barranquero's avatar
Juanma Barranquero committed
490

491 492 493 494 495
  (make-local-variable 'paragraph-start)
  (make-local-variable 'paragraph-separate)
  (make-local-variable 'paragraph-ignore-fill-prefix)
  (make-local-variable 'adaptive-fill-mode)
  (make-local-variable 'adaptive-fill-regexp)
496
  (make-local-variable 'fill-paragraph-handle-comment)
497

Gerd Moellmann's avatar
Gerd Moellmann committed
498
  ;; now set their values
499 500 501 502 503 504 505
  (set (make-local-variable 'parse-sexp-ignore-comments) t)
  (set (make-local-variable 'indent-line-function) 'c-indent-line)
  (set (make-local-variable 'indent-region-function) 'c-indent-region)
  (set (make-local-variable 'normal-auto-fill-function) 'c-do-auto-fill)
  (set (make-local-variable 'comment-multi-line) t)
  (set (make-local-variable 'comment-line-break-function)
       'c-indent-new-comment-line)
506

507 508 509
  ;; For the benefit of adaptive file, which otherwise mis-fills.
  (setq fill-paragraph-handle-comment nil)

510 511 512
  ;; Install `c-fill-paragraph' on `fill-paragraph-function' so that a
  ;; direct call to `fill-paragraph' behaves better.  This still
  ;; doesn't work with filladapt but it's better than nothing.
513
  (set (make-local-variable 'fill-paragraph-function) 'c-fill-paragraph)
514

Paul Eggert's avatar
Paul Eggert committed
515
  ;; Initialize the cache of brace pairs, and opening braces/brackets/parens.
516 517
  (c-state-cache-init)

518
  (when (or c-recognize-<>-arglists
519
	    (c-major-mode-is 'awk-mode)
520
	    (c-major-mode-is '(java-mode c-mode c++-mode objc-mode)))
521 522 523 524 525 526 527 528 529 530
    ;; We'll use the syntax-table text property to change the syntax
    ;; of some chars for this language, so do the necessary setup for
    ;; that.
    ;;
    ;; Note to other package developers: It's ok to turn this on in CC
    ;; Mode buffers when CC Mode doesn't, but it's not ok to turn it
    ;; off if CC Mode has turned it on.

    ;; Emacs.
    (when (boundp 'parse-sexp-lookup-properties)
531
      (set (make-local-variable 'parse-sexp-lookup-properties) t))
532 533 534

    ;; Same as above for XEmacs.
    (when (boundp 'lookup-syntax-properties)
535
      (set (make-local-variable 'lookup-syntax-properties) t)))
536

537
  ;; Use this in Emacs 21+ to avoid meddling with the rear-nonsticky
538 539
  ;; property on each character.
  (when (boundp 'text-property-default-nonsticky)
540 541
    (mapc (lambda (tprop)
	    (unless (assq tprop text-property-default-nonsticky)
542 543
	      (set (make-local-variable 'text-property-default-nonsticky)
                   (cons `(,tprop . t) text-property-default-nonsticky))))
544
	  '(syntax-table category c-type)))
545 546 547

  ;; In Emacs 21 and later it's possible to turn off the ad-hoc
  ;; heuristic that open parens in column 0 are defun starters.  Since
548 549
  ;; we have c-state-cache, that heuristic isn't useful and only causes
  ;; trouble, so turn it off.
550 551 552 553 554
;; 2006/12/17: This facility is somewhat confused, and doesn't really seem
;; helpful.  Comment it out for now.
;;   (when (memq 'col-0-paren c-emacs-features)
;;     (make-local-variable 'open-paren-in-column-0-is-defun-start)
;;     (setq open-paren-in-column-0-is-defun-start nil))
555 556 557 558

  (c-clear-found-types)

  ;; now set the mode style based on default-style
559
  (let ((style (cc-choose-style-for-mode mode default-style)))
Gerd Moellmann's avatar
Gerd Moellmann committed
560 561 562 563 564 565 566 567 568 569 570 571
    ;; Override style variables if `c-old-style-variable-behavior' is
    ;; set.  Also override if we are using global style variables,
    ;; have already initialized a style once, and are switching to a
    ;; different style.  (It's doubtful whether this is desirable, but
    ;; the whole situation with nonlocal style variables is a bit
    ;; awkward.  It's at least the most compatible way with the old
    ;; style init procedure.)
    (c-set-style style (not (or c-old-style-variable-behavior
				(and (not c-style-variables-are-local-p)
				     c-indentation-style
				     (not (string-equal c-indentation-style
							style)))))))
572 573
  (c-setup-paragraph-variables)

Gerd Moellmann's avatar
Gerd Moellmann committed
574 575 576
  ;; we have to do something special for c-offsets-alist so that the
  ;; buffer local value has its own alist structure.
  (setq c-offsets-alist (copy-alist c-offsets-alist))
577

Gerd Moellmann's avatar
Gerd Moellmann committed
578
  ;; setup the comment indent variable in a Emacs version portable way
579
  (set (make-local-variable 'comment-indent-function) 'c-comment-indent)
580

581 582 583 584 585 586
;;   ;; Put submode indicators onto minor-mode-alist, but only once.
;;   (or (assq 'c-submode-indicators minor-mode-alist)
;;       (setq minor-mode-alist
;; 	    (cons '(c-submode-indicators c-submode-indicators)
;; 		  minor-mode-alist)))
  (c-update-modeline)
587

588 589
  ;; Install the functions that ensure that various internal caches
  ;; don't become invalid due to buffer changes.
590 591 592
  (when (featurep 'xemacs)
    (make-local-hook 'before-change-functions)
    (make-local-hook 'after-change-functions))
593
  (add-hook 'before-change-functions 'c-before-change nil t)
594
  (add-hook 'after-change-functions 'c-after-change nil t)
595
  (set (make-local-variable 'font-lock-extend-after-change-region-function)
596
 	'c-extend-after-change-region))	; Currently (2009-05) used by all
Paul Eggert's avatar
Paul Eggert committed
597
			; languages with #define (C, C++,; ObjC), and by AWK.
598 599 600 601 602 603 604 605 606

(defun c-setup-doc-comment-style ()
  "Initialize the variables that depend on the value of `c-doc-comment-style'."
  (when (and (featurep 'font-lock)
	     (symbol-value 'font-lock-mode))
    ;; Force font lock mode to reinitialize itself.
    (font-lock-mode 0)
    (font-lock-mode 1)))

607 608
;; Buffer local variables defining the region to be fontified by a font lock
;; after-change function.  They are set in c-after-change to
609 610
;; after-change-functions' BEG and END, and may be modified by functions in
;; `c-before-font-lock-functions'.
611 612 613 614 615
(defvar c-new-BEG 0)
(make-variable-buffer-local 'c-new-BEG)
(defvar c-new-END 0)
(make-variable-buffer-local 'c-new-END)

616 617 618 619 620 621 622 623 624
(defun c-common-init (&optional mode)
  "Common initialization for all CC Mode modes.
In addition to the work done by `c-basic-common-init' and
`c-font-lock-init', this function sets up various other things as
customary in CC Mode modes but which aren't strictly necessary for CC
Mode to operate correctly.

MODE is the symbol for the mode to initialize, like 'c-mode.  See
`c-basic-common-init' for details.  It's only optional to be
625
compatible with old code; callers should always specify it."
626 627 628 629

  (unless mode
    ;; Called from an old third party package.  The fallback is to
    ;; initialize for C.
630
    (c-init-language-vars-for 'c-mode))
631 632 633 634 635 636

  (c-basic-common-init mode c-default-style)
  (when mode
    ;; Only initialize font locking if we aren't called from an old package.
    (c-font-lock-init))

637 638 639
  ;; Starting a mode is a sort of "change".  So call the change functions...
  (save-restriction
    (widen)
Alan Mackenzie's avatar
Alan Mackenzie committed
640 641
    (setq c-new-BEG (point-min))
    (setq c-new-END (point-max))
642
    (save-excursion
643 644 645 646 647 648 649
      (mapc (lambda (fn)
	      (funcall fn (point-min) (point-max)))
	    c-get-state-before-change-functions)
      (mapc (lambda (fn)
	      (funcall fn (point-min) (point-max)
		       (- (point-max) (point-min))))
	    c-before-font-lock-functions)))
650

651 652
  (set (make-local-variable 'outline-regexp) "[^#\n\^M]")
  (set (make-local-variable 'outline-level) 'c-outline-level)
653 654 655
  (set (make-local-variable 'add-log-current-defun-function)
       (lambda ()
	 (or (c-cpp-define-name) (c-defun-name))))
656 657
  (let ((rfn (assq mode c-require-final-newline)))
    (when rfn
658
      (and (cdr rfn)
659 660
	   (set (make-local-variable 'require-final-newline)
                mode-require-final-newline)))))
Gerd Moellmann's avatar
Gerd Moellmann committed
661

662 663 664 665 666 667 668 669 670 671
(defun c-count-cfss (lv-alist)
  ;; LV-ALIST is an alist like `file-local-variables-alist'.  Count how many
  ;; elements with the key `c-file-style' there are in it.
  (let ((elt-ptr lv-alist) elt (cownt 0))
    (while elt-ptr
      (setq elt (car elt-ptr)
	    elt-ptr (cdr elt-ptr))
      (when (eq (car elt) 'c-file-style)
	(setq cownt (1+ cownt))))
    cownt))
Juanma Barranquero's avatar
Juanma Barranquero committed
672

673 674 675 676 677 678 679
(defun c-before-hack-hook ()
  "Set the CC Mode style and \"offsets\" when in the buffer's local variables.
They are set only when, respectively, the pseudo variables
`c-file-style' and `c-file-offsets' are present in the list.

This function is called from the hook `before-hack-local-variables-hook'."
  (when c-buffer-is-cc-mode
680 681
    (let ((mode-cons (assq 'mode file-local-variables-alist))
	  (stile (cdr (assq 'c-file-style file-local-variables-alist)))
682
	  (offsets (cdr (assq 'c-file-offsets file-local-variables-alist))))
683 684 685 686
      (when mode-cons
	(hack-one-local-variable (car mode-cons) (cdr mode-cons))
	(setq file-local-variables-alist
	      (delq mode-cons file-local-variables-alist)))
687 688
      (when stile
	(or (stringp stile) (error "c-file-style is not a string"))
689 690 691 692 693 694 695
	(if (boundp 'dir-local-variables-alist)
	    ;; Determine whether `c-file-style' was set in the file's local
	    ;; variables or in a .dir-locals.el (a directory setting).
	    (let ((cfs-in-file-and-dir-count
		   (c-count-cfss file-local-variables-alist))
		  (cfs-in-dir-count (c-count-cfss dir-local-variables-alist)))
	      (c-set-style stile
696 697
			   (and (= cfs-in-file-and-dir-count cfs-in-dir-count)
				'keep-defaults)))
698
	  (c-set-style stile)))
699 700 701 702 703 704 705 706
      (when offsets
	(mapc
	 (lambda (langentry)
	   (let ((langelem (car langentry))
		 (offset (cdr langentry)))
	     (c-set-offset langelem offset)))
	 offsets)))))

707 708 709 710
(defun c-remove-any-local-eval-or-mode-variables ()
  ;; If the buffer specifies `mode' or `eval' in its File Local Variable list
  ;; or on the first line, remove all occurrences.  See
  ;; `c-postprocess-file-styles' for justification.  There is no need to save
711 712
  ;; point here, or even bother too much about the buffer contents.  However,
  ;; DON'T mess up the kill-ring.
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740
  ;;
  ;; Most of the code here is derived from Emacs 21.3's `hack-local-variables'
  ;; in files.el.
  (goto-char (point-max))
  (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
  (let (lv-point (prefix "") (suffix ""))
    (when (let ((case-fold-search t))
	    (search-forward "Local Variables:" nil t))
      (setq lv-point (point))
      ;; The prefix is what comes before "local variables:" in its line.
      ;; The suffix is what comes after "local variables:" in its line.
      (skip-chars-forward " \t")
      (or (eolp)
	  (setq suffix (buffer-substring (point)
					 (progn (end-of-line) (point)))))
      (goto-char (match-beginning 0))
      (or (bolp)
	  (setq prefix
		(buffer-substring (point)
				  (progn (beginning-of-line) (point)))))

      (while (search-forward-regexp
	      (concat "^[ \t]*"
		      (regexp-quote prefix)
		      "\\(mode\\|eval\\):.*"
		      (regexp-quote suffix)
		      "$")
	      nil t)
741 742
	(forward-line 0)
	(delete-region (point) (progn (forward-line) (point)))))
743 744 745 746 747 748 749

    ;; Delete the first line, if we've got one, in case it contains a mode spec.
    (unless (and lv-point
		 (progn (goto-char lv-point)
			(forward-line 0)
			(bobp)))
      (goto-char (point-min))
750 751
      (unless (eobp)
	(delete-region (point) (progn (forward-line) (point)))))))
752

Gerd Moellmann's avatar
Gerd Moellmann committed
753
(defun c-postprocess-file-styles ()
754
  "Function that post processes relevant file local variables in CC Mode.
Gerd Moellmann's avatar
Gerd Moellmann committed
755 756 757 758 759 760
Currently, this function simply applies any style and offset settings
found in the file's Local Variable list.  It first applies any style
setting found in `c-file-style', then it applies any offset settings
it finds in `c-file-offsets'.

Note that the style variables are always made local to the buffer."
761

Gerd Moellmann's avatar
Gerd Moellmann committed
762
  ;; apply file styles and offsets
763 764 765
  (when c-buffer-is-cc-mode
    (if (or c-file-style c-file-offsets)
	(c-make-styles-buffer-local t))
766 767 768
    (when c-file-style
      (or (stringp c-file-style)
	  (error "c-file-style is not a string"))
769
      (c-set-style c-file-style))
770

771
    (and c-file-offsets
Glenn Morris's avatar
Glenn Morris committed
772
	 (mapc
773 774 775 776
	  (lambda (langentry)
	    (let ((langelem (car langentry))
		  (offset (cdr langentry)))
	      (c-set-offset langelem offset)))
777 778 779 780 781 782
	  c-file-offsets))
    ;; Problem: The file local variable block might have explicitly set a
    ;; style variable.  The `c-set-style' or `mapcar' call might have
    ;; overwritten this.  So we run `hack-local-variables' again to remedy
    ;; this.  There are no guarantees this will work properly, particularly as
    ;; we have no control over what the other hook functions on
783 784 785 786 787 788 789 790
    ;; `hack-local-variables-hook' would have done.  We now (2006/2/1) remove
    ;; any `eval' or `mode' expressions before we evaluate again (see below).
    ;; ACM, 2005/11/2.
    ;;
    ;; Problem (bug reported by Gustav Broberg): if one of the variables is
    ;; `mode', this will invoke c-mode (etc.) again, setting up the style etc.
    ;; We prevent this by temporarily removing `mode' from the Local Variables
    ;; section.
791
    (if (or c-file-style c-file-offsets)
792 793
	(let ((hack-local-variables-hook nil) (inhibit-read-only t))
	  (c-tentative-buffer-changes
794 795 796
	    (c-remove-any-local-eval-or-mode-variables)
	    (hack-local-variables))
	  nil))))
Gerd Moellmann's avatar
Gerd Moellmann committed
797

798 799 800
(if (boundp 'before-hack-local-variables-hook)
    (add-hook 'before-hack-local-variables-hook 'c-before-hack-hook)
  (add-hook 'hack-local-variables-hook 'c-postprocess-file-styles))
Gerd Moellmann's avatar
Gerd Moellmann committed
801

802 803
(defmacro c-run-mode-hooks (&rest hooks)
  ;; Emacs 21.1 has introduced a system with delayed mode hooks that
804
  ;; requires the use of the new function `run-mode-hooks'.
805 806 807 808
  (if (cc-bytecomp-fboundp 'run-mode-hooks)
      `(run-mode-hooks ,@hooks)
    `(progn ,@(mapcar (lambda (hook) `(run-hooks ,hook)) hooks))))

809 810 811 812 813 814 815 816 817 818 819 820

;;; Change hooks, linking with Font Lock.

;; Buffer local variables recording Beginning/End-of-Macro position before a
;; change, when a macro straddles, respectively, the BEG or END (or both) of
;; the change region.  Otherwise these have the values BEG/END.
(defvar c-old-BOM 0)
(make-variable-buffer-local 'c-old-BOM)
(defvar c-old-EOM 0)
(make-variable-buffer-local 'c-old-EOM)

(defun c-extend-region-for-CPP (beg end)
821 822
  ;; Set c-old-BOM or c-old-EOM respectively to BEG, END, each extended to the
  ;; beginning/end of any preprocessor construct they may be in.
823 824 825 826 827
  ;;
  ;; Point is undefined both before and after this function call; the buffer
  ;; has already been widened, and match-data saved.  The return value is
  ;; meaningless.
  ;;
828 829
  ;; This function is in the C/C++/ObjC values of
  ;; `c-get-state-before-change-functions' and is called exclusively as a
830 831 832 833 834 835
  ;; before change function.
  (goto-char beg)
  (c-beginning-of-macro)
  (setq c-old-BOM (point))

  (goto-char end)
836 837 838 839
  (when (c-beginning-of-macro)
    (c-end-of-macro)
    (or (eobp) (forward-char)))	 ; Over the terminating NL which may be marked
				 ; with a c-cpp-delimiter category property
840
  (setq c-old-EOM (point)))
841

842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
(defun c-extend-font-lock-region-for-macros (begg endd &optional old-len)
  ;; Extend the region (BEGG ENDD) to cover all (possibly changed)
  ;; preprocessor macros; return the cons (new-BEG . new-END).  OLD-LEN should
  ;; be either the old length parameter when called from an
  ;; after-change-function, or nil otherwise.  This defun uses the variables
  ;; c-old-BOM, c-new-BOM.
  ;;
  ;; Point is undefined on both entry and exit to this function.  The buffer
  ;; will have been widened on entry.
  (let (limits new-beg new-end)
    (goto-char c-old-BOM)	  ; already set to old start of macro or begg.
    (setq new-beg
	  (min begg
	       (if (setq limits (c-state-literal-at (point)))
		   (cdr limits)	    ; go forward out of any string or comment.
		 (point))))

    (goto-char endd)
    (if (setq limits (c-state-literal-at (point)))
	(goto-char (car limits)))  ; go backward out of any string or comment.
    (if (c-beginning-of-macro)
	(c-end-of-macro))
    (setq new-end (max endd
		       (if old-len
			   (+ (- c-old-EOM old-len) (- endd begg))
			 c-old-EOM)
		       (point)))
    (cons new-beg new-end)))

871
(defun c-neutralize-CPP-line (beg end)
872 873 874 875
  ;; BEG and END bound a region, typically a preprocessor line.  Put a
  ;; "punctuation" syntax-table property on syntactically obtrusive
  ;; characters, ones which would interact syntactically with stuff outside
  ;; this region.
876 877 878 879
  ;;
  ;; These are unmatched string delimiters, or unmatched
  ;; parens/brackets/braces.  An unclosed comment is regarded as valid, NOT
  ;; obtrusive.
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
  (save-excursion
    (let (s)
      (while
	  (progn
	    (setq s (parse-partial-sexp beg end -1))
	    (cond
	     ((< (nth 0 s) 0)		; found an unmated ),},]
	      (c-put-char-property (1- (point)) 'syntax-table '(1))
	      t)
	     ((nth 3 s)			; In a string
	      (c-put-char-property (nth 8 s) 'syntax-table '(1))
	      t)
	     ((> (nth 0 s) 0)		; In a (,{,[
	      (c-put-char-property (nth 1 s) 'syntax-table '(1))
	      t)
	     (t nil)))))))
896

897
(defun c-neutralize-syntax-in-and-mark-CPP (begg endd old-len)
898 899 900
  ;; (i) Extend the font lock region to cover all changed preprocessor
  ;; regions; it does this by setting the variables `c-new-BEG' and
  ;; `c-new-END' to the new boundaries.
Juanma Barranquero's avatar
Juanma Barranquero committed
901
  ;;
902 903 904 905
  ;; (ii) "Neutralize" every preprocessor line wholly or partially in the
  ;; extended changed region.  "Restore" lines which were CPP lines before the
  ;; change and are no longer so; these can be located from the Buffer local
  ;; variables `c-old-BOM' and `c-old-EOM'.
906 907 908 909 910 911
  ;;
  ;; (iii) Mark every CPP construct by placing a `category' property value
  ;; `c-cpp-delimiter' at its start and end.  The marked characters are the
  ;; opening # and usually the terminating EOL, but sometimes the character
  ;; before a comment/string delimiter.
  ;;
912 913
  ;; That is, set syntax-table properties on characters that would otherwise
  ;; interact syntactically with those outside the CPP line(s).
914
  ;;
915 916 917 918 919 920 921
  ;; This function is called from an after-change function, BEGG ENDD and
  ;; OLD-LEN being the standard parameters.  It prepares the buffer for font
  ;; locking, hence must get called before `font-lock-after-change-function'.
  ;;
  ;; Point is undefined both before and after this function call, the buffer
  ;; has been widened, and match-data saved.  The return value is ignored.
  ;;
922
  ;; This function is in the C/C++/ObjC value of `c-before-font-lock-functions'.
923
  ;;
924
  ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
925
  ;;
926
  ;; This function might make hidden buffer changes.
927
  (c-save-buffer-state (new-bounds)
928 929 930
    ;; First determine the region, (c-new-BEG c-new-END), which will get font
    ;; locked.  It might need "neutralizing".  This region may not start
    ;; inside a string, comment, or macro.
931 932
    (setq new-bounds (c-extend-font-lock-region-for-macros
		      c-new-BEG c-new-END old-len))
933 934
    (setq c-new-BEG (max (car new-bounds) (c-determine-limit 500 begg))
	  c-new-END (min (cdr new-bounds) (c-determine-+ve-limit 500 endd)))
935
    ;; Clear all old relevant properties.
936
    (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
937 938
    (c-clear-char-property-with-value c-new-BEG c-new-END 'category 'c-cpp-delimiter)
    ;; FIXME!!!  What about the "<" and ">" category properties?  2009-11-16
939

940 941
    ;; Add needed properties to each CPP construct in the region.
    (goto-char c-new-BEG)
942 943
    (skip-chars-backward " \t")
    (let ((pps-position (point))  pps-state mbeg)
944 945
      (while (and (< (point) c-new-END)
		  (search-forward-regexp c-anchored-cpp-prefix c-new-END t))
946 947 948 949 950 951
	;; If we've found a "#" inside a string/comment, ignore it.
	(setq pps-state
	      (parse-partial-sexp pps-position (point) nil nil pps-state)
	      pps-position (point))
	(unless (or (nth 3 pps-state)	; in a string?
		    (nth 4 pps-state))	; in a comment?
952
	  (goto-char (match-beginning 1))
953 954 955 956
	  (setq mbeg (point))
	  (if (> (c-syntactic-end-of-macro) mbeg)
	      (progn
		(c-neutralize-CPP-line mbeg (point))
957
		(c-set-cpp-delimiters mbeg (point)))
958 959
	    (forward-line))	      ; no infinite loop with, e.g., "#//"
	  )))))
960 961

(defun c-before-change (beg end)
962 963
  ;; Function to be put on `before-change-functions'.  Primarily, this calls
  ;; the language dependent `c-get-state-before-change-functions'.  It is
964 965 966
  ;; otherwise used only to remove stale entries from the `c-found-types'
  ;; cache, and to record entries which a `c-after-change' function might
  ;; confirm as stale.
967
  ;;
968 969 970
  ;; Note that this function must be FAST rather than accurate.  Note
  ;; also that it only has any effect when font locking is enabled.
  ;; We exploit this by checking for font-lock-*-face instead of doing
Paul Eggert's avatar
Paul Eggert committed
971
  ;; rigorous syntactic analysis.
972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036

  ;; If either change boundary is wholly inside an identifier, delete
  ;; it/them from the cache.  Don't worry about being inside a string
  ;; or a comment - "wrongly" removing a symbol from `c-found-types'
  ;; isn't critical.
  (setq c-maybe-stale-found-type nil)
  (save-restriction
    (save-match-data
      (widen)
      (save-excursion
	;; Are we inserting/deleting stuff in the middle of an identifier?
	(c-unfind-enclosing-token beg)
	(c-unfind-enclosing-token end)
	;; Are we coalescing two tokens together, e.g. "fo o" -> "foo"?
	(when (< beg end)
	  (c-unfind-coalesced-tokens beg end))
	;; Are we (potentially) disrupting the syntactic context which
	;; makes a type a type?  E.g. by inserting stuff after "foo" in
	;; "foo bar;", or before "foo" in "typedef foo *bar;"?
	;;
	;; We search for appropriate c-type properties "near" the change.
	;; First, find an appropriate boundary for this property search.
	(let (lim
	      type type-pos
	      marked-id term-pos
	      (end1
	       (or (and (eq (get-text-property end 'face) 'font-lock-comment-face)
			(previous-single-property-change end 'face))
		   end)))
	  (when (>= end1 beg) ; Don't hassle about changes entirely in comments.
	    ;; Find a limit for the search for a `c-type' property
	    (while
		(and (/= (skip-chars-backward "^;{}") 0)
		     (> (point) (point-min))
		     (memq (c-get-char-property (1- (point)) 'face)
			   '(font-lock-comment-face font-lock-string-face))))
	    (setq lim (max (point-min) (1- (point))))

	    ;; Look for the latest `c-type' property before end1
	    (when (and (> end1 (point-min))
		       (setq type-pos
			     (if (get-text-property (1- end1) 'c-type)
				 end1
			       (previous-single-property-change end1 'c-type nil lim))))
	      (setq type (get-text-property (max (1- type-pos) lim) 'c-type))

	      (when (memq type '(c-decl-id-start c-decl-type-start))
		;; Get the identifier, if any, that the property is on.
		(goto-char (1- type-pos))
		(setq marked-id
		      (when (looking-at "\\(\\sw\\|\\s_\\)")
			(c-beginning-of-current-token)
			(buffer-substring-no-properties (point) type-pos)))

		(goto-char end1)
		(skip-chars-forward "^;{}") ; FIXME!!!  loop for comment, maybe
		(setq lim (point))
		(setq term-pos
		      (or (next-single-property-change end 'c-type nil lim) lim))
		(setq c-maybe-stale-found-type
		      (list type marked-id
			    type-pos term-pos
			    (buffer-substring-no-properties type-pos term-pos)
			    (buffer-substring-no-properties beg end)))))))

1037 1038 1039 1040
	(if c-get-state-before-change-functions
	    (mapc (lambda (fn)
		    (funcall fn beg end))
		  c-get-state-before-change-functions))
1041 1042 1043 1044
	)))
  ;; The following must be done here rather than in `c-after-change' because
  ;; newly inserted parens would foul up the invalidation algorithm.
  (c-invalidate-state-cache beg))
1045

1046 1047 1048 1049 1050
(defvar c-in-after-change-fontification nil)
(make-variable-buffer-local 'c-in-after-change-fontification)
;; A flag to prevent region expanding stuff being done twice for after-change
;; fontification.

1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
(defun c-after-change (beg end old-len)
  ;; Function put on `after-change-functions' to adjust various caches
  ;; etc.  Prefer speed to finesse here, since there will be an order
  ;; of magnitude more calls to this function than any of the
  ;; functions that use the caches.
  ;;
  ;; Note that care must be taken so that this is called before any
  ;; font-lock callbacks since we might get calls to functions using
  ;; these caches from inside them, and we must thus be sure that this
  ;; has already been executed.
  ;;
1062
  ;; This calls the language variable c-before-font-lock-functions, if non nil.
1063 1064
  ;; This typically sets `syntax-table' properties.

1065