diff options
| author | Alan Mackenzie | 2019-03-27 11:50:53 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2019-03-27 11:50:53 +0000 |
| commit | 29ec1e48883dbdce8f9f81ac25d9ec38c474cdcb (patch) | |
| tree | ce9c31a6c3c6d4c0b521b24264294f897a4c4216 | |
| parent | c26704483726d454cd554406d41dd7bfde537454 (diff) | |
| download | emacs-29ec1e48883dbdce8f9f81ac25d9ec38c474cdcb.tar.gz emacs-29ec1e48883dbdce8f9f81ac25d9ec38c474cdcb.zip | |
Improve C++ raw string fontification.
Integrate the handling of raw string and ordinary string fontification.
* lisp/progmodes/cc-defs.el (c-font-lock-flush)
(c-search-forward-char-property-without-value-on-char): new macros.
(c-point): In the 'eoll arm, check for eobp.
(c-search-forward-char-property-with-value-on-char): Handle the &optional
limit argument being nil.
(c-clear-char-property-with-value-on-char-function)
(c-clear-char-property-with-value-on-char): Return the position of the first
cleared property.
* lisp/progmodes/cc-engine.el (c-find-decl-prefix-search): Don't spuriously
recognize the change of face at a ) as the start of a string (a
"pseudo match").
(c-old-beg-rs c-old-end-rs): New variables.
(c-raw-string-pos): Analyze raw string delimiters more carefully.
(c-raw-string-in-end-delim): New function.
(c-depropertize-raw-string): Largely rewritten.
(c-before-change-check-raw-strings): New functionality: only remove the
syntax-table text properties from raw strings whose delimiters are about to
change.
(c-propertize-raw-string-id): New function.
(c-after-change-re-mark-raw-strings): Remove, incorporating functionality into
other functions.
(c-propertize-raw-string-opener): Largely rewritten.
(c-after-change-re-mark-raw-strings): Removed.
(c-after-change-unmark-raw-strings, c-after-change-unmark-raw-strings): New
functions.
* lisp/progmodes/cc-fonts.el (c-font-lock-raw-strings): Largely rewritten.
* lisp/progmodes/cc-langs.el (c-before-font-lock-functions): Replace
c-after-change-re-mark-unbalanced-strings by
c-after-change-mark-abnormal-strings in the t, c+objc, c++ and java sections.
Add c-after-change-unmark-raw-strings and remove
c-after-change-re-mark-raw-strings from the c++ section.
* lisp/progmodes/cc-mode.el (c-old-BEG c-old-END): Remove.
(c-old-END-literality): New variable.
(c-depropertize-CPP): Remove syntax-table properties from raw strings within
macros.
(c-before-change-check-unbalanced-strings): Call
c-truncate-semi-nonlit-pos-cache to preserve the integrity of the cache.
(c-before-change-check-unbalanced-strings): Call
c-truncate-semi-nonlit-pos-cache, largely rewritten.
(c-after-change-re-mark-unbalanced-strings): Renamed to
c-after-change-mark-abnormal-strings. Call c-maybe-re-mark-raw-string.
| -rw-r--r-- | lisp/progmodes/cc-defs.el | 76 | ||||
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 584 | ||||
| -rw-r--r-- | lisp/progmodes/cc-fonts.el | 40 | ||||
| -rw-r--r-- | lisp/progmodes/cc-langs.el | 10 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 90 |
5 files changed, 562 insertions, 238 deletions
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 97272ca9d21..87ddf3ac1e2 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el | |||
| @@ -212,6 +212,13 @@ This variant works around bugs in `eval-when-compile' in various | |||
| 212 | `(cl-delete-duplicates ,cl-seq ,@cl-keys) | 212 | `(cl-delete-duplicates ,cl-seq ,@cl-keys) |
| 213 | `(delete-duplicates ,cl-seq ,@cl-keys)))) | 213 | `(delete-duplicates ,cl-seq ,@cl-keys)))) |
| 214 | 214 | ||
| 215 | (defmacro c-font-lock-flush (beg end) | ||
| 216 | "Declare the region BEG...END's fontification as out-of-date. | ||
| 217 | On XEmacs and older Emacsen, this refontifies that region immediately." | ||
| 218 | (if (fboundp 'font-lock-flush) | ||
| 219 | `(font-lock-flush ,beg ,end) | ||
| 220 | `(font-lock-fontify-region ,beg ,end))) | ||
| 221 | |||
| 215 | (defmacro c-point (position &optional point) | 222 | (defmacro c-point (position &optional point) |
| 216 | "Return the value of certain commonly referenced POSITIONs relative to POINT. | 223 | "Return the value of certain commonly referenced POSITIONs relative to POINT. |
| 217 | The current point is used if POINT isn't specified. POSITION can be | 224 | The current point is used if POINT isn't specified. POSITION can be |
| @@ -258,10 +265,12 @@ to it is returned. This function does not modify the point or the mark." | |||
| 258 | ((eq position 'eoll) | 265 | ((eq position 'eoll) |
| 259 | `(save-excursion | 266 | `(save-excursion |
| 260 | ,@(if point `((goto-char ,point))) | 267 | ,@(if point `((goto-char ,point))) |
| 261 | (while (progn | 268 | (while (and |
| 262 | (end-of-line) | 269 | (not (eobp)) |
| 263 | (prog1 (eq (logand 1 (skip-chars-backward "\\\\")) 1))) | 270 | (progn |
| 264 | (beginning-of-line 2)) | 271 | (end-of-line) |
| 272 | (prog1 (eq (logand 1 (skip-chars-backward "\\\\")) 1)))) | ||
| 273 | (forward-line)) | ||
| 265 | (end-of-line) | 274 | (end-of-line) |
| 266 | (point))) | 275 | (point))) |
| 267 | 276 | ||
| @@ -1214,7 +1223,7 @@ Leave point just after the character, and set the match data on | |||
| 1214 | this character, and return point. If the search fails, return | 1223 | this character, and return point. If the search fails, return |
| 1215 | nil; point is then left undefined." | 1224 | nil; point is then left undefined." |
| 1216 | `(let ((char-skip (concat "^" (char-to-string ,char))) | 1225 | `(let ((char-skip (concat "^" (char-to-string ,char))) |
| 1217 | (-limit- ,limit) | 1226 | (-limit- (or ,limit (point-max))) |
| 1218 | (-value- ,value)) | 1227 | (-value- ,value)) |
| 1219 | (while | 1228 | (while |
| 1220 | (and | 1229 | (and |
| @@ -1226,15 +1235,39 @@ nil; point is then left undefined." | |||
| 1226 | (search-forward-regexp ".") ; to set the match-data. | 1235 | (search-forward-regexp ".") ; to set the match-data. |
| 1227 | (point)))) | 1236 | (point)))) |
| 1228 | 1237 | ||
| 1238 | (defmacro c-search-forward-char-property-without-value-on-char | ||
| 1239 | (property value char &optional limit) | ||
| 1240 | "Search forward for a character CHAR without text property PROPERTY having | ||
| 1241 | a value CHAR. | ||
| 1242 | LIMIT bounds the search. The value comparison is done with `equal'. | ||
| 1243 | PROPERTY must be a constant. | ||
| 1244 | |||
| 1245 | Leave point just after the character, and set the match data on | ||
| 1246 | this character, and return point. If the search fails, return | ||
| 1247 | nil; point is then left undefined." | ||
| 1248 | `(let ((char-skip (concat "^" (char-to-string ,char))) | ||
| 1249 | (-limit- (or ,limit (point-max))) | ||
| 1250 | (-value- ,value)) | ||
| 1251 | (while | ||
| 1252 | (and | ||
| 1253 | (progn (skip-chars-forward char-skip -limit-) | ||
| 1254 | (< (point) -limit-)) | ||
| 1255 | (equal (c-get-char-property (point) ,property) -value-)) | ||
| 1256 | (forward-char)) | ||
| 1257 | (when (< (point) -limit-) | ||
| 1258 | (search-forward-regexp ".") ; to set the match-data. | ||
| 1259 | (point)))) | ||
| 1260 | |||
| 1229 | (defun c-clear-char-property-with-value-on-char-function (from to property | 1261 | (defun c-clear-char-property-with-value-on-char-function (from to property |
| 1230 | value char) | 1262 | value char) |
| 1231 | "Remove all text-properties PROPERTY with value VALUE on | 1263 | "Remove all text-properties PROPERTY with value VALUE on |
| 1232 | characters with value CHAR from the region [FROM, TO), as tested | 1264 | characters with value CHAR from the region [FROM, TO), as tested |
| 1233 | by `equal'. These properties are assumed to be over individual | 1265 | by `equal'. These properties are assumed to be over individual |
| 1234 | characters, having been put there by c-put-char-property. POINT | 1266 | characters, having been put there by c-put-char-property. POINT |
| 1235 | remains unchanged." | 1267 | remains unchanged. Return the position of the first removed |
| 1268 | property, or nil." | ||
| 1236 | (let ((place from) | 1269 | (let ((place from) |
| 1237 | ) | 1270 | first) |
| 1238 | (while ; loop round occurrences of (PROPERTY VALUE) | 1271 | (while ; loop round occurrences of (PROPERTY VALUE) |
| 1239 | (progn | 1272 | (progn |
| 1240 | (while ; loop round changes in PROPERTY till we find VALUE | 1273 | (while ; loop round changes in PROPERTY till we find VALUE |
| @@ -1243,28 +1276,34 @@ remains unchanged." | |||
| 1243 | (not (equal (get-text-property place property) value))) | 1276 | (not (equal (get-text-property place property) value))) |
| 1244 | (setq place (c-next-single-property-change place property nil to))) | 1277 | (setq place (c-next-single-property-change place property nil to))) |
| 1245 | (< place to)) | 1278 | (< place to)) |
| 1246 | (if (eq (char-after place) char) | 1279 | (when (eq (char-after place) char) |
| 1247 | (remove-text-properties place (1+ place) (cons property nil))) | 1280 | (remove-text-properties place (1+ place) (cons property nil)) |
| 1281 | (or first (setq first place))) | ||
| 1248 | ;; Do we have to do anything with stickiness here? | 1282 | ;; Do we have to do anything with stickiness here? |
| 1249 | (setq place (1+ place))))) | 1283 | (setq place (1+ place))) |
| 1284 | first)) | ||
| 1250 | 1285 | ||
| 1251 | (defmacro c-clear-char-property-with-value-on-char (from to property value char) | 1286 | (defmacro c-clear-char-property-with-value-on-char (from to property value char) |
| 1252 | "Remove all text-properties PROPERTY with value VALUE on | 1287 | "Remove all text-properties PROPERTY with value VALUE on |
| 1253 | characters with value CHAR from the region [FROM, TO), as tested | 1288 | characters with value CHAR from the region [FROM, TO), as tested |
| 1254 | by `equal'. These properties are assumed to be over individual | 1289 | by `equal'. These properties are assumed to be over individual |
| 1255 | characters, having been put there by c-put-char-property. POINT | 1290 | characters, having been put there by c-put-char-property. POINT |
| 1256 | remains unchanged." | 1291 | remains unchanged. Return the position of the first removed |
| 1292 | property, or nil." | ||
| 1257 | (if c-use-extents | 1293 | (if c-use-extents |
| 1258 | ;; XEmacs | 1294 | ;; XEmacs |
| 1259 | `(let ((-property- ,property) | 1295 | `(let ((-property- ,property) |
| 1260 | (-char- ,char)) | 1296 | (-char- ,char) |
| 1297 | (first (1+ (point-max)))) | ||
| 1261 | (map-extents (lambda (ext val) | 1298 | (map-extents (lambda (ext val) |
| 1262 | (if (and (equal (extent-property ext -property-) val) | 1299 | (when (and (equal (extent-property ext -property-) val) |
| 1263 | (eq (char-after | 1300 | (eq (char-after |
| 1264 | (extent-start-position ext)) | 1301 | (extent-start-position ext)) |
| 1265 | -char-)) | 1302 | -char-)) |
| 1266 | (delete-extent ext))) | 1303 | (setq first (min first (extent-start-position ext))) |
| 1267 | nil ,from ,to ,value nil -property-)) | 1304 | (delete-extent ext))) |
| 1305 | nil ,from ,to ,value nil -property-) | ||
| 1306 | (and (<= first (point-max)) first)) | ||
| 1268 | ;; GNU Emacs | 1307 | ;; GNU Emacs |
| 1269 | `(c-clear-char-property-with-value-on-char-function ,from ,to ,property | 1308 | `(c-clear-char-property-with-value-on-char-function ,from ,to ,property |
| 1270 | ,value ,char))) | 1309 | ,value ,char))) |
| @@ -1316,6 +1355,7 @@ with value CHAR in the region [FROM to)." | |||
| 1316 | ;(eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el. | 1355 | ;(eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el. |
| 1317 | ; '(progn | 1356 | ; '(progn |
| 1318 | (def-edebug-spec cc-eval-when-compile (&rest def-form)) | 1357 | (def-edebug-spec cc-eval-when-compile (&rest def-form)) |
| 1358 | (def-edebug-spec c-font-lock-flush t) | ||
| 1319 | (def-edebug-spec c--mapcan t) | 1359 | (def-edebug-spec c--mapcan t) |
| 1320 | (def-edebug-spec c--set-difference (form form &rest [symbolp form])) | 1360 | (def-edebug-spec c--set-difference (form form &rest [symbolp form])) |
| 1321 | (def-edebug-spec c--intersection (form form &rest [symbolp form])) | 1361 | (def-edebug-spec c--intersection (form form &rest [symbolp form])) |
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index cc3753a7ebd..1a8c5164906 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -5646,8 +5646,12 @@ comment at the start of cc-engine.el for more info." | |||
| 5646 | ;; Pseudo match inside a comment or string literal. Skip out | 5646 | ;; Pseudo match inside a comment or string literal. Skip out |
| 5647 | ;; of comments and string literals. | 5647 | ;; of comments and string literals. |
| 5648 | (while (progn | 5648 | (while (progn |
| 5649 | (goto-char (c-next-single-property-change | 5649 | (unless |
| 5650 | (point) 'face nil cfd-limit)) | 5650 | (and (match-end 1) |
| 5651 | (c-got-face-at (1- (point)) c-literal-faces) | ||
| 5652 | (not (c-got-face-at (point) c-literal-faces))) | ||
| 5653 | (goto-char (c-next-single-property-change | ||
| 5654 | (point) 'face nil cfd-limit))) | ||
| 5651 | (and (< (point) cfd-limit) | 5655 | (and (< (point) cfd-limit) |
| 5652 | (c-got-face-at (point) c-literal-faces)))) | 5656 | (c-got-face-at (point) c-literal-faces)))) |
| 5653 | t) ; Continue the loop over pseudo matches. | 5657 | t) ; Continue the loop over pseudo matches. |
| @@ -6350,9 +6354,8 @@ comment at the start of cc-engine.el for more info." | |||
| 6350 | ;; Set by c-common-init in cc-mode.el. | 6354 | ;; Set by c-common-init in cc-mode.el. |
| 6351 | (defvar c-new-BEG) | 6355 | (defvar c-new-BEG) |
| 6352 | (defvar c-new-END) | 6356 | (defvar c-new-END) |
| 6353 | ;; Set by c-after-change in cc-mode.el. | 6357 | ;; Set by c-before-change-check-raw-strings. |
| 6354 | (defvar c-old-BEG) | 6358 | (defvar c-old-END-literality) |
| 6355 | (defvar c-old-END) | ||
| 6356 | 6359 | ||
| 6357 | (defun c-before-change-check-<>-operators (beg end) | 6360 | (defun c-before-change-check-<>-operators (beg end) |
| 6358 | ;; Unmark certain pairs of "< .... >" which are currently marked as | 6361 | ;; Unmark certain pairs of "< .... >" which are currently marked as |
| @@ -6484,9 +6487,9 @@ comment at the start of cc-engine.el for more info." | |||
| 6484 | ;; A valid C++ raw string looks like | 6487 | ;; A valid C++ raw string looks like |
| 6485 | ;; R"<id>(<contents>)<id>" | 6488 | ;; R"<id>(<contents>)<id>" |
| 6486 | ;; , where <id> is an identifier from 0 to 16 characters long, not containing | 6489 | ;; , where <id> is an identifier from 0 to 16 characters long, not containing |
| 6487 | ;; spaces, control characters, double quote or left/right paren. <contents> | 6490 | ;; spaces, control characters, or left/right paren. <contents> can include |
| 6488 | ;; can include anything which isn't the terminating )<id>", including new | 6491 | ;; anything which isn't the terminating )<id>", including new lines, "s, |
| 6489 | ;; lines, "s, parentheses, etc. | 6492 | ;; parentheses, etc. |
| 6490 | ;; | 6493 | ;; |
| 6491 | ;; CC Mode handles C++ raw strings by the use of `syntax-table' text | 6494 | ;; CC Mode handles C++ raw strings by the use of `syntax-table' text |
| 6492 | ;; properties as follows: | 6495 | ;; properties as follows: |
| @@ -6496,16 +6499,18 @@ comment at the start of cc-engine.el for more info." | |||
| 6496 | ;; contents is given the property value "punctuation" (`(1)') to prevent it | 6499 | ;; contents is given the property value "punctuation" (`(1)') to prevent it |
| 6497 | ;; interacting with the "s in the delimiters. | 6500 | ;; interacting with the "s in the delimiters. |
| 6498 | ;; | 6501 | ;; |
| 6499 | ;; The font locking routine `c-font-lock-c++-raw-strings' (in cc-fonts.el) | 6502 | ;; The font locking routine `c-font-lock-raw-strings' (in cc-fonts.el) |
| 6500 | ;; recognizes valid raw strings, and fontifies the delimiters (apart from | 6503 | ;; recognizes valid raw strings, and fontifies the delimiters (apart from |
| 6501 | ;; the parentheses) with the default face and the parentheses and the | 6504 | ;; the parentheses) with the default face and the parentheses and the |
| 6502 | ;; <contents> with font-lock-string-face. | 6505 | ;; <contents> with font-lock-string-face. |
| 6503 | ;; | 6506 | ;; |
| 6504 | ;; (ii) A valid, but unterminated, raw string opening delimiter gets the | 6507 | ;; (ii) A valid, but unterminated, raw string opening delimiter gets the |
| 6505 | ;; "punctuation" value (`(1)') of the `syntax-table' text property, and the | 6508 | ;; "punctuation" value (`(1)') of the `syntax-table' text property, and the |
| 6506 | ;; open parenthesis gets the "string fence" value (`(15)'). | 6509 | ;; open parenthesis gets the "string fence" value (`(15)'). When such a |
| 6510 | ;; delimiter is found, no attempt is made in any way to "correct" any text | ||
| 6511 | ;; properties after the delimiter. | ||
| 6507 | ;; | 6512 | ;; |
| 6508 | ;; `c-font-lock-c++-raw-strings' puts c-font-lock-warning-face on the entire | 6513 | ;; `c-font-lock-raw-strings' puts c-font-lock-warning-face on the entire |
| 6509 | ;; unmatched opening delimiter (from the R up to the open paren), and allows | 6514 | ;; unmatched opening delimiter (from the R up to the open paren), and allows |
| 6510 | ;; the rest of the buffer to get font-lock-string-face, caused by the | 6515 | ;; the rest of the buffer to get font-lock-string-face, caused by the |
| 6511 | ;; unmatched "string fence" `syntax-table' text property value. | 6516 | ;; unmatched "string fence" `syntax-table' text property value. |
| @@ -6522,10 +6527,14 @@ comment at the start of cc-engine.el for more info." | |||
| 6522 | ;; already at the end of the macro, it gets the "punctuation" value, and no | 6527 | ;; already at the end of the macro, it gets the "punctuation" value, and no |
| 6523 | ;; "string fence"s are used. | 6528 | ;; "string fence"s are used. |
| 6524 | ;; | 6529 | ;; |
| 6525 | ;; The effect on the fontification of either of these tactics is that rest of | 6530 | ;; The effect on the fontification of either of these tactics is that the |
| 6526 | ;; the macro (if any) after the "(" gets font-lock-string-face, but the rest | 6531 | ;; rest of the macro (if any) after the "(" gets font-lock-string-face, but |
| 6527 | ;; of the file is fontified normally. | 6532 | ;; the rest of the file is fontified normally. |
| 6528 | 6533 | ||
| 6534 | ;; The values of the function `c-raw-string-pos' at before-change-functions' | ||
| 6535 | ;; BEG and END. | ||
| 6536 | (defvar c-old-beg-rs nil) | ||
| 6537 | (defvar c-old-end-rs nil) | ||
| 6529 | 6538 | ||
| 6530 | (defun c-raw-string-pos () | 6539 | (defun c-raw-string-pos () |
| 6531 | ;; Get POINT's relationship to any containing raw string. | 6540 | ;; Get POINT's relationship to any containing raw string. |
| @@ -6542,7 +6551,7 @@ comment at the start of cc-engine.el for more info." | |||
| 6542 | ;; characters.) If the raw string is not terminated, E\) and E\" are set to | 6551 | ;; characters.) If the raw string is not terminated, E\) and E\" are set to |
| 6543 | ;; nil. | 6552 | ;; nil. |
| 6544 | ;; | 6553 | ;; |
| 6545 | ;; Note: this routine is dependant upon the correct syntax-table text | 6554 | ;; Note: this function is dependant upon the correct syntax-table text |
| 6546 | ;; properties being set. | 6555 | ;; properties being set. |
| 6547 | (let ((state (c-state-semi-pp-to-literal (point))) | 6556 | (let ((state (c-state-semi-pp-to-literal (point))) |
| 6548 | open-quote-pos open-paren-pos close-paren-pos close-quote-pos id) | 6557 | open-quote-pos open-paren-pos close-paren-pos close-quote-pos id) |
| @@ -6555,8 +6564,20 @@ comment at the start of cc-engine.el for more info." | |||
| 6555 | (search-backward "\"" (max (- (point) 17) (point-min)) t))) | 6564 | (search-backward "\"" (max (- (point) 17) (point-min)) t))) |
| 6556 | ((and (eq (cadr state) 'string) | 6565 | ((and (eq (cadr state) 'string) |
| 6557 | (goto-char (nth 2 state)) | 6566 | (goto-char (nth 2 state)) |
| 6558 | (or (eq (char-after) ?\") | 6567 | (cond |
| 6559 | (search-backward "\"" (max (- (point) 17) (point-min)) t)) | 6568 | ((eq (char-after) ?\")) |
| 6569 | ((eq (char-after) ?\() | ||
| 6570 | (let ((here (point))) | ||
| 6571 | (goto-char (max (- (point) 18) (point-min))) | ||
| 6572 | (while | ||
| 6573 | (and | ||
| 6574 | (search-forward-regexp | ||
| 6575 | "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" | ||
| 6576 | (1+ here) 'limit) | ||
| 6577 | (< (point) here))) | ||
| 6578 | (and (eq (point) (1+ here)) | ||
| 6579 | (match-beginning 1) | ||
| 6580 | (goto-char (1- (match-beginning 1))))))) | ||
| 6560 | (not (bobp))))) | 6581 | (not (bobp))))) |
| 6561 | (eq (char-before) ?R) | 6582 | (eq (char-before) ?R) |
| 6562 | (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")) | 6583 | (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")) |
| @@ -6579,6 +6600,21 @@ comment at the start of cc-engine.el for more info." | |||
| 6579 | (t nil)) | 6600 | (t nil)) |
| 6580 | open-quote-pos open-paren-pos close-paren-pos close-quote-pos)))) | 6601 | open-quote-pos open-paren-pos close-paren-pos close-quote-pos)))) |
| 6581 | 6602 | ||
| 6603 | (defun c-raw-string-in-end-delim (beg end) | ||
| 6604 | ;; If the region (BEG END) intersects a possible raw string terminator, | ||
| 6605 | ;; return a cons of the position of the ) and the position of the " in the | ||
| 6606 | ;; first one found. | ||
| 6607 | (save-excursion | ||
| 6608 | (goto-char (max (- beg 17) (point-min))) | ||
| 6609 | (while | ||
| 6610 | (and | ||
| 6611 | (search-forward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"" | ||
| 6612 | (min (+ end 17) (point-max)) t) | ||
| 6613 | (<= (point) beg))) | ||
| 6614 | (unless (or (<= (point) beg) | ||
| 6615 | (>= (match-beginning 0) end)) | ||
| 6616 | (cons (match-beginning 0) (match-end 1))))) | ||
| 6617 | |||
| 6582 | (defun c-depropertize-raw-string (id open-quote open-paren bound) | 6618 | (defun c-depropertize-raw-string (id open-quote open-paren bound) |
| 6583 | ;; Point is immediately after a raw string opening delimiter. Remove any | 6619 | ;; Point is immediately after a raw string opening delimiter. Remove any |
| 6584 | ;; `syntax-table' text properties associated with the delimiter (if it's | 6620 | ;; `syntax-table' text properties associated with the delimiter (if it's |
| @@ -6587,29 +6623,55 @@ comment at the start of cc-engine.el for more info." | |||
| 6587 | ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN | 6623 | ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN |
| 6588 | ;; are the buffer positions of the delimiter's components. BOUND is the | 6624 | ;; are the buffer positions of the delimiter's components. BOUND is the |
| 6589 | ;; bound for searching for a matching closing delimiter; it is usually nil, | 6625 | ;; bound for searching for a matching closing delimiter; it is usually nil, |
| 6590 | ;; but if we're inside a macro, it's the end of the macro. | 6626 | ;; but if we're inside a macro, it's the end of the macro (i.e. just before |
| 6627 | ;; the terminating \n). | ||
| 6591 | ;; | 6628 | ;; |
| 6592 | ;; Point is moved to after the (terminated) raw string, or left after the | 6629 | ;; Point is moved to after the (terminated) raw string, or left after the |
| 6593 | ;; unmatched opening delimiter, as the case may be. The return value is of | 6630 | ;; unmatched opening delimiter, as the case may be. The return value is of |
| 6594 | ;; no significance. | 6631 | ;; no significance. |
| 6595 | (let ((open-paren-prop (c-get-char-property open-paren 'syntax-table))) | 6632 | (let ((open-paren-prop (c-get-char-property open-paren 'syntax-table)) |
| 6633 | first) | ||
| 6634 | ;; If the delimiter is "unclosed", or sombody's used " in their id, clear | ||
| 6635 | ;; the 'syntax-table property from all of them. | ||
| 6636 | (setq first (c-clear-char-property-with-value-on-char | ||
| 6637 | open-quote open-paren 'syntax-table '(1) ?\")) | ||
| 6638 | (if first (c-truncate-semi-nonlit-pos-cache first)) | ||
| 6596 | (cond | 6639 | (cond |
| 6597 | ((null open-paren-prop) | 6640 | ((null open-paren-prop) |
| 6598 | ;; A terminated raw string | 6641 | ;; Should be a terminated raw string... |
| 6599 | (when (search-forward (concat ")" id "\"") nil t) | 6642 | (when (search-forward (concat ")" id "\"") nil t) |
| 6643 | ;; Yes, it is. :-) | ||
| 6644 | ;; Clear any '(1)s from "s in the identifier. | ||
| 6645 | (setq first (c-clear-char-property-with-value-on-char | ||
| 6646 | (1+ (match-beginning 0)) (1- (match-end 0)) | ||
| 6647 | 'syntax-table '(1) ?\")) | ||
| 6648 | (if first (c-truncate-semi-nonlit-pos-cache first)) | ||
| 6649 | ;; Clear any random `syntax-table' text properties from the contents. | ||
| 6600 | (let* ((closing-paren (match-beginning 0)) | 6650 | (let* ((closing-paren (match-beginning 0)) |
| 6601 | (first-punctuation | 6651 | (first-st |
| 6602 | (save-match-data | 6652 | (and |
| 6603 | (goto-char (1+ open-paren)) | 6653 | (< (1+ open-paren) closing-paren) |
| 6604 | (and (c-search-forward-char-property 'syntax-table '(1) | 6654 | (or |
| 6605 | closing-paren) | 6655 | (and (c-get-char-property (1+ open-paren) 'syntax-table) |
| 6606 | (1- (point))))) | 6656 | (1+ open-paren)) |
| 6607 | ) | 6657 | (and |
| 6608 | (when first-punctuation | 6658 | (setq first |
| 6609 | (c-clear-char-property-with-value | 6659 | (c-next-single-property-change |
| 6610 | first-punctuation (match-beginning 0) 'syntax-table '(1)) | 6660 | (1+ open-paren) 'syntax-table nil closing-paren)) |
| 6611 | (c-truncate-semi-nonlit-pos-cache first-punctuation) | 6661 | (< first closing-paren) |
| 6612 | )))) | 6662 | first))))) |
| 6663 | (when first-st | ||
| 6664 | (c-clear-char-properties first-st (match-beginning 0) | ||
| 6665 | 'syntax-table) | ||
| 6666 | (c-truncate-semi-nonlit-pos-cache first-st)) | ||
| 6667 | (when (c-get-char-property (1- (match-end 0)) 'syntax-table) | ||
| 6668 | ;; Was previously an unterminated (ordinary) string | ||
| 6669 | (save-excursion | ||
| 6670 | (goto-char (1- (match-end 0))) | ||
| 6671 | (when (c-safe (c-forward-sexp)) ; to '(1) at EOL. | ||
| 6672 | (c-clear-char-property (1- (point)) 'syntax-table)) | ||
| 6673 | (c-clear-char-property (1- (match-end 0)) 'syntax-table) | ||
| 6674 | (c-truncate-semi-nonlit-pos-cache (1- (match-end 0)))))))) | ||
| 6613 | ((or (and (equal open-paren-prop '(15)) (null bound)) | 6675 | ((or (and (equal open-paren-prop '(15)) (null bound)) |
| 6614 | (equal open-paren-prop '(1))) | 6676 | (equal open-paren-prop '(1))) |
| 6615 | ;; An unterminated raw string either not in a macro, or in a macro with | 6677 | ;; An unterminated raw string either not in a macro, or in a macro with |
| @@ -6623,13 +6685,8 @@ comment at the start of cc-engine.el for more info." | |||
| 6623 | (c-clear-char-property open-quote 'syntax-table) | 6685 | (c-clear-char-property open-quote 'syntax-table) |
| 6624 | (c-truncate-semi-nonlit-pos-cache open-quote) | 6686 | (c-truncate-semi-nonlit-pos-cache open-quote) |
| 6625 | (c-clear-char-property open-paren 'syntax-table) | 6687 | (c-clear-char-property open-paren 'syntax-table) |
| 6626 | (let ((after-string-fence-pos | 6688 | (c-clear-char-property-with-value (1+ open-paren) bound 'syntax-table |
| 6627 | (save-excursion | 6689 | '(15)))))) |
| 6628 | (goto-char (1+ open-paren)) | ||
| 6629 | (c-search-forward-char-property 'syntax-table '(15) bound)))) | ||
| 6630 | (when after-string-fence-pos | ||
| 6631 | (c-clear-char-property (1- after-string-fence-pos) 'syntax-table))) | ||
| 6632 | )))) | ||
| 6633 | 6690 | ||
| 6634 | (defun c-depropertize-raw-strings-in-region (start finish) | 6691 | (defun c-depropertize-raw-strings-in-region (start finish) |
| 6635 | ;; Remove any `syntax-table' text properties associated with C++ raw strings | 6692 | ;; Remove any `syntax-table' text properties associated with C++ raw strings |
| @@ -6669,37 +6726,89 @@ comment at the start of cc-engine.el for more info." | |||
| 6669 | 6726 | ||
| 6670 | (defun c-before-change-check-raw-strings (beg end) | 6727 | (defun c-before-change-check-raw-strings (beg end) |
| 6671 | ;; This function clears `syntax-table' text properties from C++ raw strings | 6728 | ;; This function clears `syntax-table' text properties from C++ raw strings |
| 6672 | ;; in the region (c-new-BEG c-new-END). BEG and END are the standard | 6729 | ;; whose delimiters are about to change in the region (c-new-BEG c-new-END). |
| 6673 | ;; arguments supplied to any before-change function. | 6730 | ;; BEG and END are the standard arguments supplied to any before-change |
| 6731 | ;; function. | ||
| 6674 | ;; | 6732 | ;; |
| 6675 | ;; Point is undefined on both entry and exit, and the return value has no | 6733 | ;; Point is undefined on both entry and exit, and the return value has no |
| 6676 | ;; significance. | 6734 | ;; significance. |
| 6677 | ;; | 6735 | ;; |
| 6678 | ;; This function is called as a before-change function solely due to its | 6736 | ;; This function is called as a before-change function solely due to its |
| 6679 | ;; membership of the C++ value of `c-get-state-before-change-functions'. | 6737 | ;; membership of the C++ value of `c-get-state-before-change-functions'. |
| 6738 | (goto-char end) | ||
| 6739 | ;; We use the following to detect a R"<id>( being swallowed into a string by | ||
| 6740 | ;; the pending change. | ||
| 6741 | (setq c-old-END-literality (c-in-literal)) | ||
| 6680 | (c-save-buffer-state | 6742 | (c-save-buffer-state |
| 6681 | ((beg-rs (progn (goto-char beg) (c-raw-string-pos))) | 6743 | (;; (beg-rs (progn (goto-char beg) (c-raw-string-pos))) |
| 6682 | (beg-plus (if (null beg-rs) | 6744 | ;; (end-rs (progn (goto-char end) (c-raw-string-pos))) |
| 6683 | beg | 6745 | ; FIXME!!! |
| 6684 | (max beg | ||
| 6685 | (1+ (or (nth 4 beg-rs) (nth 2 beg-rs)))))) | ||
| 6686 | (end-rs (progn (goto-char end) (c-raw-string-pos))) ; FIXME!!! | ||
| 6687 | ; Optimize this so that we don't call | 6746 | ; Optimize this so that we don't call |
| 6688 | ; `c-raw-string-pos' twice when once | 6747 | ; `c-raw-string-pos' twice when once |
| 6689 | ; will do. (2016-06-02). | 6748 | ; will do. (2016-06-02). |
| 6690 | (end-minus (if (null end-rs) | 6749 | (term-del (c-raw-string-in-end-delim beg end)) |
| 6691 | end | 6750 | Rquote close-quote) |
| 6692 | (min end (cadr end-rs)))) | 6751 | (setq c-old-beg-rs (progn (goto-char beg) (c-raw-string-pos)) |
| 6693 | ) | 6752 | c-old-end-rs (progn (goto-char end) (c-raw-string-pos))) |
| 6694 | (when beg-rs | 6753 | (cond |
| 6695 | (setq c-new-BEG (min c-new-BEG (1- (cadr beg-rs))))) | 6754 | ;; We're not changing, or we're obliterating raw strings. |
| 6696 | (c-depropertize-raw-strings-in-region c-new-BEG beg-plus) | 6755 | ((and (null c-old-beg-rs) (null c-old-end-rs))) |
| 6697 | 6756 | ;; We're changing the putative terminating delimiter of a raw string | |
| 6698 | (when end-rs | 6757 | ;; containing BEG. |
| 6699 | (setq c-new-END (max c-new-END | 6758 | ((and c-old-beg-rs term-del |
| 6700 | (1+ (or (nth 4 end-rs) | 6759 | (or (null (nth 3 c-old-beg-rs)) |
| 6701 | (nth 2 end-rs)))))) | 6760 | (<= (car term-del) (nth 3 c-old-beg-rs)))) |
| 6702 | (c-depropertize-raw-strings-in-region end-minus c-new-END))) | 6761 | (setq Rquote (1- (cadr c-old-beg-rs)) |
| 6762 | close-quote (1+ (cdr term-del))) | ||
| 6763 | (c-depropertize-raw-strings-in-region Rquote close-quote) | ||
| 6764 | (setq c-new-BEG (min c-new-BEG Rquote) | ||
| 6765 | c-new-END (max c-new-END close-quote))) | ||
| 6766 | ;; We're breaking an escaped NL in a raw string in a macro. | ||
| 6767 | ((and c-old-end-rs | ||
| 6768 | (< beg end) | ||
| 6769 | (goto-char end) (eq (char-before) ?\\) | ||
| 6770 | (c-beginning-of-macro)) | ||
| 6771 | (let ((bom (point)) | ||
| 6772 | (eom (progn (c-end-of-macro) (point)))) | ||
| 6773 | (c-depropertize-raw-strings-in-region bom eom) | ||
| 6774 | (setq c-new-BEG (min c-new-BEG bom) | ||
| 6775 | c-new-END (max c-new-END eom)))) | ||
| 6776 | ;; We're changing only the contents of a raw string. | ||
| 6777 | ((and (equal (cdr c-old-beg-rs) (cdr c-old-end-rs)) | ||
| 6778 | (null (car c-old-beg-rs)) (null (car c-old-end-rs)))) | ||
| 6779 | ((or | ||
| 6780 | ;; We're removing (at least part of) the R" of the starting delim of a | ||
| 6781 | ;; raw string: | ||
| 6782 | (null c-old-beg-rs) | ||
| 6783 | (and (eq beg (cadr c-old-beg-rs)) | ||
| 6784 | (< beg end)) | ||
| 6785 | ;; Or we're removing the ( of the starting delim of a raw string. | ||
| 6786 | (and (eq (car c-old-beg-rs) 'open-delim) | ||
| 6787 | (or (null c-old-end-rs) | ||
| 6788 | (not (eq (car c-old-end-rs) 'open-delim)) | ||
| 6789 | (not (equal (cdr c-old-beg-rs) (cdr c-old-end-rs)))))) | ||
| 6790 | (let ((close (nth 4 (or c-old-end-rs c-old-beg-rs)))) | ||
| 6791 | (setq Rquote (1- (cadr (or c-old-end-rs c-old-beg-rs))) | ||
| 6792 | close-quote (if close (1+ close) (point-max)))) | ||
| 6793 | (c-depropertize-raw-strings-in-region Rquote close-quote) | ||
| 6794 | (setq c-new-BEG (min c-new-BEG Rquote) | ||
| 6795 | c-new-END (max c-new-END close-quote))) | ||
| 6796 | ;; We're changing only the text of the identifier of the opening | ||
| 6797 | ;; delimiter of a raw string. | ||
| 6798 | ((and (eq (car c-old-beg-rs) 'open-delim) | ||
| 6799 | (equal c-old-beg-rs c-old-end-rs)))))) | ||
| 6800 | |||
| 6801 | (defun c-propertize-raw-string-id (start end) | ||
| 6802 | ;; If the raw string identifier between buffer positions START and END | ||
| 6803 | ;; contains any double quote characters, put a punctuation syntax-table text | ||
| 6804 | ;; property on them. The return value is of no significance. | ||
| 6805 | (save-excursion | ||
| 6806 | (goto-char start) | ||
| 6807 | (while (and (skip-chars-forward "^\"" end) | ||
| 6808 | (< (point) end)) | ||
| 6809 | (c-put-char-property (point) 'syntax-table '(1)) | ||
| 6810 | (c-truncate-semi-nonlit-pos-cache (point)) | ||
| 6811 | (forward-char)))) | ||
| 6703 | 6812 | ||
| 6704 | (defun c-propertize-raw-string-opener (id open-quote open-paren bound) | 6813 | (defun c-propertize-raw-string-opener (id open-quote open-paren bound) |
| 6705 | ;; Point is immediately after a raw string opening delimiter. Apply any | 6814 | ;; Point is immediately after a raw string opening delimiter. Apply any |
| @@ -6709,117 +6818,264 @@ comment at the start of cc-engine.el for more info." | |||
| 6709 | ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN | 6818 | ;; ID, a string, is the delimiter's identifier. OPEN-QUOTE and OPEN-PAREN |
| 6710 | ;; are the buffer positions of the delimiter's components. BOUND is the | 6819 | ;; are the buffer positions of the delimiter's components. BOUND is the |
| 6711 | ;; bound for searching for a matching closing delimiter; it is usually nil, | 6820 | ;; bound for searching for a matching closing delimiter; it is usually nil, |
| 6712 | ;; but if we're inside a macro, it's the end of the macro. | 6821 | ;; but if we're inside a macro, it's the end of the macro (i.e. the position |
| 6713 | ;; | 6822 | ;; of the closing newline). |
| 6714 | ;; Point is moved to after the (terminated) raw string, or left after the | 6823 | ;; |
| 6715 | ;; unmatched opening delimiter, as the case may be. The return value is of | 6824 | ;; Point is moved to after the (terminated) raw string and t is returned, or |
| 6716 | ;; no significance. | 6825 | ;; it is left after the unmatched opening delimiter and nil is returned. |
| 6717 | (if (search-forward (concat ")" id "\"") bound t) | 6826 | (c-propertize-raw-string-id (1+ open-quote) open-paren) |
| 6718 | (let ((end-string (match-beginning 0)) | 6827 | (prog1 |
| 6719 | (after-quote (match-end 0))) | 6828 | (if (search-forward (concat ")" id "\"") bound t) |
| 6720 | (goto-char open-paren) | 6829 | (let ((end-string (match-beginning 0)) |
| 6721 | (while (progn (skip-syntax-forward "^\"" end-string) | 6830 | (after-quote (match-end 0))) |
| 6722 | (< (point) end-string)) | 6831 | (c-propertize-raw-string-id |
| 6723 | (c-put-char-property (point) 'syntax-table '(1)) ; punctuation | 6832 | (1+ (match-beginning 0)) (1- (match-end 0))) |
| 6724 | (c-truncate-semi-nonlit-pos-cache (point)) | 6833 | (goto-char open-paren) |
| 6725 | (forward-char)) | 6834 | (while (progn (skip-syntax-forward "^\"" end-string) |
| 6726 | (goto-char after-quote)) | 6835 | (< (point) end-string)) |
| 6727 | (c-put-char-property open-quote 'syntax-table '(1)) ; punctuation | 6836 | (c-put-char-property (point) 'syntax-table '(1)) ; punctuation |
| 6728 | (c-truncate-semi-nonlit-pos-cache open-quote) | 6837 | (c-truncate-semi-nonlit-pos-cache (point)) |
| 6729 | (c-put-char-property open-paren 'syntax-table '(15)) ; generic string | 6838 | (forward-char)) |
| 6730 | (when bound | 6839 | (goto-char after-quote) |
| 6731 | ;; In a CPP construct, we try to apply a generic-string `syntax-table' | 6840 | t) |
| 6732 | ;; text property to the last possible character in the string, so that | 6841 | (c-put-char-property open-quote 'syntax-table '(1)) ; punctuation |
| 6733 | ;; only characters within the macro get "stringed out". | 6842 | (c-truncate-semi-nonlit-pos-cache open-quote) |
| 6734 | (goto-char bound) | 6843 | (c-put-char-property open-paren 'syntax-table '(15)) ; generic string |
| 6735 | (if (save-restriction | 6844 | (when bound |
| 6736 | (narrow-to-region (1+ open-paren) (point-max)) | 6845 | ;; In a CPP construct, we try to apply a generic-string |
| 6737 | (re-search-backward | 6846 | ;; `syntax-table' text property to the last possible character in |
| 6738 | (eval-when-compile | 6847 | ;; the string, so that only characters within the macro get |
| 6739 | ;; This regular expression matches either an escape pair (which | 6848 | ;; "stringed out". |
| 6740 | ;; isn't an escaped NL) (submatch 5) or a non-escaped character | 6849 | (goto-char bound) |
| 6741 | ;; (which isn't itself a backslash) (submatch 10). The long | 6850 | (if (save-restriction |
| 6742 | ;; preambles to these (respectively submatches 2-4 and 6-9) | 6851 | (narrow-to-region (1+ open-paren) (point-max)) |
| 6743 | ;; ensure that we have the correct parity for sequences of | 6852 | (re-search-backward |
| 6744 | ;; backslashes, etc.. | 6853 | (eval-when-compile |
| 6745 | (concat "\\(" ; 1 | 6854 | ;; This regular expression matches either an escape pair |
| 6746 | "\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)*" ; 2-4 | 6855 | ;; (which isn't an escaped NL) (submatch 5) or a |
| 6747 | "\\(\\\\.\\)" ; 5 | 6856 | ;; non-escaped character (which isn't itself a backslash) |
| 6748 | "\\|" | 6857 | ;; (submatch 10). The long preambles to these |
| 6749 | "\\(\\`\\|[^\\]\\|\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)+\\)" ; 6-9 | 6858 | ;; (respectively submatches 2-4 and 6-9) ensure that we |
| 6750 | "\\([^\\]\\)" ; 10 | 6859 | ;; have the correct parity for sequences of backslashes, |
| 6751 | "\\)" | 6860 | ;; etc.. |
| 6752 | "\\(\\\\\n\\)*\\=")) ; 11 | 6861 | (concat "\\(" ; 1 |
| 6753 | (1+ open-paren) t)) | 6862 | "\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)*" ; 2-4 |
| 6754 | (if (match-beginning 10) | 6863 | "\\(\\\\.\\)" ; 5 |
| 6755 | (progn | 6864 | "\\|" |
| 6756 | (c-put-char-property (match-beginning 10) 'syntax-table '(15)) | 6865 | "\\(\\`\\|[^\\]\\|\\(\\`[^\\]?\\|[^\\][^\\]\\)\\(\\\\\\(.\\|\n\\)\\)+\\)" ; 6-9 |
| 6757 | (c-truncate-semi-nonlit-pos-cache (match-beginning 10))) | 6866 | "\\([^\\]\\)" ; 10 |
| 6758 | (c-put-char-property (match-beginning 5) 'syntax-table '(1)) | 6867 | "\\)" |
| 6759 | (c-put-char-property (1+ (match-beginning 5)) 'syntax-table '(15)) | 6868 | "\\(\\\\\n\\)*\\=")) ; 11 |
| 6760 | (c-truncate-semi-nonlit-pos-cache (1+ (match-beginning 5)))) | 6869 | (1+ open-paren) t)) |
| 6761 | (c-put-char-property open-paren 'syntax-table '(1))) | 6870 | (if (match-beginning 10) |
| 6762 | (goto-char bound)))) | 6871 | (progn |
| 6763 | 6872 | (c-put-char-property (match-beginning 10) 'syntax-table '(15)) | |
| 6764 | (defun c-after-change-re-mark-raw-strings (_beg _end _old-len) | 6873 | (c-truncate-semi-nonlit-pos-cache (match-beginning 10))) |
| 6765 | ;; This function applies `syntax-table' text properties to C++ raw strings | 6874 | (c-put-char-property (match-beginning 5) 'syntax-table '(1)) |
| 6766 | ;; beginning in the region (c-new-BEG c-new-END). BEG, END, and OLD-LEN are | 6875 | (c-put-char-property (1+ (match-beginning 5)) 'syntax-table '(15)) |
| 6767 | ;; the standard arguments supplied to any after-change function. | 6876 | (c-truncate-semi-nonlit-pos-cache (1+ (match-beginning 5)))) |
| 6877 | ;; (c-put-char-property open-paren 'syntax-table '(1)) | ||
| 6878 | ) | ||
| 6879 | (goto-char bound)) | ||
| 6880 | nil) | ||
| 6881 | ;; Ensure the opening delimiter will get refontified. | ||
| 6882 | (c-font-lock-flush (1- open-quote) (1+ open-paren)))) | ||
| 6883 | |||
| 6884 | (defun c-after-change-unmark-raw-strings (beg end _old-len) | ||
| 6885 | ;; This function removes `syntax-table' text properties from any raw strings | ||
| 6886 | ;; which have been affected by the current change. These are those which | ||
| 6887 | ;; have been "stringed out" and from newly formed raw strings, or any | ||
| 6888 | ;; existing raw string which the new text terminates. BEG, END, and | ||
| 6889 | ;; _OLD-LEN are the standard arguments supplied to any | ||
| 6890 | ;; after-change-function. | ||
| 6768 | ;; | 6891 | ;; |
| 6769 | ;; Point is undefined on both entry and exit, and the return value has no | 6892 | ;; Point is undefined on both entry and exit, and the return value has no |
| 6770 | ;; significance. | 6893 | ;; significance. |
| 6771 | ;; | 6894 | ;; |
| 6772 | ;; This function is called as an after-change function solely due to its | 6895 | ;; This functions is called as an after-change function by virtue of its |
| 6773 | ;; membership of the C++ value of `c-before-font-lock-functions'. | 6896 | ;; membership of the C++ value of `c-before-font-lock-functions'. |
| 6774 | (c-save-buffer-state () | 6897 | ;; (when (< beg end) |
| 6775 | ;; If the region (c-new-BEG c-new-END) has expanded, remove | 6898 | (c-save-buffer-state (found eoll state id found-beg found-end) |
| 6776 | ;; `syntax-table' text-properties from the new piece(s). | 6899 | ;; Has an inserted " swallowed up a R"(, turning it into "...R"(? |
| 6777 | (when (< c-new-BEG c-old-BEG) | 6900 | (goto-char end) |
| 6778 | (let ((beg-rs (progn (goto-char c-old-BEG) (c-raw-string-pos)))) | 6901 | (setq eoll (c-point 'eoll)) |
| 6779 | (c-depropertize-raw-strings-in-region | 6902 | (when (and (null c-old-END-literality) |
| 6780 | c-new-BEG | 6903 | (search-forward-regexp "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" |
| 6781 | (if beg-rs | 6904 | eoll t)) |
| 6782 | (1+ (or (nth 4 beg-rs) (nth 2 beg-rs))) | 6905 | (setq state (c-state-semi-pp-to-literal end)) |
| 6783 | c-old-BEG)))) | 6906 | (when (eq (cadr state) 'string) |
| 6784 | (when (> c-new-END c-old-END) | 6907 | (unwind-protect |
| 6785 | (let ((end-rs (progn (goto-char c-old-END) (c-raw-string-pos)))) | 6908 | ;; Temporarily insert a closing string delimiter.... |
| 6786 | (c-depropertize-raw-strings-in-region | 6909 | (progn |
| 6787 | (if end-rs | 6910 | (goto-char end) |
| 6788 | (cadr end-rs) | 6911 | (cond |
| 6789 | c-old-END) | 6912 | ((c-characterp (nth 3 (car state))) |
| 6790 | c-new-END))) | 6913 | (insert (nth 3 (car state)))) |
| 6914 | ((eq (nth 3 (car state)) t) | ||
| 6915 | (insert ?\") | ||
| 6916 | (c-put-char-property end 'syntax-table '(15)))) | ||
| 6917 | (c-truncate-semi-nonlit-pos-cache end) | ||
| 6918 | ;; ....ensure c-new-END extends right to the end of the about | ||
| 6919 | ;; to be un-stringed raw string.... | ||
| 6920 | (save-excursion | ||
| 6921 | (goto-char (match-beginning 1)) | ||
| 6922 | (let ((end-bs (c-raw-string-pos))) | ||
| 6923 | (setq c-new-END | ||
| 6924 | (max c-new-END | ||
| 6925 | (if (nth 4 end-bs) | ||
| 6926 | (1+ (nth 4 end-bs)) | ||
| 6927 | eoll))))) | ||
| 6928 | |||
| 6929 | ;; ...and clear `syntax-table' text propertes from the | ||
| 6930 | ;; following raw strings. | ||
| 6931 | (c-depropertize-raw-strings-in-region (point) (1+ eoll))) | ||
| 6932 | ;; Remove the temporary string delimiter. | ||
| 6933 | (goto-char end) | ||
| 6934 | (delete-char 1)))) | ||
| 6935 | |||
| 6936 | ;; Have we just created a new starting id? | ||
| 6937 | (goto-char (max (- beg 18) (point-min))) | ||
| 6938 | (while | ||
| 6939 | (and | ||
| 6940 | (setq found | ||
| 6941 | (search-forward-regexp "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" | ||
| 6942 | c-new-END 'bound)) | ||
| 6943 | (<= (match-end 0) beg))) | ||
| 6944 | (when (and found (<= (match-beginning 0) end)) | ||
| 6945 | (setq c-new-BEG (min c-new-BEG (match-beginning 0))) | ||
| 6946 | (c-depropertize-raw-strings-in-region c-new-BEG c-new-END)) | ||
| 6947 | |||
| 6948 | ;; Have we invalidated an opening delimiter by typing into it? | ||
| 6949 | (when (and c-old-beg-rs | ||
| 6950 | (eq (car c-old-beg-rs) 'open-delim) | ||
| 6951 | (equal (c-get-char-property (cadr c-old-beg-rs) | ||
| 6952 | 'syntax-table) | ||
| 6953 | '(1))) | ||
| 6954 | (goto-char (1- (cadr c-old-beg-rs))) | ||
| 6955 | (unless (looking-at "R\"[^ ()\\\n\r\t]\\{0,16\\}(") | ||
| 6956 | (c-clear-char-property (1+ (point)) 'syntax-table) | ||
| 6957 | (c-truncate-semi-nonlit-pos-cache (1+ (point))) | ||
| 6958 | (if (c-search-forward-char-property 'syntax-table '(15) | ||
| 6959 | (c-point 'eol)) | ||
| 6960 | (c-clear-char-property (1- (point)) 'syntax-table)))) | ||
| 6961 | |||
| 6962 | ;; Have we terminated an existing raw string by inserting or removing | ||
| 6963 | ;; text? | ||
| 6964 | (when (eq c-old-END-literality 'string) | ||
| 6965 | (setq state (c-state-semi-pp-to-literal beg)) | ||
| 6966 | (cond | ||
| 6967 | ;; Possibly terminating a(n un)terminated raw string. | ||
| 6968 | ((eq (nth 3 (car state)) t) | ||
| 6969 | (goto-char (nth 8 (car state))) | ||
| 6970 | (when | ||
| 6971 | (and (eq (char-after) ?\() | ||
| 6972 | (search-backward-regexp | ||
| 6973 | "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)\\=" (- (point) 18) t)) | ||
| 6974 | (setq id (match-string-no-properties 1) | ||
| 6975 | found-beg (match-beginning 0) | ||
| 6976 | found-end (1+ (match-end 0))))) | ||
| 6977 | ;; Possibly terminating an already terminated raw string. | ||
| 6978 | ((eq (nth 3 (car state)) ?\") | ||
| 6979 | (goto-char (nth 8 (car state))) | ||
| 6980 | (when | ||
| 6981 | (and (eq (char-before) ?R) | ||
| 6982 | (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")) | ||
| 6983 | (setq id (match-string-no-properties 1) | ||
| 6984 | found-beg (1- (point)) | ||
| 6985 | found-end (match-end 0))))) | ||
| 6986 | (when id | ||
| 6987 | (goto-char (max (- beg 18) (point-min))) | ||
| 6988 | (when (search-forward (concat ")" id "\"") (+ end 1 (length id)) t) | ||
| 6989 | ;; Has an earlier close delimiter just been inserted into an | ||
| 6990 | ;; already terminated raw string? | ||
| 6991 | (if (and (eq (nth 3 (car state)) ?\") | ||
| 6992 | (search-forward (concat ")" id "\"") nil t)) | ||
| 6993 | (setq found-end (point))) | ||
| 6994 | (setq c-new-BEG (min c-new-BEG found-beg) | ||
| 6995 | c-new-END (max c-new-END found-end)) | ||
| 6996 | (c-clear-char-properties found-beg found-end 'syntax-table) | ||
| 6997 | (c-truncate-semi-nonlit-pos-cache found-beg)))) | ||
| 6998 | |||
| 6999 | ;; Are there any raw strings in a newly created macro? | ||
| 7000 | (when (< beg end) | ||
| 7001 | (goto-char beg) | ||
| 7002 | (setq found-beg (point)) | ||
| 7003 | (when (search-forward-regexp c-anchored-cpp-prefix end t) | ||
| 7004 | (c-end-of-macro) | ||
| 7005 | (c-depropertize-raw-strings-in-region found-beg (point)))))) | ||
| 6791 | 7006 | ||
| 6792 | (goto-char c-new-BEG) | 7007 | (defun c-maybe-re-mark-raw-string () |
| 6793 | (while (and (< (point) c-new-END) | 7008 | ;; When this function is called, point is immediately after a ". If this " |
| 6794 | (re-search-forward | 7009 | ;; is the characteristic " of of a raw string delimiter, apply the pertinent |
| 6795 | (concat "\\(" ; 1 | 7010 | ;; `syntax-table' text properties to the entire raw string (when properly |
| 6796 | c-anchored-cpp-prefix ; 2 | 7011 | ;; terminated) or just the delimiter (otherwise). |
| 6797 | "\\)\\|\\(" ; 3 | 7012 | ;; |
| 6798 | "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" ; 4 | 7013 | ;; If the " is in any way part of a raw string, return non-nil. Otherwise |
| 6799 | "\\)") | 7014 | ;; return nil. |
| 6800 | c-new-END t)) | 7015 | (let ((here (point)) |
| 6801 | (when (save-excursion | 7016 | in-macro macro-end id Rquote found) |
| 6802 | (goto-char (match-beginning 0)) (not (c-in-literal))) | 7017 | (cond |
| 6803 | (if (match-beginning 4) ; the id | 7018 | ((and |
| 6804 | ;; We've found a raw string. | 7019 | (eq (char-before (1- (point))) ?R) |
| 7020 | (looking-at "\\([^ ()\\\n\r\t]\\{0,16\\}\\)(")) | ||
| 7021 | (save-excursion | ||
| 7022 | (setq in-macro (c-beginning-of-macro)) | ||
| 7023 | (setq macro-end (when in-macro | ||
| 7024 | (c-end-of-macro) | ||
| 7025 | (point) ;; (min (1+ (point)) (point-max)) | ||
| 7026 | ))) | ||
| 7027 | (if (not | ||
| 7028 | (c-propertize-raw-string-opener | ||
| 7029 | (match-string-no-properties 1) ; id | ||
| 7030 | (1- (point)) ; open quote | ||
| 7031 | (match-end 1) ; open paren | ||
| 7032 | macro-end)) ; bound (end of macro) or nil. | ||
| 7033 | (goto-char (or macro-end (point-max)))) | ||
| 7034 | t) | ||
| 7035 | ((save-excursion | ||
| 7036 | (and | ||
| 7037 | (search-backward-regexp ")\\([^ ()\\\n\r\t]\\{0,16\\}\\)\"\\=" nil t) | ||
| 7038 | (setq id (match-string-no-properties 1)) | ||
| 7039 | (let* ((quoted-id (regexp-quote id)) | ||
| 7040 | (quoted-id-depth (regexp-opt-depth quoted-id))) | ||
| 7041 | (while | ||
| 7042 | (and | ||
| 7043 | ;; Search back for an opening delimiter with identifier `id'. | ||
| 7044 | ;; A closing delimiter with `id' "blocks" our search. | ||
| 7045 | (search-backward-regexp ; This could be slow. | ||
| 7046 | (concat "\\(R\"" quoted-id "(\\)" | ||
| 7047 | "\\|" | ||
| 7048 | "\\()" quoted-id "\"\\)") | ||
| 7049 | nil t) | ||
| 7050 | (setq found t) | ||
| 7051 | (if (eq (c-in-literal) 'string) | ||
| 7052 | (match-beginning 1) | ||
| 7053 | (match-beginning (+ 2 quoted-id-depth))))) | ||
| 7054 | (and found | ||
| 7055 | (null (c-in-literal)) | ||
| 7056 | (match-beginning 1))) | ||
| 7057 | (setq Rquote (point)))) | ||
| 7058 | (save-excursion | ||
| 7059 | (goto-char Rquote) | ||
| 7060 | (setq in-macro (c-beginning-of-macro)) | ||
| 7061 | (setq macro-end (when in-macro | ||
| 7062 | (c-end-of-macro) | ||
| 7063 | (point)))) | ||
| 7064 | (if (or (not in-macro) | ||
| 7065 | (<= here macro-end)) | ||
| 7066 | (progn | ||
| 6805 | (c-propertize-raw-string-opener | 7067 | (c-propertize-raw-string-opener |
| 6806 | (match-string-no-properties 4) ; id | 7068 | id (1+ (point)) (match-end 1) macro-end) |
| 6807 | (1+ (match-beginning 3)) ; open quote | 7069 | (goto-char here) |
| 6808 | (match-end 4) ; open paren | 7070 | t) |
| 6809 | nil) ; bound | 7071 | (goto-char here) |
| 6810 | ;; We've found a CPP construct. Search for raw strings within it. | 7072 | nil)) |
| 6811 | (goto-char (match-beginning 2)) ; the "#" | 7073 | |
| 6812 | (c-end-of-macro) | 7074 | (t |
| 6813 | (let ((eom (point))) | 7075 | ;; If the " is in another part of a raw string (whether as part of the |
| 6814 | (goto-char (match-end 2)) ; after the "#". | 7076 | ;; identifier, or in the string itself) the `syntax-table' text |
| 6815 | (while (and (< (point) eom) | 7077 | ;; properties on the raw string will be current. So, we can use... |
| 6816 | (c-syntactic-re-search-forward | 7078 | (c-raw-string-pos))))) |
| 6817 | "R\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" eom t)) | ||
| 6818 | (c-propertize-raw-string-opener | ||
| 6819 | (match-string-no-properties 1) ; id | ||
| 6820 | (1+ (match-beginning 0)) ; open quote | ||
| 6821 | (match-end 1) ; open paren | ||
| 6822 | eom)))))))) ; bound | ||
| 6823 | 7079 | ||
| 6824 | 7080 | ||
| 6825 | ;; Handling of small scale constructs like types and names. | 7081 | ;; Handling of small scale constructs like types and names. |
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 0b41eff1577..e7a3748af43 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el | |||
| @@ -1674,25 +1674,36 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1674 | (goto-char string-start) | 1674 | (goto-char string-start) |
| 1675 | (and (eq (char-before) ?R) | 1675 | (and (eq (char-before) ?R) |
| 1676 | (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(") | 1676 | (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(") |
| 1677 | (match-string-no-properties 1)))))) | 1677 | (match-string-no-properties 1))))) |
| 1678 | (content-start (and raw-id (point)))) | ||
| 1679 | ;; We go round the next loop twice per raw string, once for each "end". | ||
| 1678 | (while (< (point) limit) | 1680 | (while (< (point) limit) |
| 1679 | (if raw-id | 1681 | (if raw-id |
| 1682 | ;; Search for the raw string end delimiter | ||
| 1680 | (progn | 1683 | (progn |
| 1681 | (if (search-forward-regexp (concat ")\\(" (regexp-quote raw-id) "\\)\"") | 1684 | (when (search-forward-regexp (concat ")\\(" (regexp-quote raw-id) "\\)\"") |
| 1682 | limit 'limit) | 1685 | limit 'limit) |
| 1683 | (c-put-font-lock-face (match-beginning 1) (point) 'default)) | 1686 | (c-put-font-lock-face content-start (match-beginning 1) |
| 1687 | 'font-lock-string-face) | ||
| 1688 | (c-remove-font-lock-face (match-beginning 1) (point))) | ||
| 1684 | (setq raw-id nil)) | 1689 | (setq raw-id nil)) |
| 1685 | 1690 | ;; Search for the start of a raw string. | |
| 1686 | (when (search-forward-regexp | 1691 | (when (search-forward-regexp |
| 1687 | "R\\(\"\\)\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" limit 'limit) | 1692 | "R\\(\"\\)\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" limit 'limit) |
| 1688 | (when | 1693 | (when |
| 1689 | (or (and (eobp) | 1694 | ;; Make sure we're not in a comment or string. |
| 1690 | (eq (c-get-char-property (1- (point)) 'face) | 1695 | (and |
| 1691 | 'font-lock-warning-face)) | 1696 | (not (memq (c-get-char-property (match-beginning 0) 'face) |
| 1692 | (eq (c-get-char-property (point) 'face) 'font-lock-string-face) | 1697 | '(font-lock-comment-face font-lock-comment-delimiter-face |
| 1693 | (and (equal (c-get-char-property (match-end 2) 'syntax-table) '(1)) | 1698 | font-lock-string-face))) |
| 1694 | (equal (c-get-char-property (match-beginning 1) 'syntax-table) | 1699 | (or (and (eobp) |
| 1695 | '(1)))) | 1700 | (eq (c-get-char-property (1- (point)) 'face) |
| 1701 | 'font-lock-warning-face)) | ||
| 1702 | (not (eq (c-get-char-property (point) 'face) 'font-lock-comment-face)) | ||
| 1703 | ;; (eq (c-get-char-property (point) 'face) 'font-lock-string-face) | ||
| 1704 | (and (equal (c-get-char-property (match-end 2) 'syntax-table) '(1)) | ||
| 1705 | (equal (c-get-char-property (match-beginning 1) 'syntax-table) | ||
| 1706 | '(1))))) | ||
| 1696 | (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table))) | 1707 | (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table))) |
| 1697 | (if paren-prop | 1708 | (if paren-prop |
| 1698 | (progn | 1709 | (progn |
| @@ -1703,8 +1714,9 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1703 | (equal paren-prop '(15)) | 1714 | (equal paren-prop '(15)) |
| 1704 | (not (c-search-forward-char-property 'syntax-table '(15) limit))) | 1715 | (not (c-search-forward-char-property 'syntax-table '(15) limit))) |
| 1705 | (goto-char limit))) | 1716 | (goto-char limit))) |
| 1706 | (c-put-font-lock-face (match-beginning 1) (match-end 2) 'default) | 1717 | (c-remove-font-lock-face (match-beginning 0) (match-end 2)) |
| 1707 | (setq raw-id (match-string-no-properties 2))))))))) | 1718 | (setq raw-id (match-string-no-properties 2)) |
| 1719 | (setq content-start (match-end 0))))))))) | ||
| 1708 | nil) | 1720 | nil) |
| 1709 | 1721 | ||
| 1710 | (defun c-font-lock-c++-lambda-captures (limit) | 1722 | (defun c-font-lock-c++-lambda-captures (limit) |
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 7cc8029e0a3..22b7b602f1e 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el | |||
| @@ -497,25 +497,25 @@ parameters \(point-min) and \(point-max).") | |||
| 497 | ;; For documentation see the following c-lang-defvar of the same name. | 497 | ;; For documentation see the following c-lang-defvar of the same name. |
| 498 | ;; The value here may be a list of functions or a single function. | 498 | ;; The value here may be a list of functions or a single function. |
| 499 | t '(c-depropertize-new-text | 499 | t '(c-depropertize-new-text |
| 500 | c-after-change-re-mark-unbalanced-strings | 500 | c-after-change-mark-abnormal-strings |
| 501 | c-change-expand-fl-region) | 501 | c-change-expand-fl-region) |
| 502 | (c objc) '(c-depropertize-new-text | 502 | (c objc) '(c-depropertize-new-text |
| 503 | c-parse-quotes-after-change | 503 | c-parse-quotes-after-change |
| 504 | c-after-change-re-mark-unbalanced-strings | 504 | c-after-change-mark-abnormal-strings |
| 505 | c-extend-font-lock-region-for-macros | 505 | c-extend-font-lock-region-for-macros |
| 506 | c-neutralize-syntax-in-CPP | 506 | c-neutralize-syntax-in-CPP |
| 507 | c-change-expand-fl-region) | 507 | c-change-expand-fl-region) |
| 508 | c++ '(c-depropertize-new-text | 508 | c++ '(c-depropertize-new-text |
| 509 | c-after-change-unmark-raw-strings | ||
| 509 | c-parse-quotes-after-change | 510 | c-parse-quotes-after-change |
| 510 | c-after-change-re-mark-unbalanced-strings | 511 | c-after-change-mark-abnormal-strings |
| 511 | c-extend-font-lock-region-for-macros | 512 | c-extend-font-lock-region-for-macros |
| 512 | c-after-change-re-mark-raw-strings | ||
| 513 | c-neutralize-syntax-in-CPP | 513 | c-neutralize-syntax-in-CPP |
| 514 | c-restore-<>-properties | 514 | c-restore-<>-properties |
| 515 | c-change-expand-fl-region) | 515 | c-change-expand-fl-region) |
| 516 | java '(c-depropertize-new-text | 516 | java '(c-depropertize-new-text |
| 517 | c-parse-quotes-after-change | 517 | c-parse-quotes-after-change |
| 518 | c-after-change-re-mark-unbalanced-strings | 518 | c-after-change-mark-abnormal-strings |
| 519 | c-restore-<>-properties | 519 | c-restore-<>-properties |
| 520 | c-change-expand-fl-region) | 520 | c-change-expand-fl-region) |
| 521 | awk '(c-depropertize-new-text | 521 | awk '(c-depropertize-new-text |
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 8343978fc38..c1fb6aa0915 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -678,14 +678,12 @@ that requires a literal mode spec at compile time." | |||
| 678 | (make-variable-buffer-local 'c-new-BEG) | 678 | (make-variable-buffer-local 'c-new-BEG) |
| 679 | (defvar c-new-END 0) | 679 | (defvar c-new-END 0) |
| 680 | (make-variable-buffer-local 'c-new-END) | 680 | (make-variable-buffer-local 'c-new-END) |
| 681 | ;; The following two variables record the values of `c-new-BEG' and | 681 | |
| 682 | ;; `c-new-END' just after `c-new-END' has been adjusted for the length of text | 682 | ;; Buffer local variable which notes the value of calling `c-in-literal' just |
| 683 | ;; inserted or removed. They may be read by any after-change function (but | 683 | ;; before a change. It is one of 'string, 'c, 'c++ (for the two sorts of |
| 684 | ;; should not be altered by one). | 684 | ;; comments), or nil. |
| 685 | (defvar c-old-BEG 0) | 685 | (defvar c-old-END-literality nil) |
| 686 | (make-variable-buffer-local 'c-old-BEG) | 686 | (make-variable-buffer-local 'c-old-END-literality) |
| 687 | (defvar c-old-END 0) | ||
| 688 | (make-variable-buffer-local 'c-old-END) | ||
| 689 | 687 | ||
| 690 | (defun c-common-init (&optional mode) | 688 | (defun c-common-init (&optional mode) |
| 691 | "Common initialization for all CC Mode modes. | 689 | "Common initialization for all CC Mode modes. |
| @@ -900,7 +898,8 @@ Note that the style variables are always made local to the buffer." | |||
| 900 | 898 | ||
| 901 | (defun c-depropertize-CPP (beg end) | 899 | (defun c-depropertize-CPP (beg end) |
| 902 | ;; Remove the punctuation syntax-table text property from the CPP parts of | 900 | ;; Remove the punctuation syntax-table text property from the CPP parts of |
| 903 | ;; (c-new-BEG c-new-END). | 901 | ;; (c-new-BEG c-new-END), and remove all syntax-table properties from any |
| 902 | ;; raw strings within these CPP parts. | ||
| 904 | ;; | 903 | ;; |
| 905 | ;; This function is in the C/C++/ObjC values of | 904 | ;; This function is in the C/C++/ObjC values of |
| 906 | ;; `c-get-state-before-change-functions' and is called exclusively as a | 905 | ;; `c-get-state-before-change-functions' and is called exclusively as a |
| @@ -912,6 +911,7 @@ Note that the style variables are always made local to the buffer." | |||
| 912 | (goto-char (match-beginning 1)) | 911 | (goto-char (match-beginning 1)) |
| 913 | (setq m-beg (point)) | 912 | (setq m-beg (point)) |
| 914 | (c-end-of-macro) | 913 | (c-end-of-macro) |
| 914 | (save-excursion (c-depropertize-raw-strings-in-region m-beg (point))) | ||
| 915 | (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1))) | 915 | (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1))) |
| 916 | 916 | ||
| 917 | (while (and (< (point) end) | 917 | (while (and (< (point) end) |
| @@ -920,14 +920,16 @@ Note that the style variables are always made local to the buffer." | |||
| 920 | (goto-char (match-beginning 1)) | 920 | (goto-char (match-beginning 1)) |
| 921 | (setq m-beg (point)) | 921 | (setq m-beg (point)) |
| 922 | (c-end-of-macro)) | 922 | (c-end-of-macro)) |
| 923 | (if (and ss-found (> (point) end)) | 923 | (when (and ss-found (> (point) end)) |
| 924 | (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1))) | 924 | (save-excursion (c-depropertize-raw-strings-in-region m-beg (point))) |
| 925 | (c-clear-char-property-with-value m-beg (point) 'syntax-table '(1))) | ||
| 925 | 926 | ||
| 926 | (while (and (< (point) c-new-END) | 927 | (while (and (< (point) c-new-END) |
| 927 | (search-forward-regexp c-anchored-cpp-prefix c-new-END 'bound)) | 928 | (search-forward-regexp c-anchored-cpp-prefix c-new-END 'bound)) |
| 928 | (goto-char (match-beginning 1)) | 929 | (goto-char (match-beginning 1)) |
| 929 | (setq m-beg (point)) | 930 | (setq m-beg (point)) |
| 930 | (c-end-of-macro) | 931 | (c-end-of-macro) |
| 932 | (save-excursion (c-depropertize-raw-strings-in-region m-beg (point))) | ||
| 931 | (c-clear-char-property-with-value | 933 | (c-clear-char-property-with-value |
| 932 | m-beg (point) 'syntax-table '(1))))) | 934 | m-beg (point) 'syntax-table '(1))))) |
| 933 | 935 | ||
| @@ -1213,6 +1215,7 @@ Note that the style variables are always made local to the buffer." | |||
| 1213 | "\"\\|\\s|" (point-max) t t) | 1215 | "\"\\|\\s|" (point-max) t t) |
| 1214 | (progn | 1216 | (progn |
| 1215 | (c-clear-char-property (1- (point)) 'syntax-table) | 1217 | (c-clear-char-property (1- (point)) 'syntax-table) |
| 1218 | (c-truncate-semi-nonlit-pos-cache (1- (point))) | ||
| 1216 | (not (eq (char-before) ?\"))))) | 1219 | (not (eq (char-before) ?\"))))) |
| 1217 | (eq (char-before) ?\")) | 1220 | (eq (char-before) ?\")) |
| 1218 | (progn | 1221 | (progn |
| @@ -1247,27 +1250,38 @@ Note that the style variables are always made local to the buffer." | |||
| 1247 | (forward-char) | 1250 | (forward-char) |
| 1248 | (backward-sexp) | 1251 | (backward-sexp) |
| 1249 | (c-clear-char-property eoll-1 'syntax-table) | 1252 | (c-clear-char-property eoll-1 'syntax-table) |
| 1253 | (c-truncate-semi-nonlit-pos-cache eoll-1) | ||
| 1250 | (c-clear-char-property (point) 'syntax-table)) | 1254 | (c-clear-char-property (point) 'syntax-table)) |
| 1251 | ;; Opening " at EOB. | 1255 | ;; Opening " at EOB. |
| 1252 | (c-clear-char-property (1- (point)) 'syntax-table)) | 1256 | (c-clear-char-property (1- (point)) 'syntax-table)) |
| 1253 | (if (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) | 1257 | (when (and (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) |
| 1254 | ;; Opening " on last line of text (without EOL). | 1258 | (eq (char-after) ?\")) ; Ignore an unterminated raw string's (. |
| 1255 | (c-clear-char-property (point) 'syntax-table)))) | 1259 | ;; Opening " on last line of text (without EOL). |
| 1260 | (c-clear-char-property (point) 'syntax-table) | ||
| 1261 | (c-truncate-semi-nonlit-pos-cache (point))))) | ||
| 1256 | 1262 | ||
| 1257 | (t (goto-char end) ; point-max | 1263 | (t (goto-char end) ; point-max |
| 1258 | (if (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) | 1264 | (when |
| 1259 | (c-clear-char-property (point) 'syntax-table)))) | 1265 | (and |
| 1266 | (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) | ||
| 1267 | (eq (char-after) ?\")) | ||
| 1268 | (c-clear-char-property (point) 'syntax-table) | ||
| 1269 | (c-truncate-semi-nonlit-pos-cache (point))))) | ||
| 1260 | 1270 | ||
| 1261 | (unless (and c-multiline-string-start-char | 1271 | (unless (and c-multiline-string-start-char |
| 1262 | (not (c-characterp c-multiline-string-start-char))) | 1272 | (not (c-characterp c-multiline-string-start-char))) |
| 1263 | (when (eq end-literal-type 'string) | 1273 | (when (and (eq end-literal-type 'string) |
| 1264 | (c-clear-char-property (1- (cdr end-limits)) 'syntax-table)) | 1274 | (not (eq (char-before (cdr end-limits)) ?\())) |
| 1275 | (c-clear-char-property (1- (cdr end-limits)) 'syntax-table) | ||
| 1276 | (c-truncate-semi-nonlit-pos-cache (1- (cdr end-limits)))) | ||
| 1265 | 1277 | ||
| 1266 | (when (eq beg-literal-type 'string) | 1278 | (when (and (eq beg-literal-type 'string) |
| 1279 | (eq (char-after (car beg-limits)) ?\")) | ||
| 1267 | (setq c-new-BEG (min c-new-BEG (car beg-limits))) | 1280 | (setq c-new-BEG (min c-new-BEG (car beg-limits))) |
| 1268 | (c-clear-char-property (car beg-limits) 'syntax-table))))) | 1281 | (c-clear-char-property (car beg-limits) 'syntax-table) |
| 1282 | (c-truncate-semi-nonlit-pos-cache (car beg-limits)))))) | ||
| 1269 | 1283 | ||
| 1270 | (defun c-after-change-re-mark-unbalanced-strings (beg end _old-len) | 1284 | (defun c-after-change-mark-abnormal-strings (beg end _old-len) |
| 1271 | ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with | 1285 | ;; Mark any unbalanced strings in the region (c-new-BEG c-new-END) with |
| 1272 | ;; string fence syntax-table text properties. | 1286 | ;; string fence syntax-table text properties. |
| 1273 | ;; | 1287 | ;; |
| @@ -1318,7 +1332,8 @@ Note that the style variables are always made local to the buffer." | |||
| 1318 | (min (1+ (point)) (point-max))))) | 1332 | (min (1+ (point)) (point-max))))) |
| 1319 | ((and (null beg-literal-type) | 1333 | ((and (null beg-literal-type) |
| 1320 | (goto-char beg) | 1334 | (goto-char beg) |
| 1321 | (eq (char-before) c-multiline-string-start-char) | 1335 | (and (not (bobp)) |
| 1336 | (eq (char-before) c-multiline-string-start-char)) | ||
| 1322 | (memq (char-after) c-string-delims)) | 1337 | (memq (char-after) c-string-delims)) |
| 1323 | (cons (point) | 1338 | (cons (point) |
| 1324 | (progn | 1339 | (progn |
| @@ -1343,22 +1358,24 @@ Note that the style variables are always made local to the buffer." | |||
| 1343 | (while (progn | 1358 | (while (progn |
| 1344 | (setq s (parse-partial-sexp (point) c-new-END nil | 1359 | (setq s (parse-partial-sexp (point) c-new-END nil |
| 1345 | nil s 'syntax-table)) | 1360 | nil s 'syntax-table)) |
| 1346 | (and (< (point) c-new-END) | 1361 | (and (< (point) c-new-END) |
| 1347 | (or (not (nth 3 s)) | 1362 | (or (not (nth 3 s)) |
| 1348 | (not (memq (char-before) c-string-delims)))))) | 1363 | (not (memq (char-before) c-string-delims)))))) |
| 1349 | ;; We're at the start of a string. | 1364 | ;; We're at the start of a string. |
| 1350 | (memq (char-before) c-string-delims))) | 1365 | (memq (char-before) c-string-delims))) |
| 1351 | (if (c-unescaped-nls-in-string-p (1- (point))) | 1366 | (unless (and (c-major-mode-is 'c++-mode) |
| 1352 | (looking-at "\\(\\\\\\(.\\|\n\\|\r\\)\\|[^\"]\\)*") | 1367 | (c-maybe-re-mark-raw-string)) |
| 1353 | (looking-at (cdr (assq (char-before) c-string-innards-re-alist)))) | 1368 | (if (c-unescaped-nls-in-string-p (1- (point))) |
| 1354 | (cond | 1369 | (looking-at "\\(\\\\\\(.\\|\n|\\\r\\)\\|[^\"]\\)*") |
| 1355 | ((memq (char-after (match-end 0)) '(?\n ?\r)) | 1370 | (looking-at (cdr (assq (char-before) c-string-innards-re-alist)))) |
| 1356 | (c-put-char-property (1- (point)) 'syntax-table '(15)) | 1371 | (cond |
| 1357 | (c-put-char-property (match-end 0) 'syntax-table '(15))) | 1372 | ((memq (char-after (match-end 0)) '(?\n ?\r)) |
| 1358 | ((or (eq (match-end 0) (point-max)) | 1373 | (c-put-char-property (1- (point)) 'syntax-table '(15)) |
| 1359 | (eq (char-after (match-end 0)) ?\\)) ; \ at EOB | 1374 | (c-put-char-property (match-end 0) 'syntax-table '(15))) |
| 1360 | (c-put-char-property (1- (point)) 'syntax-table '(15)))) | 1375 | ((or (eq (match-end 0) (point-max)) |
| 1361 | (goto-char (min (1+ (match-end 0)) (point-max))) | 1376 | (eq (char-after (match-end 0)) ?\\)) ; \ at EOB |
| 1377 | (c-put-char-property (1- (point)) 'syntax-table '(15)))) | ||
| 1378 | (goto-char (min (1+ (match-end 0)) (point-max)))) | ||
| 1362 | (setq s nil))))) | 1379 | (setq s nil))))) |
| 1363 | 1380 | ||
| 1364 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 1381 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| @@ -1721,7 +1738,6 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".") | |||
| 1721 | ;; (c-new-BEG c-new-END) will be the region to fontify. It may become | 1738 | ;; (c-new-BEG c-new-END) will be the region to fontify. It may become |
| 1722 | ;; larger than (beg end). | 1739 | ;; larger than (beg end). |
| 1723 | (setq c-new-END (- (+ c-new-END (- end beg)) old-len)) | 1740 | (setq c-new-END (- (+ c-new-END (- end beg)) old-len)) |
| 1724 | (setq c-old-BEG c-new-BEG c-old-END c-new-END) | ||
| 1725 | 1741 | ||
| 1726 | (unless (c-called-from-text-property-change-p) | 1742 | (unless (c-called-from-text-property-change-p) |
| 1727 | (setq c-just-done-before-change nil) | 1743 | (setq c-just-done-before-change nil) |