changeset 107937:18526db8f26d

Reverse change 99448: "Change strategy for marking < and > as template delimiters: mark them strictly in matching pairs."
author Alan Mackenzie <acm@muc.de>
date Mon, 12 Apr 2010 15:15:07 +0000
parents 10f6e25f2e26
children 1a9d5fee61d1
files lisp/ChangeLog lisp/progmodes/cc-cmds.el lisp/progmodes/cc-defs.el lisp/progmodes/cc-engine.el lisp/progmodes/cc-langs.el lisp/progmodes/cc-mode.el
diffstat 6 files changed, 116 insertions(+), 355 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Mon Apr 12 14:59:56 2010 +0000
+++ b/lisp/ChangeLog	Mon Apr 12 15:15:07 2010 +0000
@@ -695,33 +695,6 @@
 	(doc-view-pdf->png): Don't rely on doc-view-pdf/ps->png for the few
 	windows that are not yet showing images.
 
-2010-02-04  Alan Mackenzie  <acm@muc.de>
-
-	Change strategy for marking < and > as template delimiters: mark
-	them strictly in matching pairs.
-
-	* cc-mode.el (c-before-change):
-	Use c-get-state-before-change-functions.
-	(c-common-init): Adapt to use
-	c-get-state-before-change-functions (note plural).
-
-	* cc-langs.el (c-no-parens-syntax-table): New syntax table, used
-	for searching syntactically for matching <s and >s.
-	(c-get-state-before-change-functions): New language variable (note
-	the plural) which supersedes c-get-state-before-change-function.
-
-	* cc-engine.el (c-clear-<-pair-props, c-clear->-pair-props)
-	(c-clear-<>-pair-props, c-clear-<-pair-props-if-match-after)
-	(c-clear->-pair-props-if-match-before)
-	(c-before-change-check-<>-operators): New functions.
-	(c-after-change-check-<>-operators): Use macro
-	c-unmark-<->-as-paren.
-
-	* cc-defs.el (c-search-backward-char-property): New macro.
-
-	* cc-cmds.el (c-electric-lt-gt): Do not set text properties on <
-	and > any more.  (These will be handled by font locking.)
-
 2010-02-04  Michael Albinus  <michael.albinus@gmx.de>
 
 	* dired.el (dired-revert): If DIRED-DIRECTORY is a cons cell, call
--- a/lisp/progmodes/cc-cmds.el	Mon Apr 12 14:59:56 2010 +0000
+++ b/lisp/progmodes/cc-cmds.el	Mon Apr 12 15:15:07 2010 +0000
@@ -1086,76 +1086,104 @@
 
   (interactive "*P")
   (let ((c-echo-syntactic-information-p nil)
-	final-pos close-paren-inserted found-delim)
+	final-pos close-paren-inserted)
 
     (self-insert-command (prefix-numeric-value arg))
     (setq final-pos (point))
 
-;;;; 2010-01-31: There used to be code here to put a syntax-table text
-;;;; property on the new < or > and its mate (if any) when they are template
-;;;; parens.  This is now done in an after-change function.
+    (c-save-buffer-state (c-parse-and-markup-<>-arglists
+			  c-restricted-<>-arglists
+			  <-pos)
+
+      (when c-recognize-<>-arglists
+	(if (eq last-command-event ?<)
+	    (when (and (progn
+			 (backward-char)
+			 (= (point)
+			    (progn
+			      (c-beginning-of-current-token)
+			      (point))))
+		       (progn
+			 (c-backward-token-2)
+			 (looking-at c-opt-<>-sexp-key)))
+	      (c-mark-<-as-paren (1- final-pos)))
+
+	  ;; It's a ">".  Check if there's an earlier "<" which either has
+	  ;; open paren syntax already or that can be recognized as an arglist
+	  ;; together with this ">".  Note that this won't work in cases like
+	  ;; "template <x, a < b, y>" but they ought to be rare.
+
+	  (save-restriction
+	    ;; Narrow to avoid that `c-forward-<>-arglist' below searches past
+	    ;; our position.
+	    (narrow-to-region (point-min) final-pos)
+
+	    (while (and
+		    (progn
+		      (goto-char final-pos)
+		      (c-syntactic-skip-backward "^<;}" nil t)
+		      (eq (char-before) ?<))
+		    (progn
+		      (backward-char)
+		      ;; If the "<" already got open paren syntax we know we
+		      ;; have the matching closer.  Handle it and exit the
+		      ;; loop.
+		      (if (looking-at "\\s\(")
+			  (progn
+			    (c-mark->-as-paren (1- final-pos))
+			    (setq close-paren-inserted t)
+			    nil)
+			t))
+
+		    (progn
+		      (setq <-pos (point))
+		      (c-backward-syntactic-ws)
+		      (c-simple-skip-symbol-backward))
+		    (or (looking-at c-opt-<>-sexp-key)
+			(not (looking-at c-keywords-regexp)))
+
+		    (let ((c-parse-and-markup-<>-arglists t)
+			  c-restricted-<>-arglists
+			  (containing-sexp
+			   (c-most-enclosing-brace (c-parse-state))))
+		      (when (and containing-sexp
+				 (progn (goto-char containing-sexp)
+					(eq (char-after) ?\())
+				 (not (eq (get-text-property (point) 'c-type)
+					  'c-decl-arg-start)))
+			(setq c-restricted-<>-arglists t))
+		      (goto-char <-pos)
+		      (c-forward-<>-arglist nil))
+
+		    ;; Loop here if the "<" we found above belongs to a nested
+		    ;; angle bracket sexp.  When we start over we'll find the
+		    ;; previous or surrounding sexp.
+		    (if (< (point) final-pos)
+			t
+		      (setq close-paren-inserted t)
+		      nil)))))))
+    (goto-char final-pos)
 
     ;; Indent the line if appropriate.
-    (when (and c-electric-flag c-syntactic-indentation c-recognize-<>-arglists)
-      (setq found-delim
-	    (if (eq last-command-event ?<)
-		;; If a <, basically see if it's got "template" before it .....
-		(or (and (progn
-			   (backward-char)
-			   (= (point)
-			      (progn (c-beginning-of-current-token) (point))))
-			 (progn
-			   (c-backward-token-2)
-			   (looking-at c-opt-<>-sexp-key)))
-		    ;; ..... or is a C++ << operator.
-		    (and (c-major-mode-is 'c++-mode)
-			 (progn
-			   (goto-char (1- final-pos))
-			   (c-beginning-of-current-token)
-			   (looking-at "<<"))
-			 (>= (match-end 0) final-pos)))
-
-	      ;; It's a >.  Either a C++ >> operator. ......
-	      (or (and (c-major-mode-is 'c++-mode)
-		       (progn
-			 (goto-char (1- final-pos))
-			 (c-beginning-of-current-token)
-			 (looking-at ">>"))
-		       (>= (match-end 0) final-pos))
-		  ;; ...., or search back for a < which isn't already marked as an
-		  ;; opening template delimiter.
-		  (save-restriction
-		    (widen)
-		    ;; Narrow to avoid `c-forward-<>-arglist' below searching past
-		    ;; our position.
-		    (narrow-to-region (point-min) final-pos)
-		    (goto-char final-pos)
-		    (while
-			(and
-			 (progn
-			   (c-syntactic-skip-backward "^<;}" nil t)
-			   (eq (char-before) ?<))
-			 (progn
-			   (backward-char)
-			   (looking-at "\\s\("))))
-		    (and (eq (char-after) ?<)
-			 (not (looking-at "\\s\("))
-			 (progn (c-backward-syntactic-ws)
-				(c-simple-skip-symbol-backward))
-			 (or (looking-at c-opt-<>-sexp-key)
-			     (not (looking-at c-keywords-regexp)))))))))
-
-    (goto-char final-pos)
-    (when found-delim
-      (indent-according-to-mode)
-      (when (and (eq (char-before) ?>)
-		 (not executing-kbd-macro)
-		 blink-paren-function)
-	    ;; Note: Most paren blink functions, such as the standard
-	    ;; `blink-matching-open', currently doesn't handle paren chars
-	    ;; marked with text properties very well.  Maybe we should avoid
-	    ;; this call for the time being?
-	    (funcall blink-paren-function)))))
+    (when (and c-electric-flag c-syntactic-indentation)
+      (backward-char)
+      (when (prog1 (or (looking-at "\\s\(\\|\\s\)")
+		       (and (c-major-mode-is 'c++-mode)
+			    (progn
+			      (c-beginning-of-current-token)
+			      (looking-at "<<\\|>>"))
+			    (= (match-end 0) final-pos)))
+	      (goto-char final-pos))
+	(indent-according-to-mode)))
+
+    (when (and close-paren-inserted
+	       (not executing-kbd-macro)
+	       blink-paren-function)
+      ;; Note: Most paren blink functions, such as the standard
+      ;; `blink-matching-open', currently doesn't handle paren chars
+      ;; marked with text properties very well.  Maybe we should avoid
+      ;; this call for the time being?
+      (funcall blink-paren-function))))
 
 (defun c-electric-paren (arg)
   "Insert a parenthesis.
--- a/lisp/progmodes/cc-defs.el	Mon Apr 12 14:59:56 2010 +0000
+++ b/lisp/progmodes/cc-defs.el	Mon Apr 12 15:15:07 2010 +0000
@@ -1029,44 +1029,6 @@
     ;; Emacs.
     `(remove-text-properties ,from ,to '(,property nil))))
 
-(defmacro c-search-forward-char-property (property value &optional limit)
-  "Search forward for a text-property PROPERTY having value VALUE.
-LIMIT bounds the search.  The comparison is done with `equal'.
-
-Leave point just after the character, and set the match data on
-this character, and return point.  If VALUE isn't found, Return
-nil; point is then left undefined."
-  `(let ((place (point)))
-     (while
-	 (and
-	  (< place ,(or limit '(point-max)))
-	  (not (equal (get-text-property place ,property) ,value)))
-       (setq place (next-single-property-change
-		    place ,property nil ,(or limit '(point-max)))))
-     (when (< place ,(or limit '(point-max)))
-       (goto-char place)
-       (search-forward-regexp ".")	; to set the match-data.
-       (point))))
-
-(defmacro c-search-backward-char-property (property value &optional limit)
-  "Search backward for a text-property PROPERTY having value VALUE.
-LIMIT bounds the search.  The comparison is done with `equal'.
-
-Leave point just before the character, set the match data on this
-character, and return point.  If VALUE isn't found, Return nil;
-point is then left undefined."
-  `(let ((place (point)))
-     (while
-	 (and
-	  (> place ,(or limit '(point-min)))
-	  (not (equal (get-text-property (1- place) ,property) ,value)))
-       (setq place (previous-single-property-change
-		    place ,property nil ,(or limit '(point-min)))))
-     (when (> place ,(or limit '(point-max)))
-       (goto-char place)
-       (search-backward-regexp ".")	; to set the match-data.
-       (point))))
-
 (defun c-clear-char-property-with-value-function (from to property value)
   "Remove all text-properties PROPERTY from the region (FROM, TO)
 which have the value VALUE, as tested by `equal'.  These
--- a/lisp/progmodes/cc-engine.el	Mon Apr 12 14:59:56 2010 +0000
+++ b/lisp/progmodes/cc-engine.el	Mon Apr 12 15:15:07 2010 +0000
@@ -4880,168 +4880,7 @@
 	)))
 
 
-;; Setting and removing syntax properties on < and > in languages (C++
-;; and Java) where they can be template/generic delimiters as well as
-;; their normal meaning of "less/greater than".
-
-;; Normally, < and > have syntax 'punctuation'.  When they are found to
-;; be delimiters, they are marked as such with the category properties
-;; c-<-as-paren-syntax, c->-as-paren-syntax respectively.
-
-;; STRATEGY:
-;;
-;; It is impossible to determine with certainty whether a <..> pair in
-;; C++ is two comparison operators or is template delimiters, unless
-;; one duplicates a lot of a C++ compiler.  For example, the following
-;; code fragment:
-;;
-;;     foo (a < b, c > d) ;
-;;
-;; could be a function call with two integer parameters (each a
-;; relational expression), or it could be a constructor for class foo
-;; taking one parameter d of templated type "a < b, c >".  They are
-;; somewhat easier to distinguish in Java.
-;;
-;; The strategy now (2010-01) adopted is to mark and unmark < and
-;; > IN MATCHING PAIRS ONLY.  [Previously, they were marked
-;; individually when their context so indicated.  This gave rise to
-;; intractible problems when one of a matching pair was deleted, or
-;; pulled into a literal.]
-;;
-;; At each buffer change, the syntax-table properties are removed in a
-;; before-change function and reapplied, when needed, in an
-;; after-change function.  It is far more important that the
-;; properties get removed when they they are spurious than that they
-;; be present when wanted.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun c-clear-<-pair-props (&optional pos)
-  ;; POS (default point) is at a < character.  If it is marked with
-  ;; open paren syntax-table text property, remove the property,
-  ;; together with the close paren property on the matching > (if
-  ;; any).
-  (save-excursion
-    (if pos
-	(goto-char pos)
-      (setq pos (point)))
-    (when (equal (c-get-char-property (point) 'syntax-table)
-		 c-<-as-paren-syntax)
-      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
-	(c-go-list-forward))
-      (when (equal (c-get-char-property (1- (point)) 'syntax-table)
-		   c->-as-paren-syntax) ; should always be true.
-	(c-clear-char-property (1- (point)) 'syntax-table))
-      (c-clear-char-property pos 'syntax-table))))
-
-(defun c-clear->-pair-props (&optional pos)
-  ;; POS (default point) is at a > character.  If it is marked with
-  ;; close paren syntax-table property, remove the property, together
-  ;; with the open paren property on the matching < (if any).
-  (save-excursion
-    (if pos
-	(goto-char pos)
-      (setq pos (point)))
-    (when (equal (c-get-char-property (point) 'syntax-table)
-		 c->-as-paren-syntax)
-      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
-	(c-go-up-list-backward))
-      (when (equal (c-get-char-property (point) 'syntax-table)
-			c-<-as-paren-syntax) ; should always be true.
-	(c-clear-char-property (point) 'syntax-table))
-      (c-clear-char-property pos 'syntax-table))))
-
-(defun c-clear-<>-pair-props (&optional pos)
-  ;; POS (default point) is at a < or > character.  If it has an
-  ;; open/close paren syntax-table property, remove this property both
-  ;; from the current character and its partner (which will also be
-  ;; thusly marked).
-  (cond
-   ((eq (char-after) ?\<)
-    (c-clear-<-pair-props pos))
-   ((eq (char-after) ?\>)
-    (c-clear->-pair-props pos))
-   (t (c-benign-error
-       "c-clear-<>-pair-props called from wrong position"))))
-
-(defun c-clear-<-pair-props-if-match-after (lim &optional pos)
-  ;; POS (default point) is at a < character.  If it is both marked
-  ;; with open/close paren syntax-table property, and has a matching >
-  ;; (also marked) which is after LIM, remove the property both from
-  ;; the current > and its partner.
-  (save-excursion
-    (if pos
-	(goto-char pos)
-      (setq pos (point)))
-    (when (equal (c-get-char-property (point) 'syntax-table)
-		 c-<-as-paren-syntax)
-      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
-	(c-go-list-forward))
-      (when (and (>= (point) lim)
-		 (equal (c-get-char-property (1- (point)) 'syntax-table)
-			c->-as-paren-syntax)) ; should always be true.
-	(c-unmark-<->-as-paren (1- (point)))
-	(c-unmark-<->-as-paren pos)))))
-
-(defun c-clear->-pair-props-if-match-before (lim &optional pos)
-  ;; POS (default point) is at a > character.  If it is both marked
-  ;; with open/close paren syntax-table property, and has a matching <
-  ;; (also marked) which is before LIM, remove the property both from
-  ;; the current < and its partner.
-  (save-excursion
-    (if pos
-	(goto-char pos)
-      (setq pos (point)))
-    (when (equal (c-get-char-property (point) 'syntax-table)
-		 c->-as-paren-syntax)
-      (with-syntax-table c-no-parens-syntax-table ; ignore unbalanced [,{,(,..
-	(c-go-up-list-backward))
-      (when (and (<= (point) lim)
-		 (equal (c-get-char-property (point) 'syntax-table)
-			c-<-as-paren-syntax)) ; should always be true.
-	(c-unmark-<->-as-paren (point))
-	(c-unmark-<->-as-paren pos)))))
-
-(defun c-before-change-check-<>-operators (beg end)
-  ;; Unmark certain pairs of "< .... >" which are currently marked as
-  ;; template/generic delimiters.  (This marking is via syntax-table
-  ;; text properties).
-  ;;
-  ;; These pairs are those which are in the current "statement" (i.e.,
-  ;; the region between the {, }, or ; before BEG and the one after
-  ;; END), and which enclose any part of the interval (BEG END).
-  ;;
-  ;; Note that in C++ (?and Java), template/generic parens cannot
-  ;; enclose a brace or semicolon, so we use these as bounds on the
-  ;; region we must work on.
-  ;;
-  ;; This function is called from before-change-functions (via
-  ;; c-get-state-before-change-functions).  Thus the buffer is widened,
-  ;; and point is undefined, both at entry and exit.
-  ;;
-  ;; FIXME!!!  This routine ignores the possibility of macros entirely.
-  ;; 2010-01-29.
-  (save-excursion
-    (let ((beg-lit-limits (progn (goto-char beg) (c-literal-limits)))
-	  (end-lit-limits (progn (goto-char end) (c-literal-limits))))
-      ;; Locate the barrier before the changed region
-      (goto-char  (if beg-lit-limits (car beg-lit-limits) beg))
-      (c-syntactic-skip-backward "^;{}" (max (- beg 2048) (point-min)))
-
-      ;; Remove the syntax-table properties from each pertinent <...> pair.
-      ;; Firsly, the ones with the < before beg and > after beg.
-      (while (c-search-forward-char-property 'category 'c-<-as-paren-syntax beg)
-	(c-clear-<-pair-props-if-match-after beg (1- (point))))
-
-      ;; Locate the barrier after END.
-      (goto-char (if end-lit-limits (cdr end-lit-limits) end))
-      (c-syntactic-re-search-forward "[;{}]"
-				     (min (+ end 2048) (point-max)) 'end)
-
-      ;; Remove syntax-table properties from the remaining pertinent <...>
-      ;; pairs, those with a > after end and < before end.
-      (while (c-search-backward-char-property 'category 'c->-as-paren-syntax end)
-	(c-clear->-pair-props-if-match-before end)))))
-
-
+;; Handling of small scale constructs like types and names.
 
 (defun c-after-change-check-<>-operators (beg end)
   ;; This is called from `after-change-functions' when
@@ -5063,7 +4902,7 @@
 		 (< beg (setq beg (match-end 0))))
 	(while (progn (skip-chars-forward "^<>" beg)
 		      (< (point) beg))
-	  (c-clear-<>-pair-props)
+	  (c-clear-char-property (point) 'syntax-table)
 	  (forward-char))))
 
     (when (< beg end)
@@ -5078,13 +4917,9 @@
 		   (< end (setq end (match-end 0))))
 	  (while (progn (skip-chars-forward "^<>" end)
 			(< (point) end))
-	    (c-clear-<>-pair-props)
+	    (c-clear-char-property (point) 'syntax-table)
 	    (forward-char)))))))
 
-
-
-;; Handling of small scale constructs like types and names.
-
 ;; Dynamically bound variable that instructs `c-forward-type' to also
 ;; treat possible types (i.e. those that it normally returns 'maybe or
 ;; 'found for) as actual types (and always return 'found for them).
--- a/lisp/progmodes/cc-langs.el	Mon Apr 12 14:59:56 2010 +0000
+++ b/lisp/progmodes/cc-langs.el	Mon Apr 12 15:15:07 2010 +0000
@@ -391,27 +391,6 @@
   (and (c-lang-const c++-make-template-syntax-table)
        (funcall (c-lang-const c++-make-template-syntax-table))))
 
-(c-lang-defconst c-no-parens-syntax-table
-  ;; A variant of the standard syntax table which is used to find matching
-  ;; "<"s and ">"s which have been marked as parens using syntax table
-  ;; properties.  The other paren characters (e.g. "{", ")" "]") are given a
-  ;; non-paren syntax here. so that the list commands will work on "< ... >"
-  ;; even when there's unbalanced other parens inside them.
-  ;;
-  ;; This variable is nil for languages which don't have template stuff.
-  t  `(lambda ()
-	(if (c-lang-const c-recognize-<>-arglists)
-	    (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table))))
-	      (modify-syntax-entry ?\( "." table)
-	      (modify-syntax-entry ?\) "." table)
-	      (modify-syntax-entry ?\[ "." table)
-	      (modify-syntax-entry ?\] "." table)
-	      (modify-syntax-entry ?\{ "." table)
-	      (modify-syntax-entry ?\} "." table)
-	      table))))
-(c-lang-defvar c-no-parens-syntax-table
-	       (funcall (c-lang-const c-no-parens-syntax-table)))
-
 (c-lang-defconst c-identifier-syntax-modifications
   "A list that describes the modifications that should be done to the
 mode syntax table to get a syntax table that matches all identifiers
@@ -444,36 +423,26 @@
 classifies symbol constituents like '_' and '$' as word constituents,
 so that all identifiers are recognized as words.")
 
-(c-lang-defconst c-get-state-before-change-functions
-  ;; For documentation see the following c-lang-defvar of the same name.
-  ;; The value here may be a list of functions or a single function.
-  t nil
-  c++ '(c-extend-region-for-CPP c-before-change-check-<>-operators)
-  (c objc) 'c-extend-region-for-CPP
-  ;; java 'c-before-change-check-<>-operators
-  awk 'c-awk-record-region-clear-NL)
-(c-lang-defvar c-get-state-before-change-functions
-	       (let ((fs (c-lang-const c-get-state-before-change-functions)))
-		  (if (listp fs)
-		      fs
-		    (list fs)))
-  "If non-nil, a list of functions called from c-before-change-hook.
-Typically these will record enough state to allow
+(c-lang-defconst c-get-state-before-change-function
+  "If non-nil, a function called from c-before-change-hook.
+Typically it will record enough state to allow
 `c-before-font-lock-function' to extend the region to fontify,
 and may do such things as removing text-properties which must be
 recalculated.
 
-These functions will be run in the order given.  Each of them
-takes 2 parameters, the BEG and END supplied to every
+It takes 2 parameters, the BEG and END supplied to every
 before-change function; on entry, the buffer will have been
 widened and match-data will have been saved; point is undefined
 on both entry and exit; the return value is ignored.
 
-The functions are called even when font locking isn't enabled.
-
-When the mode is initialized, the functions are called with
-parameters \(point-min) and \(point-max).")
-
+When the mode is initialized, this function is called with
+parameters \(point-min) and \(point-max)."
+  t nil
+  (c c++ objc) 'c-extend-region-for-CPP
+  awk 'c-awk-record-region-clear-NL)
+(c-lang-defvar c-get-state-before-change-function
+	       (c-lang-const c-get-state-before-change-function))
+  
 (c-lang-defconst c-before-font-lock-function
   "If non-nil, a function called just before font locking.
 Typically it will extend the region about to be fontified \(see
--- a/lisp/progmodes/cc-mode.el	Mon Apr 12 14:59:56 2010 +0000
+++ b/lisp/progmodes/cc-mode.el	Mon Apr 12 15:15:07 2010 +0000
@@ -641,12 +641,8 @@
   (save-restriction
     (widen)
     (save-excursion
-      (if c-get-state-before-change-functions
-	  (let ((beg (point-min))
-		(end (point-max)))
-	    (mapc (lambda (fn)
-		    (funcall fn beg end))
-		  c-get-state-before-change-functions)))
+      (if c-get-state-before-change-function
+	  (funcall c-get-state-before-change-function (point-min) (point-max)))
       (if c-before-font-lock-function
 	  (funcall c-before-font-lock-function (point-min) (point-max)
 		   (- (point-max) (point-min))))))
@@ -779,7 +775,7 @@
 
 (defmacro c-run-mode-hooks (&rest hooks)
   ;; Emacs 21.1 has introduced a system with delayed mode hooks that
-  ;; requires the use of the new function `run-mode-hooks'.
+  ;; require the use of the new function `run-mode-hooks'.
   (if (cc-bytecomp-fboundp 'run-mode-hooks)
       `(run-mode-hooks ,@hooks)
     `(progn ,@(mapcar (lambda (hook) `(run-hooks ,hook)) hooks))))
@@ -812,8 +808,8 @@
   ;; has already been widened, and match-data saved.  The return value is
   ;; meaningless.
   ;;
-  ;; This function is in the C/C++/ObjC values of
-  ;; `c-get-state-before-change-functions' and is called exclusively as a
+  ;; This function is the C/C++/ObjC value of
+  ;; `c-get-state-before-change-function' and is called exclusively as a
   ;; before change function.
   (goto-char beg)
   (c-beginning-of-macro)
@@ -926,8 +922,8 @@
 	  )))))
 
 (defun c-before-change (beg end)
-  ;; Function to be put on `before-change-functions'.  Primarily, this calls
-  ;; the language dependent `c-get-state-before-change-functions'.  It is
+  ;; Function to be put on `before-change-function'.  Primarily, this calls
+  ;; the language dependent `c-get-state-before-change-function'.  It is
   ;; 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.
@@ -1005,10 +1001,8 @@
 	;; larger than (beg end).
 	(setq c-new-BEG beg
 	      c-new-END end)
-	(if c-get-state-before-change-functions
-	    (mapc (lambda (fn)
-		    (funcall fn beg end))
-		  c-get-state-before-change-functions))
+	(if c-get-state-before-change-function
+	    (funcall c-get-state-before-change-function beg end))
 	))))
 
 (defun c-after-change (beg end old-len)