Function: c-before-change

c-before-change is a byte-compiled function defined in cc-mode.el.gz.

Signature

(c-before-change BEG END)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-mode.el.gz
(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
  ;; 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.
  ;;
  ;; 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
  ;; rigorous syntactic analysis.

  ;; 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.
  (unless (c-called-from-text-property-change-p)
    (save-restriction
      (widen)
      (if c-just-done-before-change
	  ;; We have two consecutive calls to `before-change-functions' without
	  ;; an intervening `after-change-functions'.  An example of this is bug
	  ;; #38691.  To protect CC Mode, assume that the entire buffer has
	  ;; changed.
	  (setq beg (point-min)
		end (point-max)
		c-just-done-before-change 'whole-buffer)
	(setq c-just-done-before-change t))
      ;; (c-new-BEG c-new-END) will be the region to fontify.
      (setq c-new-BEG beg  c-new-END end)
      (setq c-maybe-stale-found-type nil)
      ;; A workaround for syntax-ppss's failure to notice syntax-table text
      ;; property changes.
      (when (fboundp 'syntax-ppss)
	(setq c-syntax-table-hwm most-positive-fixnum))
      (save-match-data
	(widen)
	(unwind-protect
	    (progn
	      (c-restore-string-fences)
	      (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))
		(c-invalidate-sws-region-before 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 lim-2
		      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
		    ;; Point is currently undefined.  A `goto-char' somewhere is needed.  (2020-12-06).
		    (setq lim-2 (c-determine-limit 1000 (point) ; that is wrong.  FIXME!!!  (2020-12-06)
						   ))
		    (while
			(and (/= (skip-chars-backward "^;{}" lim-2) 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)
			(setq lim-2 (c-determine-+ve-limit 1000))
			(skip-chars-forward "^;{}" lim-2) ; FIXME!!!  loop for
					; comment, maybe
			(setq lim (point))
			(setq term-pos
			      (or (c-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)))))))

		(if c-get-state-before-change-functions
		    (mapc (lambda (fn)
			    (funcall fn beg end))
			  c-get-state-before-change-functions))

		(c-laomib-invalidate-cache beg end)))
	  (c-clear-string-fences))))
    (c-truncate-lit-pos-cache beg)
    ;; 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)
    ;; The following must happen after the previous, which likely alters
    ;; the macro cache.
    (when c-opt-cpp-symbol
      (c-invalidate-macro-cache beg end))))