aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2016-06-09 12:24:27 +0000
committerAlan Mackenzie2016-06-09 12:24:27 +0000
commitfabb558250fca14a2684357a95225241253cdfda (patch)
tree6d54ec0d8cdbd162404652a3c33ba58497ddcd82
parent47b710a976d6e343d48b5170757a7971b0ac2966 (diff)
downloademacs-fabb558250fca14a2684357a95225241253cdfda.tar.gz
emacs-fabb558250fca14a2684357a95225241253cdfda.zip
Handle C++ raw strings.
* lisp/progmodes/cc-engine.el (c-raw-string-pos, c-depropertize-raw-string) (c-depropertize-raw-strings-in-region, c-before-change-check-raw-strings) (c-propertize-raw-string-opener, c-after-change-re-mark-raw-strings): New functions. * lisp/progmodes/cc-fonts.el (c-basic-matchers-before): Insert a clause for c-font-lock-raw-strings. (c-font-lock-raw-strings): New function. * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): Insert c-before-change-check-raw-strings into the C++ value, and c-depropertize-CPP into the values for C, C++, and Objective C. (c-before-font-lock-functions): Insert c-after-change-re-mark-raw-strings into the C++ value. * lisp/progmodes/cc-mode.el (c-old-BEG, c-old-END): New variables. (c-depropertize-CPP): New function, extracted from c-neutralize-syntax-in-and-mark-CPP. (c-neutralize-syntax-in-and-mark-CPP): Remove the call to c-clear-char-property-with-value for 'syntax-table value '(1) at the beginning of the function. (c-after-change): Set c-old-BEG and c-old-END to the current values of c-new-BEG and c-new-END.
-rw-r--r--lisp/progmodes/cc-engine.el338
-rw-r--r--lisp/progmodes/cc-fonts.el41
-rw-r--r--lisp/progmodes/cc-langs.el4
-rw-r--r--lisp/progmodes/cc-mode.el39
4 files changed, 416 insertions, 6 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 4d6a1203c25..7c77b70de5c 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -83,8 +83,9 @@
83;; 83;;
84;; 'syntax-table 84;; 'syntax-table
85;; Used to modify the syntax of some characters. It is used to 85;; Used to modify the syntax of some characters. It is used to
86;; mark the "<" and ">" of angle bracket parens with paren syntax, and 86;; mark the "<" and ">" of angle bracket parens with paren syntax, to
87;; to "hide" obtrusive characters in preprocessor lines. 87;; "hide" obtrusive characters in preprocessor lines, and to mark C++
88;; raw strings to enable their fontification.
88;; 89;;
89;; This property is used on single characters and is therefore 90;; This property is used on single characters and is therefore
90;; always treated as front and rear nonsticky (or start and end open 91;; always treated as front and rear nonsticky (or start and end open
@@ -2293,7 +2294,8 @@ comment at the start of cc-engine.el for more info."
2293 ;; (STATE TYPE (BEG . END)) if TO is in a literal; or 2294 ;; (STATE TYPE (BEG . END)) if TO is in a literal; or
2294 ;; (STATE) otherwise, 2295 ;; (STATE) otherwise,
2295 ;; where STATE is the parsing state at TO, TYPE is the type of the literal 2296 ;; where STATE is the parsing state at TO, TYPE is the type of the literal
2296 ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal. 2297 ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal,
2298 ;; including the delimiters.
2297 ;; 2299 ;;
2298 ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character 2300 ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character
2299 ;; comment opener, this is recognized as being in a comment literal. 2301 ;; comment opener, this is recognized as being in a comment literal.
@@ -5657,6 +5659,9 @@ comment at the start of cc-engine.el for more info."
5657;; Set by c-common-init in cc-mode.el. 5659;; Set by c-common-init in cc-mode.el.
5658(defvar c-new-BEG) 5660(defvar c-new-BEG)
5659(defvar c-new-END) 5661(defvar c-new-END)
5662;; Set by c-after-change in cc-mode.el.
5663(defvar c-old-BEG)
5664(defvar c-old-END)
5660 5665
5661(defun c-before-change-check-<>-operators (beg end) 5666(defun c-before-change-check-<>-operators (beg end)
5662 ;; Unmark certain pairs of "< .... >" which are currently marked as 5667 ;; Unmark certain pairs of "< .... >" which are currently marked as
@@ -5777,6 +5782,333 @@ comment at the start of cc-engine.el for more info."
5777 'c-decl-arg-start))))))) 5782 'c-decl-arg-start)))))))
5778 (or (c-forward-<>-arglist nil) 5783 (or (c-forward-<>-arglist nil)
5779 (forward-char))))) 5784 (forward-char)))))
5785
5786
5787;; Functions to handle C++ raw strings.
5788;;
5789;; A valid C++ raw string looks like
5790;; R"<id>(<contents>)<id>"
5791;; , where <id> is an identifier from 0 to 16 characters long, not containing
5792;; spaces, control characters, double quote or left/right paren. <contents>
5793;; can include anything which isn't the terminating )<id>", including new
5794;; lines, "s, parentheses, etc.
5795;;
5796;; CC Mode handles C++ raw strings by the use of `syntax-table' text
5797;; properties as follows:
5798;;
5799;; (i) On a validly terminated raw string, no `syntax-table' text properties
5800;; are applied to the opening and closing delimiters, but any " in the
5801;; contents is given the property value "punctuation" (`(1)') to prevent it
5802;; interacting with the "s in the delimiters.
5803;;
5804;; The font locking routine `c-font-lock-c++-raw-strings' (in cc-fonts.el)
5805;; recognizes valid raw strings, and fontifies the delimiters (apart from
5806;; the parentheses) with the default face and the parentheses and the
5807;; <contents> with font-lock-string-face.
5808;;
5809;; (ii) A valid, but unterminated, raw string opening delimiter gets the
5810;; "punctuation" value (`(1)') of the `syntax-table' text property, and the
5811;; open parenthesis gets the "string fence" value (`(15)').
5812;;
5813;; `c-font-lock-c++-raw-strings' puts c-font-lock-warning-face on the entire
5814;; unmatched opening delimiter (from the R up to the open paren), and allows
5815;; the rest of the buffer to get font-lock-string-face, caused by the
5816;; unmatched "string fence" `syntax-table' text property value.
5817;;
5818;; (iii) Inside a macro, a valid raw string is handled as in (i). An
5819;; unmatched opening delimiter is handled slightly differently. In addition
5820;; to the "punctuation" and "string fence" properties on the delimiter,
5821;; another "string fence" `syntax-table' property is applied to the last
5822;; possible character of the macro before the terminating linefeed (if there
5823;; is such a character after the "("). This "last possible" character is
5824;; never a backslash escaping the end of line. If the character preceding
5825;; this "last possible" character is itself a backslash, this preceding
5826;; character gets a "punctuation" `syntax-table' value. If the "(" is
5827;; already at the end of the macro, it gets the "punctuaion" value, and no
5828;; "string fence"s are used.
5829;;
5830;; The effect on the fontification of either of these tactics is that rest of
5831;; the macro (if any) after the "(" gets font-lock-string-face, but the rest
5832;; of the file is fontified normally.
5833
5834
5835(defun c-raw-string-pos ()
5836 ;; Get POINT's relationship to any containing raw string.
5837 ;; If point isn't in a raw string, return nil.
5838 ;; Otherwise, return the following list:
5839 ;;
5840 ;; (POS B\" B\( E\) E\")
5841 ;;
5842 ;; , where POS is the symbol `open-delim' if point is in the opening
5843 ;; delimiter, the symbol `close-delim' if it's in the closing delimiter, and
5844 ;; nil if it's in the string body. B\", B\(, E\), E\" are the positions of
5845 ;; the opening and closing quotes and parentheses of a correctly terminated
5846 ;; raw string. (N.B.: E\) and E\" are NOT on the "outside" of these
5847 ;; characters.) If the raw string is not terminated, E\) and E\" are set to
5848 ;; nil.
5849 ;;
5850 ;; Note: this routine is dependant upon the correct syntax-table text
5851 ;; properties being set.
5852 (let* ((safe (c-state-semi-safe-place (point)))
5853 (state (c-state-pp-to-literal safe (point)))
5854 open-quote-pos open-paren-pos close-paren-pos close-quote-pos id)
5855 (save-excursion
5856 (when
5857 (and
5858 (cond
5859 ((null (cadr state))
5860 (or (eq (char-after) ?\")
5861 (search-backward "\"" (max (- (point) 17) (point-min)) t)))
5862 ((and (eq (cadr state) 'string)
5863 (goto-char (car (nth 2 state)))
5864 (or (eq (char-after) ?\")
5865 (search-backward "\"" (max (- (point) 17) (point-min)) t))
5866 (not (bobp)))))
5867 (eq (char-before) ?R)
5868 (looking-at "\"\\([^ ()\\\n\r\t]\\{,16\\}\\)("))
5869 (setq open-quote-pos (point)
5870 open-paren-pos (match-end 1)
5871 id (match-string-no-properties 1))
5872 (goto-char (1+ open-paren-pos))
5873 (when (and (not (c-get-char-property open-paren-pos 'syntax-table))
5874 (search-forward (concat ")" id "\"") nil t))
5875 (setq close-paren-pos (match-beginning 0)
5876 close-quote-pos (1- (point))))))
5877 (and open-quote-pos
5878 (list
5879 (cond
5880 ((<= (point) open-paren-pos)
5881 'open-delim)
5882 ((and close-paren-pos
5883 (> (point) close-paren-pos))
5884 'close-delim)
5885 (t nil))
5886 open-quote-pos open-paren-pos close-paren-pos close-quote-pos))))
5887
5888(defun c-depropertize-raw-string (id open-quote open-paren bound)
5889 ;; Point is immediately after a raw string opening delimiter. Remove any
5890 ;; `syntax-table' text properties associated with the delimiter (if it's
5891 ;; unmatched) or the raw string.
5892 ;;
5893 ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN
5894 ;; are the buffer positions of the delimiter's components. BOUND is the
5895 ;; bound for searching for a matching closing delimiter; it is usually nil,
5896 ;; but if we're inside a macro, it's the end of the macro.
5897 ;;
5898 ;; Point is moved to after the (terminated) raw string, or left after the
5899 ;; unmatched opening delimiter, as the case may be. The return value is of
5900 ;; no significance.
5901 (let ((open-paren-prop (c-get-char-property open-paren 'syntax-table)))
5902 (cond
5903 ((null open-paren-prop)
5904 ;; A terminated raw string
5905 (if (search-forward (concat ")" id "\"") nil t)
5906 (c-clear-char-property-with-value
5907 (1+ open-paren) (match-beginning 0) 'syntax-table '(1))))
5908 ((or (and (equal open-paren-prop '(15)) (null bound))
5909 (equal open-paren-prop '(1)))
5910 ;; An unterminated raw string either not in a macro, or in a macro with
5911 ;; the open parenthesis right up against the end of macro
5912 (c-clear-char-property open-quote 'syntax-table)
5913 (c-clear-char-property open-paren 'syntax-table))
5914 (t
5915 ;; An unterminated string in a macro, with at least one char after the
5916 ;; open paren
5917 (c-clear-char-property open-quote 'syntax-table)
5918 (c-clear-char-property open-paren 'syntax-table)
5919 (let ((after-string-fence-pos
5920 (save-excursion
5921 (goto-char (1+ open-paren))
5922 (c-search-forward-char-property 'syntax-table '(15) bound))))
5923 (when after-string-fence-pos
5924 (c-clear-char-property (1- after-string-fence-pos) 'syntax-table)))
5925 ))))
5926
5927(defun c-depropertize-raw-strings-in-region (start finish)
5928 ;; Remove any `syntax-table' text properties associated with C++ raw strings
5929 ;; contained in the region (START FINISH). Point is undefined at entry and
5930 ;; exit, and the return value has no significance.
5931 (goto-char start)
5932 (while (and (< (point) finish)
5933 (re-search-forward
5934 (concat "\\(" ; 1
5935 c-anchored-cpp-prefix ; 2
5936 "\\)\\|\\(" ; 3
5937 "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)(" ; 4
5938 "\\)")
5939 finish t))
5940 (when (save-excursion
5941 (goto-char (match-beginning 0)) (not (c-in-literal)))
5942 (if (match-beginning 4) ; the id
5943 ;; We've found a raw string
5944 (c-depropertize-raw-string
5945 (match-string-no-properties 4) ; id
5946 (1+ (match-beginning 3)) ; open quote
5947 (match-end 4) ; open paren
5948 nil) ; bound
5949 ;; We've found a CPP construct. Search for raw strings within it.
5950 (goto-char (match-beginning 2)) ; the "#"
5951 (c-end-of-macro)
5952 (let ((eom (point)))
5953 (goto-char (match-end 2)) ; after the "#".
5954 (while (and (< (point) eom)
5955 (c-syntactic-re-search-forward
5956 "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)(" eom t))
5957 (c-depropertize-raw-string
5958 (match-string-no-properties 1) ; id
5959 (1+ (match-beginning 0)) ; open quote
5960 (match-end 1) ; open paren
5961 eom))))))) ; bound.
5962
5963(defun c-before-change-check-raw-strings (beg end)
5964 ;; This function clears `syntax-table' text properties from C++ raw strings
5965 ;; in the region (c-new-BEG c-new-END). BEG and END are the standard
5966 ;; arguments supplied to any before-change function.
5967 ;;
5968 ;; Point is undefined on both entry and exit, and the return value has no
5969 ;; significance.
5970 ;;
5971 ;; This function is called as a before-change function solely due to its
5972 ;; membership of the C++ value of `c-get-state-before-change-functions'.
5973 (c-save-buffer-state
5974 ((beg-rs (progn (goto-char beg) (c-raw-string-pos)))
5975 (beg-plus (if (null beg-rs)
5976 beg
5977 (max beg
5978 (1+ (or (nth 4 beg-rs) (nth 2 beg-rs))))))
5979 (end-rs (progn (goto-char end) (c-raw-string-pos))) ; FIXME!!!
5980 ; Optimize this so that we don't call
5981 ; `c-raw-string-pos' twice when once
5982 ; will do. (2016-06-02).
5983 (end-minus (if (null end-rs)
5984 end
5985 (min end (cadr end-rs))))
5986 )
5987 (when beg-rs
5988 (setq c-new-BEG (min c-new-BEG (1- (cadr beg-rs)))))
5989 (c-depropertize-raw-strings-in-region c-new-BEG beg-plus)
5990
5991 (when end-rs
5992 (setq c-new-END (max c-new-END
5993 (1+ (or (nth 4 end-rs)
5994 (nth 2 end-rs))))))
5995 (c-depropertize-raw-strings-in-region end-minus c-new-END)))
5996
5997(defun c-propertize-raw-string-opener (id open-quote open-paren bound)
5998 ;; Point is immediately after a raw string opening delimiter. Apply any
5999 ;; pertinent `syntax-table' text properties to the delimiter and also the
6000 ;; raw string, should there be a valid matching closing delimiter.
6001 ;;
6002 ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN
6003 ;; are the buffer positions of the delimiter's components. BOUND is the
6004 ;; bound for searching for a matching closing delimiter; it is usually nil,
6005 ;; but if we're inside a macro, it's the end of the macro.
6006 ;;
6007 ;; Point is moved to after the (terminated) raw string, or left after the
6008 ;; unmatched opening delimiter, as the case may be. The return value is of
6009 ;; no significance.
6010 (if (search-forward (concat ")" id "\"") bound t)
6011 (let ((end-string (match-beginning 0))
6012 (after-quote (match-end 0)))
6013 (goto-char open-paren)
6014 (while (progn (skip-syntax-forward "^\"" end-string)
6015 (< (point) end-string))
6016 (c-put-char-property (point) 'syntax-table '(1)) ; punctuation
6017 (forward-char))
6018 (goto-char after-quote))
6019 (c-put-char-property open-quote 'syntax-table '(1)) ; punctuation
6020 (c-put-char-property open-paren 'syntax-table '(15)) ; generic string
6021 (when bound
6022 ;; In a CPP construct, we try to apply a generic-string `syntax-table'
6023 ;; text property to the last possible character in the string, so that
6024 ;; only characters within the macro get "stringed out".
6025 (goto-char bound)
6026 (if (save-restriction
6027 (narrow-to-region (1+ open-paren) (point-max))
6028 (re-search-backward
6029 (eval-when-compile
6030 ;; This regular expression matches either an escape pair (which
6031 ;; isn't an escaped NL) (submatch 5) or a non-escaped character
6032 ;; (which isn't itself a backslash) (submatch 10). The long
6033 ;; preambles to these (respectively submatches 2-4 and 6-9)
6034 ;; ensure that we have the correct parity for sequences of
6035 ;; backslashes, etc..
6036 (concat "\\(" ; 1
6037 "\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)*" ; 2-4
6038 "\\(\\\\.\\)" ; 5
6039 "\\|"
6040 "\\(\\`\\|[^\\]\\|\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)+\\)" ; 6-9
6041 "\\([^\\]\\)" ; 10
6042 "\\)"
6043 "\\(\\\\\n\\)*\\=")) ; 11
6044 (1+ open-paren) t))
6045 (if (match-beginning 10)
6046 (c-put-char-property (match-beginning 10) 'syntax-table '(15))
6047 (c-put-char-property (match-beginning 5) 'syntax-table '(1))
6048 (c-put-char-property (1+ (match-beginning 5)) 'syntax-table '(15)))
6049 (c-put-char-property open-paren 'syntax-table '(1)))
6050 (goto-char bound))))
6051
6052(defun c-after-change-re-mark-raw-strings (beg end old-len)
6053 ;; This function applies `syntax-table' text properties to C++ raw strings
6054 ;; beginning in the region (c-new-BEG c-new-END). BEG, END, and OLD-LEN are
6055 ;; the standard arguments supplied to any after-change function.
6056 ;;
6057 ;; Point is undefined on both entry and exit, and the return value has no
6058 ;; significance.
6059 ;;
6060 ;; This function is called as an after-change function solely due to its
6061 ;; membership of the C++ value of `c-before-font-lock-functions'.
6062 (c-save-buffer-state ()
6063 ;; If the region (c-new-BEG c-new-END) has expanded, remove
6064 ;; `syntax-table' text-properties from the new piece(s).
6065 (when (< c-new-BEG c-old-BEG)
6066 (let ((beg-rs (progn (goto-char c-old-BEG) (c-raw-string-pos))))
6067 (c-depropertize-raw-strings-in-region
6068 c-new-BEG
6069 (if beg-rs
6070 (1+ (or (nth 4 beg-rs) (nth 2 beg-rs)))
6071 c-old-BEG))))
6072 (when (> c-new-END c-old-END)
6073 (let ((end-rs (progn (goto-char c-old-END) (c-raw-string-pos))))
6074 (c-depropertize-raw-strings-in-region
6075 (if end-rs
6076 (cadr end-rs)
6077 c-old-END)
6078 c-new-END)))
6079
6080 (goto-char c-new-BEG)
6081 (while (and (< (point) c-new-END)
6082 (re-search-forward
6083 (concat "\\(" ; 1
6084 c-anchored-cpp-prefix ; 2
6085 "\\)\\|\\(" ; 3
6086 "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)(" ; 4
6087 "\\)")
6088 c-new-END t))
6089 (when (save-excursion
6090 (goto-char (match-beginning 0)) (not (c-in-literal)))
6091 (if (match-beginning 4) ; the id
6092 ;; We've found a raw string.
6093 (c-propertize-raw-string-opener
6094 (match-string-no-properties 4) ; id
6095 (1+ (match-beginning 3)) ; open quote
6096 (match-end 4) ; open paren
6097 nil) ; bound
6098 ;; We've found a CPP construct. Search for raw strings within it.
6099 (goto-char (match-beginning 2)) ; the "#"
6100 (c-end-of-macro)
6101 (let ((eom (point)))
6102 (goto-char (match-end 2)) ; after the "#".
6103 (while (and (< (point) eom)
6104 (c-syntactic-re-search-forward
6105 "R\"\\([^ ()\\\n\r\t]\\{,16\\}\\)(" eom t))
6106 (c-propertize-raw-string-opener
6107 (match-string-no-properties 1) ; id
6108 (1+ (match-beginning 0)) ; open quote
6109 (match-end 1) ; open paren
6110 eom)))))))) ; bound
6111
5780 6112
5781;; Handling of small scale constructs like types and names. 6113;; Handling of small scale constructs like types and names.
5782 6114
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 4e83d6df620..f3f369f5f8c 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -723,6 +723,10 @@ casts and declarations are fontified. Used on level 2 and higher."
723 (concat ".\\(" c-string-limit-regexp "\\)") 723 (concat ".\\(" c-string-limit-regexp "\\)")
724 '((c-font-lock-invalid-string))) 724 '((c-font-lock-invalid-string)))
725 725
726 ;; Fontify C++ raw strings.
727 ,@(when (c-major-mode-is 'c++-mode)
728 '(c-font-lock-raw-strings))
729
726 ;; Fontify keyword constants. 730 ;; Fontify keyword constants.
727 ,@(when (c-lang-const c-constant-kwds) 731 ,@(when (c-lang-const c-constant-kwds)
728 (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds)))) 732 (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds))))
@@ -1571,6 +1575,43 @@ casts and declarations are fontified. Used on level 2 and higher."
1571 (c-forward-syntactic-ws) 1575 (c-forward-syntactic-ws)
1572 (c-font-lock-declarators limit t in-typedef))))))) 1576 (c-font-lock-declarators limit t in-typedef)))))))
1573 1577
1578(defun c-font-lock-raw-strings (limit)
1579 ;; Fontify C++ raw strings.
1580 ;;
1581 ;; This function will be called from font-lock for a region bounded by POINT
1582 ;; and LIMIT, as though it were to identify a keyword for
1583 ;; font-lock-keyword-face. It always returns NIL to inhibit this and
1584 ;; prevent a repeat invocation. See elisp/lispref page "Search-based
1585 ;; Fontification".
1586 (while (search-forward-regexp
1587 "R\\(\"\\)\\([^ ()\\\n\r\t]\\{,16\\}\\)(" limit t)
1588 (when
1589 (or (and (eobp)
1590 (eq (c-get-char-property (1- (point)) 'face)
1591 'font-lock-warning-face))
1592 (eq (c-get-char-property (point) 'face) 'font-lock-string-face)
1593 (and (equal (c-get-char-property (match-end 2) 'syntax-table) '(1))
1594 (equal (c-get-char-property (match-beginning 1) 'syntax-table)
1595 '(1))))
1596 (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table)))
1597 (if paren-prop
1598 (progn
1599 (c-put-font-lock-face (match-beginning 0) (match-end 0)
1600 'font-lock-warning-face)
1601 (when
1602 (and
1603 (equal paren-prop '(15))
1604 (not (c-search-forward-char-property 'syntax-table '(15) limit)))
1605 (goto-char limit)))
1606 (c-put-font-lock-face (match-beginning 1) (match-end 2) 'default)
1607 (when (search-forward-regexp
1608 (concat ")\\(" (regexp-quote (match-string-no-properties 2))
1609 "\\)\"")
1610 limit t)
1611 (c-put-font-lock-face (match-beginning 1) (point)
1612 'default))))))
1613 nil)
1614
1574(c-lang-defconst c-simple-decl-matchers 1615(c-lang-defconst c-simple-decl-matchers
1575 "Simple font lock matchers for types and declarations. These are used 1616 "Simple font lock matchers for types and declarations. These are used
1576on level 2 only and so aren't combined with `c-complex-decl-matchers'." 1617on level 2 only and so aren't combined with `c-complex-decl-matchers'."
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 18f1cc4374a..ba05e81aba3 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -474,9 +474,12 @@ so that all identifiers are recognized as words.")
474 ;; The value here may be a list of functions or a single function. 474 ;; The value here may be a list of functions or a single function.
475 t nil 475 t nil
476 c++ '(c-extend-region-for-CPP 476 c++ '(c-extend-region-for-CPP
477 c-before-change-check-raw-strings
477 c-before-change-check-<>-operators 478 c-before-change-check-<>-operators
479 c-depropertize-CPP
478 c-invalidate-macro-cache) 480 c-invalidate-macro-cache)
479 (c objc) '(c-extend-region-for-CPP 481 (c objc) '(c-extend-region-for-CPP
482 c-depropertize-CPP
480 c-invalidate-macro-cache) 483 c-invalidate-macro-cache)
481 ;; java 'c-before-change-check-<>-operators 484 ;; java 'c-before-change-check-<>-operators
482 awk 'c-awk-record-region-clear-NL) 485 awk 'c-awk-record-region-clear-NL)
@@ -510,6 +513,7 @@ parameters \(point-min) and \(point-max).")
510 c-neutralize-syntax-in-and-mark-CPP 513 c-neutralize-syntax-in-and-mark-CPP
511 c-change-expand-fl-region) 514 c-change-expand-fl-region)
512 c++ '(c-extend-font-lock-region-for-macros 515 c++ '(c-extend-font-lock-region-for-macros
516 c-after-change-re-mark-raw-strings
513 c-neutralize-syntax-in-and-mark-CPP 517 c-neutralize-syntax-in-and-mark-CPP
514 c-restore-<>-properties 518 c-restore-<>-properties
515 c-change-expand-fl-region) 519 c-change-expand-fl-region)
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 9ab04808af6..6f326133671 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -665,6 +665,14 @@ that requires a literal mode spec at compile time."
665(make-variable-buffer-local 'c-new-BEG) 665(make-variable-buffer-local 'c-new-BEG)
666(defvar c-new-END 0) 666(defvar c-new-END 0)
667(make-variable-buffer-local 'c-new-END) 667(make-variable-buffer-local 'c-new-END)
668;; The following two variables record the values of `c-new-BEG' and
669;; `c-new-END' just after `c-new-END' has been adjusted for the length of text
670;; inserted or removed. They may be read by any after-change function (but
671;; should not be altered by one).
672(defvar c-old-BEG 0)
673(make-variable-buffer-local 'c-old-BEG)
674(defvar c-old-END 0)
675(make-variable-buffer-local 'c-old-END)
668 676
669(defun c-common-init (&optional mode) 677(defun c-common-init (&optional mode)
670 "Common initialization for all CC Mode modes. 678 "Common initialization for all CC Mode modes.
@@ -877,6 +885,31 @@ Note that the style variables are always made local to the buffer."
877 (memq (cadr (backtrace-frame 3)) 885 (memq (cadr (backtrace-frame 3))
878 '(put-text-property remove-list-of-text-properties))) 886 '(put-text-property remove-list-of-text-properties)))
879 887
888(defun c-depropertize-CPP (beg end)
889 ;; Remove the punctuation syntax-table text property from the CPP parts of
890 ;; (c-new-BEG c-new-END).
891 ;;
892 ;; This function is in the C/C++/ObjC values of
893 ;; `c-get-state-before-change-functions' and is called exclusively as a
894 ;; before change function.
895 (goto-char c-new-BEG)
896 (while (and (< (point) beg)
897 (search-forward-regexp c-anchored-cpp-prefix beg t))
898 (goto-char (match-beginning 1))
899 (let ((m-beg (point)))
900 (c-end-of-macro)
901 (c-clear-char-property-with-value
902 m-beg (min (point) beg) 'syntax-table '(1))))
903
904 (goto-char end)
905 (while (and (< (point) c-new-END)
906 (search-forward-regexp c-anchored-cpp-prefix c-new-END t))
907 (goto-char (match-beginning 1))
908 (let ((m-beg (point)))
909 (c-end-of-macro)
910 (c-clear-char-property-with-value
911 m-beg (min (point) c-new-END) 'syntax-table '(1)))))
912
880(defun c-extend-region-for-CPP (beg end) 913(defun c-extend-region-for-CPP (beg end)
881 ;; Adjust `c-new-BEG', `c-new-END' respectively to the beginning and end of 914 ;; Adjust `c-new-BEG', `c-new-END' respectively to the beginning and end of
882 ;; any preprocessor construct they may be in. 915 ;; any preprocessor construct they may be in.
@@ -967,9 +1000,9 @@ Note that the style variables are always made local to the buffer."
967 ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!! 1000 ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
968 ;; 1001 ;;
969 ;; This function might make hidden buffer changes. 1002 ;; This function might make hidden buffer changes.
970 (c-save-buffer-state (limits ) 1003 (c-save-buffer-state (limits)
971 ;; Clear 'syntax-table properties "punctuation": 1004 ;; Clear 'syntax-table properties "punctuation":
972 (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1)) 1005 ;; (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
973 1006
974 ;; CPP "comment" markers: 1007 ;; CPP "comment" markers:
975 (if (eval-when-compile (memq 'category-properties c-emacs-features));Emacs. 1008 (if (eval-when-compile (memq 'category-properties c-emacs-features));Emacs.
@@ -1125,8 +1158,8 @@ Note that the style variables are always made local to the buffer."
1125 1158
1126 ;; (c-new-BEG c-new-END) will be the region to fontify. It may become 1159 ;; (c-new-BEG c-new-END) will be the region to fontify. It may become
1127 ;; larger than (beg end). 1160 ;; larger than (beg end).
1128 ;; (setq c-new-BEG beg c-new-END end)
1129 (setq c-new-END (- (+ c-new-END (- end beg)) old-len)) 1161 (setq c-new-END (- (+ c-new-END (- end beg)) old-len))
1162 (setq c-old-BEG c-new-BEG c-old-END c-new-END)
1130 1163
1131 (unless (c-called-from-text-property-change-p) 1164 (unless (c-called-from-text-property-change-p)
1132 (setq c-just-done-before-change nil) 1165 (setq c-just-done-before-change nil)