aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2019-07-02 12:33:01 +0000
committerAlan Mackenzie2019-07-02 12:33:01 +0000
commitb25d58c956a9fcd2b81b804699573ea851bd8fde (patch)
tree75567cf91b5108b6257e2f83ae89a73448ce4581
parent22b64f7bac8d015f3d0e6a42e9d764a61656e7a1 (diff)
downloademacs-b25d58c956a9fcd2b81b804699573ea851bd8fde.tar.gz
emacs-b25d58c956a9fcd2b81b804699573ea851bd8fde.zip
CC Mode: Improve handling of unbalanced strings
* lisp/progmodes/cc-fonts.el (c-before-font-lock-functions): Add function c-after-change-escape-NL-in-string into value for most languages. * lisp/progmodes/cc-mode.el (c-after-change-escape-NL-in-string): New function. (c-before-change-check-unbalanced-strings): Handle the making and breaking of escaped newlines, by removal or addition of text.
-rw-r--r--lisp/progmodes/cc-langs.el6
-rw-r--r--lisp/progmodes/cc-mode.el78
2 files changed, 78 insertions, 6 deletions
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 2fcd6acf51f..153d3fc2608 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -478,7 +478,7 @@ so that all identifiers are recognized as words.")
478 (list fs))) 478 (list fs)))
479 "If non-nil, a list of functions called from c-before-change-hook. 479 "If non-nil, a list of functions called from c-before-change-hook.
480Typically these will record enough state to allow 480Typically these will record enough state to allow
481`c-before-font-lock-function' to extend the region to fontify, 481`c-before-font-lock-functions' to extend the region to fontify,
482and may do such things as removing text-properties which must be 482and may do such things as removing text-properties which must be
483recalculated. 483recalculated.
484 484
@@ -497,15 +497,18 @@ 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-escape-NL-in-string
500 c-after-change-mark-abnormal-strings 501 c-after-change-mark-abnormal-strings
501 c-change-expand-fl-region) 502 c-change-expand-fl-region)
502 (c objc) '(c-depropertize-new-text 503 (c objc) '(c-depropertize-new-text
504 c-after-change-escape-NL-in-string
503 c-parse-quotes-after-change 505 c-parse-quotes-after-change
504 c-after-change-mark-abnormal-strings 506 c-after-change-mark-abnormal-strings
505 c-extend-font-lock-region-for-macros 507 c-extend-font-lock-region-for-macros
506 c-neutralize-syntax-in-CPP 508 c-neutralize-syntax-in-CPP
507 c-change-expand-fl-region) 509 c-change-expand-fl-region)
508 c++ '(c-depropertize-new-text 510 c++ '(c-depropertize-new-text
511 c-after-change-escape-NL-in-string
509 c-after-change-unmark-raw-strings 512 c-after-change-unmark-raw-strings
510 c-parse-quotes-after-change 513 c-parse-quotes-after-change
511 c-after-change-mark-abnormal-strings 514 c-after-change-mark-abnormal-strings
@@ -514,6 +517,7 @@ parameters \(point-min) and \(point-max).")
514 c-restore-<>-properties 517 c-restore-<>-properties
515 c-change-expand-fl-region) 518 c-change-expand-fl-region)
516 java '(c-depropertize-new-text 519 java '(c-depropertize-new-text
520 c-after-change-escape-NL-in-string
517 c-parse-quotes-after-change 521 c-parse-quotes-after-change
518 c-after-change-mark-abnormal-strings 522 c-after-change-mark-abnormal-strings
519 c-restore-<>-properties 523 c-restore-<>-properties
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 5c18879712c..8f4bb341acb 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1262,11 +1262,31 @@ Note that the style variables are always made local to the buffer."
1262 (setq c-new-BEG (min (car beg-limits) c-new-BEG)))) 1262 (setq c-new-BEG (min (car beg-limits) c-new-BEG))))
1263 1263
1264 ((< end (point-max)) 1264 ((< end (point-max))
1265 (goto-char (1+ end)) ; might be a newline. 1265 ;; Have we just escaped a newline by deleting characters?
1266 ;; In the following regexp, the initial \n caters for a newline getting 1266 (if (and (eq end-literal-type 'string)
1267 ;; joined to a preceding \ by the removal of what comes between. 1267 (memq (char-after end) '(?\n ?\r)))
1268 (re-search-forward "[\n\r]?\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*" 1268 (cond
1269 nil t) 1269 ;; Are we escaping a newline by deleting stuff between \ and \n?
1270 ((and (> end beg)
1271 (progn
1272 (goto-char end)
1273 (eq (logand (skip-chars-backward "\\\\" beg) 1) 1)))
1274 (c-clear-char-property end 'syntax-table)
1275 (c-truncate-lit-pos-cache end)
1276 (goto-char (1+ end)))
1277 ;; Are we unescaping a newline by inserting stuff between \ and \n?
1278 ((and (eq end beg)
1279 (progn
1280 (goto-char end)
1281 (eq (logand (skip-chars-backward "\\\\") 1) 1)))
1282 (goto-char (1+ end))) ; To after the NL which is being unescaped.
1283 (t
1284 (goto-char end)))
1285 (goto-char end))
1286
1287 ;; Move to end of logical line (as it will be after the change, or as it
1288 ;; was before unescaping a NL.)
1289 (re-search-forward "\\(\\\\\\(.\\|\n\\|\r\\)\\|[^\\\n\r]\\)*" nil t)
1270 ;; We're at an EOLL or point-max. 1290 ;; We're at an EOLL or point-max.
1271 (if (equal (c-get-char-property (point) 'syntax-table) '(15)) 1291 (if (equal (c-get-char-property (point) 'syntax-table) '(15))
1272 (if (memq (char-after) '(?\n ?\r)) 1292 (if (memq (char-after) '(?\n ?\r))
@@ -1426,6 +1446,54 @@ Note that the style variables are always made local to the buffer."
1426 (goto-char (min (1+ (match-end 0)) (point-max)))) 1446 (goto-char (min (1+ (match-end 0)) (point-max))))
1427 (setq s nil))))) 1447 (setq s nil)))))
1428 1448
1449(defun c-after-change-escape-NL-in-string (beg end _old_len)
1450 ;; If a backslash has just been inserted into a string, and this quotes an
1451 ;; existing newline, remove the string fence syntax-table text properties
1452 ;; on what has become the tail of the string.
1453 ;;
1454 ;; POINT is undefined both at entry to and exit from this function, the
1455 ;; buffer will have been widened, and match data will have been saved.
1456 ;;
1457 ;; This function is called exclusively as an after-change function via
1458 ;; `c-before-font-lock-functions'. In C++ Mode, it should come before
1459 ;; `c-after-change-unmark-raw-strings' in that lang variable.
1460 (let (lit-start) ; Don't calculate this till we have to.
1461 (when
1462 (and (> end beg)
1463 (memq (char-after end) '(?\n ?\r))
1464 (progn (goto-char end)
1465 (eq (logand (skip-chars-backward "\\\\") 1) 1))
1466 (progn (goto-char end)
1467 (setq lit-start (c-literal-start)))
1468 (memq (char-after lit-start) c-string-delims)
1469 (or (not (c-major-mode-is 'c++-mode))
1470 (progn
1471 (goto-char lit-start)
1472 (and (not (and (eq (char-before) ?R)
1473 (looking-at c-c++-raw-string-opener-1-re)))
1474 (not (and (eq (char-after) ?\()
1475 (equal (c-get-char-property
1476 (point) 'syntax-table)
1477 '(15))))))
1478 (save-excursion
1479 (c-beginning-of-macro))))
1480 (goto-char (1+ end)) ; After the \
1481 ;; Search forward for a closing ".
1482 (when (and (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\"\\\n\r]\\)*"
1483 nil t)
1484 (eq (char-after) ?\")
1485 (equal (c-get-char-property (point) 'syntax-table) '(15)))
1486 (c-clear-char-property end 'syntax-table)
1487 (c-truncate-lit-pos-cache end)
1488 (c-clear-char-property (point) 'syntax-table)
1489 (forward-char) ; to after the "
1490 (when
1491 (and
1492 ;; Search forward for an end of logical line.
1493 (re-search-forward "\\(\\\\\\(.\\|\n\\)\\|[^\\\n\r]\\)*" nil t)
1494 (memq (char-after) '(?\n ?\r)))
1495 (c-clear-char-property (point) 'syntax-table))))))
1496
1429;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1497;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1430;; Parsing of quotes. 1498;; Parsing of quotes.
1431;; 1499;;