;; The starting position from where we determined `c-macro-cache'.
(defvar c-macro-cache-syntactic nil)
(make-variable-buffer-local 'c-macro-cache-syntactic)
-;; non-nil iff `c-macro-cache' has both elements set AND the cdr is at a
-;; syntactic end of macro, not merely an apparent one.
+;; Either nil, or the syntactic end of the macro currently represented by
+;; `c-macro-cache'.
+(defvar c-macro-cache-no-comment nil)
+(make-variable-buffer-local 'c-macro-cache-no-comment)
+;; Either nil, or the last character of the macro currently represented by
+;; `c-macro-cache' which isn't in a comment. */
(defun c-invalidate-macro-cache (beg end)
;; Called from a before-change function. If the change region is before or
((< beg (car c-macro-cache))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))
((and (cdr c-macro-cache)
(< beg (cdr c-macro-cache)))
(setcdr c-macro-cache nil)
(setq c-macro-cache-start-pos beg
- c-macro-cache-syntactic nil))))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))))
(defun c-macro-is-genuine-p ()
;; Check that the ostensible CPP construct at point is a real one. In
t))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil)
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil)
(save-restriction
(if lim (narrow-to-region lim (point-max)))
(>= (point) (car c-macro-cache)))
(setq c-macro-cache nil
c-macro-cache-start-pos nil
- c-macro-cache-syntactic nil))
+ c-macro-cache-syntactic nil
+ c-macro-cache-no-comment nil))
(while (progn
(end-of-line)
(when (and (eq (char-before) ?\\)
(let* ((here (point))
(there (progn (c-end-of-macro) (point)))
s)
- (unless c-macro-cache-syntactic
+ (if c-macro-cache-syntactic
+ (goto-char c-macro-cache-syntactic)
(setq s (parse-partial-sexp here there))
(while (and (or (nth 3 s) ; in a string
(nth 4 s)) ; in a comment (maybe at end of line comment)
(> there here)) ; No infinite loops, please.
(setq there (1- (nth 8 s)))
(setq s (parse-partial-sexp here there)))
- (setq c-macro-cache-syntactic (car c-macro-cache)))
+ (setq c-macro-cache-syntactic (point)))
+ (point)))
+
+(defun c-no-comment-end-of-macro ()
+ ;; Go to the end of a CPP directive, or a pos just before which isn't in a
+ ;; comment. For this purpose, open strings are ignored.
+ ;;
+ ;; This function must only be called from the beginning of a CPP construct.
+ ;;
+ ;; Note that this function might do hidden buffer changes. See the comment
+ ;; at the start of cc-engine.el for more info.
+ (let* ((here (point))
+ (there (progn (c-end-of-macro) (point)))
+ s)
+ (if c-macro-cache-no-comment
+ (goto-char c-macro-cache-no-comment)
+ (setq s (parse-partial-sexp here there))
+ (while (and (nth 3 s) ; in a string
+ (> there here)) ; No infinite loops, please.
+ (setq here (1+ (nth 8 s)))
+ (setq s (parse-partial-sexp here there)))
+ (when (nth 4 s)
+ (goto-char (1- (nth 8 s))))
+ (setq c-macro-cache-no-comment (point)))
(point)))
(defun c-forward-over-cpp-define-id ()
\f
;;; Change hooks, linking with Font Lock and electric-indent-mode.
-;; 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-called-from-text-property-change-p ()
;; Is the primitive which invoked `before-change-functions' or
;; `after-change-functions' one which merely changes text properties? This
'(put-text-property remove-list-of-text-properties)))
(defun c-extend-region-for-CPP (beg end)
- ;; 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.
+ ;; Adjust `c-new-BEG', `c-new-END' respectively to the beginning and end of
+ ;; any preprocessor construct they may be in.
;;
;; Point is undefined both before and after this function call; the buffer
;; has already been widened, and match-data saved. The return value is
;; This function is in the C/C++/ObjC values of
;; `c-get-state-before-change-functions' and is called exclusively as a
;; before change function.
- (goto-char beg)
+ (goto-char c-new-BEG)
(c-beginning-of-macro)
- (setq c-old-BOM (point))
+ (setq c-new-BEG (point))
- (goto-char end)
+ (goto-char c-new-END)
(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
- (setq c-old-EOM (point)))
-
-(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.
+ (setq c-new-END (point)))
+
+(defun c-extend-font-lock-region-for-macros (begg endd old-len)
+ ;; Extend the region (c-new-BEG c-new-END) to cover all (possibly changed)
+ ;; preprocessor macros; The return value has no significance.
;;
;; 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)))
+ ;;
+ ;; This function is in the C/C++/ObjC value of `c-before-font-lock-functions'.
+ (goto-char endd)
+ (if (c-beginning-of-macro)
+ (c-end-of-macro))
+ (setq c-new-END (max endd c-new-END (point)))
+ ;; Determine the region, (c-new-BEG c-new-END), which will get font
+ ;; locked. This restricts the region should there be long macros.
+ (setq c-new-BEG (max c-new-BEG (c-determine-limit 500 begg))
+ c-new-END (min c-new-END (c-determine-+ve-limit 500 endd))))
(defun c-neutralize-CPP-line (beg end)
;; BEG and END bound a region, typically a preprocessor line. Put a
(t nil)))))))
(defun c-neutralize-syntax-in-and-mark-CPP (begg endd old-len)
- ;; (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.
- ;;
- ;; (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'.
+ ;; (i) "Neutralize" every preprocessor line wholly or partially in the
+ ;; changed region. "Restore" lines which were CPP lines before the change
+ ;; and are no longer so.
;;
- ;; (iii) Mark every CPP construct by placing a `category' property value
+ ;; (ii) Mark each 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.
+ ;; before a comment delimiter.
;;
;; That is, set syntax-table properties on characters that would otherwise
;; interact syntactically with those outside the CPP line(s).
;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
;;
;; This function might make hidden buffer changes.
- (c-save-buffer-state (new-bounds)
- ;; 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.
- (setq new-bounds (c-extend-font-lock-region-for-macros
- c-new-BEG c-new-END old-len))
- (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)))
- ;; Clear all old relevant properties.
+ (c-save-buffer-state (limits )
+ ;; Clear 'syntax-table properties "punctuation":
(c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
;; CPP "comment" markers:
;; Add needed properties to each CPP construct in the region.
(goto-char c-new-BEG)
+ (if (setq limits (c-literal-limits)) ; Go past any literal.
+ (goto-char (cdr limits)))
(skip-chars-backward " \t")
(let ((pps-position (point)) pps-state mbeg)
(while (and (< (point) c-new-END)
(nth 4 pps-state)))) ; in a comment?
(goto-char (match-beginning 1))
(setq mbeg (point))
- (if (> (c-syntactic-end-of-macro) mbeg)
+ (if (> (c-no-comment-end-of-macro) mbeg)
(progn
(c-neutralize-CPP-line mbeg (point)) ; "punctuation" properties
(if (eval-when-compile
;;
;; This is called from an after-change-function, but the parameters BEG END
;; and OLD-LEN are not used.
- (if font-lock-mode
- (setq c-new-BEG
- (or (c-fl-decl-start c-new-BEG) (c-point 'bol c-new-BEG))
- c-new-END (c-point 'bonl c-new-END))))
+ (if font-lock-mode
+ (setq c-new-BEG
+ (or (c-fl-decl-start c-new-BEG) (c-point 'bol c-new-BEG))
+ c-new-END
+ (save-excursion
+ (goto-char c-new-END)
+ (if (bolp)
+ (point)
+ (c-point 'bonl c-new-END))))))
(defun c-context-expand-fl-region (beg end)
;; Return a cons (NEW-BEG . NEW-END), where NEW-BEG is the beginning of a