Function: c-after-change-mark-abnormal-strings

c-after-change-mark-abnormal-strings is a byte-compiled function defined in cc-mode.el.gz.

Signature

(c-after-change-mark-abnormal-strings BEG END OLD-LEN)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-mode.el.gz
(defun c-after-change-mark-abnormal-strings (beg end _old-len)
  ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with
  ;; string fence syntax-table text properties.
  ;;
  ;; POINT is undefined both at entry to and exit from this function, the
  ;; buffer will have been widened, and match data will have been saved.
  ;;
  ;; This function is called exclusively as an after-change function via
  ;; `c-before-font-lock-functions'.
  (if (and c-multiline-string-start-char
	   (not c-ml-string-opener-re)
	   (not (c-characterp c-multiline-string-start-char)))
      ;; Only the last " might need to be marked.
      (c-save-buffer-state
	  ((beg-literal-limits
	    (progn (goto-char beg) (c-literal-limits)))
	   (beg-literal-type (c-literal-type beg-literal-limits))
	   end-literal-limits end-literal-type)
	(when (and (eq beg-literal-type 'string)
		   (c-get-char-property (car beg-literal-limits) 'syntax-table))
	  (c-clear-syn-tab (car beg-literal-limits))
	  (setq c-bc-changed-stringiness (not c-bc-changed-stringiness)))
	(setq end-literal-limits (progn (goto-char end) (c-literal-limits))
	      end-literal-type (c-literal-type end-literal-limits))
	;; Deal with the insertion of backslashes before a ".
	(goto-char end)
	(if (and (looking-at "\\\\*\"")
		 (eq (logand (skip-chars-backward "\\\\" beg) 1) 1))
	    (setq c-bc-changed-stringiness (not c-bc-changed-stringiness)))
	(when (eq (eq (eq beg-literal-type 'string)
		      (eq end-literal-type 'string))
		  c-bc-changed-stringiness)
	  (c-multiline-string-check-final-quote)))
    ;; There could be several "s needing marking.
    (c-save-buffer-state
	((cll (progn (goto-char c-new-BEG)
		     (c-literal-limits)))
	 (beg-literal-type (and cll (c-literal-type cll)))
	 (beg-limits
	  (cond
	   ((and (eq beg-literal-type 'string)
		 (c-unescaped-nls-in-string-p (car cll)))
	    (cons
	     (car cll)
	     (progn
	       (goto-char (1+ (car cll)))
	       (search-forward-regexp
		(cdr (assq (char-after (car cll)) c-string-innards-re-alist))
		nil t)
	       (min (1+ (point)) (point-max)))))
	   ((and (null beg-literal-type)
		 (goto-char beg)
		 (and (not (bobp))
		      (not c-ml-string-opener-re)
		      (eq (char-before) c-multiline-string-start-char))
		 (memq (char-after) c-string-delims))
	    (cons (point)
		  (progn
		    (forward-char)
		    (search-forward-regexp
		     (cdr (assq (char-before) c-string-innards-re-alist)) nil t)
		    (1+ (point)))))
	   (cll)))
	 (end-hwm ; the highest position which could possibly be affected by
		   ; insertion/deletion of string delimiters.
	  (max
	   (progn
	     (goto-char
	      (if (and (memq (char-after end) '(?\n ?\r))
		       (c-is-escaped end))
		  (min (1+ end)	; 1+, if we're inside an escaped NL.
		       (point-max))
		end))
	     (while
		 (progn (end-of-line)
			(and
			 (eq (char-before) ?\\)
			 (not (eobp))))
	       (forward-line))
	     (point))
	   c-new-END))
	 s)

      (goto-char
       (cond ((null beg-literal-type)
	      c-new-BEG)
	     ((eq beg-literal-type 'string)
	      (car beg-limits))
	     (t				; comment
	      (cdr beg-limits))))
      ;; Handle one string each time around the next while loop.
      (while
	  (and
	   (< (point) end-hwm)
	   (progn
	     ;; Skip over any comments before the next string.
	     (while (progn
		      (setq s (parse-partial-sexp (point) end-hwm nil
						  nil s 'syntax-table))
		      (and (< (point) end-hwm)
			   (or (not (nth 3 s))
			       (not (memq (char-before) c-string-delims))))))
	     ;; We're at the start of a string.
	     (and (memq (char-before) c-string-delims)
		  (not (nth 4 s)))))	; Check we're actually out of the
					; comment. not stuck at EOB
	(unless
	    (and c-ml-string-opener-re
		 (c-maybe-re-mark-ml-string))
	  (if (c-unescaped-nls-in-string-p (1- (point)))
	      (looking-at "\\(\\\\\\(.\\|\n\\)\\|[^\"]\\)*")
	    (looking-at (cdr (assq (char-before) c-string-innards-re-alist))))
	  (cond
	   ((memq (char-after (match-end 0)) '(?\n ?\r))
	    (c-put-syn-tab (1- (point)) '(15))
	    (c-put-syn-tab (match-end 0) '(15))
	    (setq c-new-BEG (min c-new-BEG (point))
		  c-new-END (max c-new-END (match-end 0)))
	    (setq c-open-string-opener (1- (point))))
	   ((or (eq (match-end 0) (point-max))
		(eq (char-after (match-end 0)) ?\\)) ; \ at EOB
	    (c-put-syn-tab (1- (point)) '(15))
	    (setq c-new-BEG (min c-new-BEG (point))
		  c-new-END (max c-new-END (match-end 0))) ; Do we need c-new-END?
	    (setq c-open-string-opener (1- (point)))))
	  (goto-char (min (1+ (match-end 0)) (point-max))))
	(setq s nil)))))