aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2019-03-30 13:19:47 +0000
committerAlan Mackenzie2019-03-30 13:19:47 +0000
commitb619777dd67e271d639c6fb1d031650af8fd79e6 (patch)
tree59d47a1b9a5ce06d4bcde293979ba670fc5fd9aa
parentdd7d83e1dbe5c308384f92689d6eb27c9cde1c20 (diff)
downloademacs-b619777dd67e271d639c6fb1d031650af8fd79e6.tar.gz
emacs-b619777dd67e271d639c6fb1d031650af8fd79e6.zip
Allow a CC Mode derived mode to have strings delimited by single quotes.
Also fix the bug where the delimiters of '\033', etc. got the error face. * lisp/progmodes/cc-langs.el (c-single-quotes-quote-strings): Enhance the docr string. (c-string-delims): Change doc string to doc comment. * listp/progmodes/cc-mode.el (c-before-change-check-unbalanced-strings): In searches and comparisons, take account of the string delimiters possibly being '. Fix argument in call of c-before-change-check-unbalanced-strings. (c-parse-quotes-before-change, c-parse-quotes-after-change): Bind case-fold-search to nil. Analyze escape constructs inside character constants more accurately, in particular accepting as valid more than one character after /[0-7], /x, /u, and /U. Amend calculations to account for this extra length.
-rw-r--r--lisp/progmodes/cc-langs.el12
-rw-r--r--lisp/progmodes/cc-mode.el52
2 files changed, 43 insertions, 21 deletions
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 22b7b602f1e..2dff5cf83c8 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -599,13 +599,21 @@ EOL terminated statements."
599(c-lang-defvar c-has-bitfields (c-lang-const c-has-bitfields)) 599(c-lang-defvar c-has-bitfields (c-lang-const c-has-bitfields))
600 600
601(c-lang-defconst c-single-quotes-quote-strings 601(c-lang-defconst c-single-quotes-quote-strings
602 "Whether the language uses single quotes for multi-char strings." 602 "Whether the language uses single quotes for multi-char strings.
603
604Note that to set up a language to use this, additionally:
605\(i) the syntax of \"'\" must be \"string quote\" (7);
606\(ii) the language's value of `c-has-quoted-numbers' must be nil;
607\(iii) the language's value of `c-get-state-before-change-functions' may not
608 contain `c-parse-quotes-before-change';
609\(iv) the language's value of `c-before-font-lock-functions' may not contain
610 `c-parse-quotes-after-change'."
603 t nil) 611 t nil)
604(c-lang-defvar c-single-quotes-quote-strings 612(c-lang-defvar c-single-quotes-quote-strings
605 (c-lang-const c-single-quotes-quote-strings)) 613 (c-lang-const c-single-quotes-quote-strings))
606 614
607(c-lang-defconst c-string-delims 615(c-lang-defconst c-string-delims
608 "A list of characters which can delimit arbitrary length strings" 616;; A list of characters which can delimit arbitrary length strings.
609 t (if (c-lang-const c-single-quotes-quote-strings) 617 t (if (c-lang-const c-single-quotes-quote-strings)
610 '(?\" ?\') 618 '(?\" ?\')
611 '(?\"))) 619 '(?\")))
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index b7812fa8f3d..49268c4482e 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1212,12 +1212,15 @@ Note that the style variables are always made local to the buffer."
1212 (while 1212 (while
1213 (and 1213 (and
1214 (c-syntactic-re-search-forward 1214 (c-syntactic-re-search-forward
1215 "\"\\|\\s|" (point-max) t t) 1215 (if c-single-quotes-quote-strings
1216 "[\"']\\|\\s|"
1217 "\"\\|\\s|")
1218 (point-max) t t)
1216 (progn 1219 (progn
1217 (c-clear-char-property (1- (point)) 'syntax-table) 1220 (c-clear-char-property (1- (point)) 'syntax-table)
1218 (c-truncate-semi-nonlit-pos-cache (1- (point))) 1221 (c-truncate-semi-nonlit-pos-cache (1- (point)))
1219 (not (eq (char-before) ?\"))))) 1222 (not (memq (char-before) c-string-delims)))))
1220 (eq (char-before) ?\")) 1223 (memq (char-before) c-string-delims))
1221 (progn 1224 (progn
1222 (c-pps-to-string-delim (point-max)) 1225 (c-pps-to-string-delim (point-max))
1223 (< (point) (point-max)))))) 1226 (< (point) (point-max))))))
@@ -1229,7 +1232,9 @@ Note that the style variables are always made local to the buffer."
1229 (eq beg-literal-type 'string)))) 1232 (eq beg-literal-type 'string))))
1230 ;; Deal with deletion of backslashes before "s. 1233 ;; Deal with deletion of backslashes before "s.
1231 (goto-char end) 1234 (goto-char end)
1232 (if (and (looking-at "\\\\*\"") 1235 (if (and (looking-at (if c-single-quotes-quote-strings
1236 "\\\\*[\"']"
1237 "\\\\*\""))
1233 (eq (logand (skip-chars-backward "\\\\" beg) 1) 1)) 1238 (eq (logand (skip-chars-backward "\\\\" beg) 1) 1))
1234 (setq c-bc-changed-stringiness (not c-bc-changed-stringiness))) 1239 (setq c-bc-changed-stringiness (not c-bc-changed-stringiness)))
1235 (if (eq beg-literal-type 'string) 1240 (if (eq beg-literal-type 'string)
@@ -1250,12 +1255,12 @@ Note that the style variables are always made local to the buffer."
1250 (forward-char) 1255 (forward-char)
1251 (backward-sexp) 1256 (backward-sexp)
1252 (c-clear-char-property eoll-1 'syntax-table) 1257 (c-clear-char-property eoll-1 'syntax-table)
1253 (c-truncate-semi-nonlit-pos-cache eoll-1) 1258 (c-clear-char-property (point) 'syntax-table)
1254 (c-clear-char-property (point) 'syntax-table)) 1259 (c-truncate-semi-nonlit-pos-cache (point)))
1255 ;; Opening " at EOB. 1260 ;; Opening " at EOB.
1256 (c-clear-char-property (1- (point)) 'syntax-table)) 1261 (c-clear-char-property (1- (point)) 'syntax-table))
1257 (when (and (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) 1262 (when (and (c-search-backward-char-property 'syntax-table '(15) c-new-BEG)
1258 (eq (char-after) ?\")) ; Ignore an unterminated raw string's (. 1263 (memq (char-after) c-string-delims)) ; Ignore an unterminated raw string's (.
1259 ;; Opening " on last line of text (without EOL). 1264 ;; Opening " on last line of text (without EOL).
1260 (c-clear-char-property (point) 'syntax-table) 1265 (c-clear-char-property (point) 'syntax-table)
1261 (c-truncate-semi-nonlit-pos-cache (point))))) 1266 (c-truncate-semi-nonlit-pos-cache (point)))))
@@ -1264,7 +1269,7 @@ Note that the style variables are always made local to the buffer."
1264 (when 1269 (when
1265 (and 1270 (and
1266 (c-search-backward-char-property 'syntax-table '(15) c-new-BEG) 1271 (c-search-backward-char-property 'syntax-table '(15) c-new-BEG)
1267 (eq (char-after) ?\")) 1272 (memq (char-after) c-string-delims))
1268 (c-clear-char-property (point) 'syntax-table) 1273 (c-clear-char-property (point) 'syntax-table)
1269 (c-truncate-semi-nonlit-pos-cache (point))))) 1274 (c-truncate-semi-nonlit-pos-cache (point)))))
1270 1275
@@ -1276,7 +1281,7 @@ Note that the style variables are always made local to the buffer."
1276 (c-truncate-semi-nonlit-pos-cache (1- (cdr end-limits)))) 1281 (c-truncate-semi-nonlit-pos-cache (1- (cdr end-limits))))
1277 1282
1278 (when (and (eq beg-literal-type 'string) 1283 (when (and (eq beg-literal-type 'string)
1279 (eq (char-after (car beg-limits)) ?\")) 1284 (memq (char-after (car beg-limits)) c-string-delims))
1280 (setq c-new-BEG (min c-new-BEG (car beg-limits))) 1285 (setq c-new-BEG (min c-new-BEG (car beg-limits)))
1281 (c-clear-char-property (car beg-limits) 'syntax-table) 1286 (c-clear-char-property (car beg-limits) 'syntax-table)
1282 (c-truncate-semi-nonlit-pos-cache (car beg-limits)))))) 1287 (c-truncate-semi-nonlit-pos-cache (car beg-limits))))))
@@ -1492,7 +1497,7 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1492 ;; 1497 ;;
1493 ;; This function is called exclusively as a before-change function via the 1498 ;; This function is called exclusively as a before-change function via the
1494 ;; variable `c-get-state-before-change-functions'. 1499 ;; variable `c-get-state-before-change-functions'.
1495 (c-save-buffer-state () 1500 (c-save-buffer-state (case-fold-search)
1496 (goto-char c-new-BEG) 1501 (goto-char c-new-BEG)
1497 ;; We need to scan for 's from the BO (logical) line. 1502 ;; We need to scan for 's from the BO (logical) line.
1498 (beginning-of-line) 1503 (beginning-of-line)
@@ -1508,13 +1513,13 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1508 ((c-quoted-number-head-before-point) 1513 ((c-quoted-number-head-before-point)
1509 (if (>= (point) c-new-BEG) 1514 (if (>= (point) c-new-BEG)
1510 (setq c-new-BEG (match-beginning 0)))) 1515 (setq c-new-BEG (match-beginning 0))))
1511 ((looking-at "\\([^'\\]\\|\\\\.\\)'") 1516 ((looking-at
1517 "\\([^'\\]\\|\\\\\\([0-7]\\{1,3\\}\\|[xuU][0-9a-fA-F]+\\|.\\)\\)'")
1512 (goto-char (match-end 0)) 1518 (goto-char (match-end 0))
1513 (if (> (match-end 0) c-new-BEG) 1519 (if (> (match-end 0) c-new-BEG)
1514 (setq c-new-BEG (1- (match-beginning 0))))) 1520 (setq c-new-BEG (1- (match-beginning 0)))))
1515 ((or (>= (point) (1- c-new-BEG)) 1521 ((save-excursion
1516 (and (eq (point) (- c-new-BEG 2)) 1522 (not (search-forward "'" c-new-BEG t)))
1517 (eq (char-after) ?\\)))
1518 (setq c-new-BEG (1- (point)))) 1523 (setq c-new-BEG (1- (point))))
1519 (t nil))) 1524 (t nil)))
1520 1525
@@ -1534,19 +1539,26 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1534 (goto-char (match-end 0)) 1539 (goto-char (match-end 0))
1535 (if (> (match-end 0) c-new-END) 1540 (if (> (match-end 0) c-new-END)
1536 (setq c-new-END (match-end 0)))) 1541 (setq c-new-END (match-end 0))))
1537 ((looking-at "\\([^'\\]\\|\\\\.\\)'") 1542 ((looking-at
1543 "\\([^'\\]\\|\\\\\\([0-7]\\{1,3\\}\\|[xuU][0-9a-fA-F]+\\|.\\)\\)'")
1538 (goto-char (match-end 0)) 1544 (goto-char (match-end 0))
1539 (if (> (match-end 0) c-new-END) 1545 (if (> (match-end 0) c-new-END)
1540 (setq c-new-END (match-end 0)))) 1546 (setq c-new-END (match-end 0))))
1547 ((equal (c-get-char-property (1- (point)) 'syntax-table) '(1))
1548 (when (c-search-forward-char-property-with-value-on-char
1549 'syntax-table '(1) ?\' (c-point 'eoll))
1550 (setq c-new-END (max (point) c-new-END))))
1541 (t nil))) 1551 (t nil)))
1542 ;; Having reached c-new-END, handle any 's after it whose context may be 1552 ;; Having reached c-new-END, handle any 's after it whose context may be
1543 ;; changed by the current buffer change. 1553 ;; changed by the current buffer change. The idea is to catch
1554 ;; monstrosities like ',',',',',' changing "polarity".
1544 (goto-char c-new-END) 1555 (goto-char c-new-END)
1545 (cond 1556 (cond
1546 ((c-quoted-number-tail-after-point) 1557 ((c-quoted-number-tail-after-point)
1547 (setq c-new-END (match-end 0))) 1558 (setq c-new-END (match-end 0)))
1548 ((looking-at 1559 ((looking-at
1549 "\\(\\\\.\\|.\\)?\\('\\([^'\\]\\|\\\\.\\)\\)*'") 1560 "\\(\\\\\\([0-7]\\{1,3\\}\\|[xuU][0-9a-fA-F]+\\|.\\)\\|.\\)?\
1561\\('\\([^'\\]\\|\\\\\\([0-7]\\{1,3\\}\\|[xuU][0-9a-fA-F]+\\|.\\)\\)\\)*'")
1550 (setq c-new-END (match-end 0)))) 1562 (setq c-new-END (match-end 0))))
1551 1563
1552 ;; Remove the '(1) syntax-table property from any "'"s within (c-new-BEG 1564 ;; Remove the '(1) syntax-table property from any "'"s within (c-new-BEG
@@ -1575,7 +1587,7 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1575 ;; 1587 ;;
1576 ;; This function is called exclusively as an after-change function via the 1588 ;; This function is called exclusively as an after-change function via the
1577 ;; variable `c-before-font-lock-functions'. 1589 ;; variable `c-before-font-lock-functions'.
1578 (c-save-buffer-state (num-beg num-end) 1590 (c-save-buffer-state (num-beg num-end case-fold-search)
1579 ;; Apply the needed syntax-table and c-digit-separator text properties to 1591 ;; Apply the needed syntax-table and c-digit-separator text properties to
1580 ;; quotes. 1592 ;; quotes.
1581 (save-restriction 1593 (save-restriction
@@ -1597,7 +1609,9 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1597 (c-put-char-properties-on-char num-beg num-end 1609 (c-put-char-properties-on-char num-beg num-end
1598 'c-digit-separator t ?') 1610 'c-digit-separator t ?')
1599 (goto-char num-end)) 1611 (goto-char num-end))
1600 ((looking-at "\\([^\\']\\|\\\\.\\)'") ; balanced quoted expression. 1612 ((looking-at
1613 "\\([^\\']\\|\\\\\\([0-7]\\{1,3\\}\\|[xuU][0-9a-fA-F]+\\|.\\)\
1614\\)'") ; balanced quoted expression.
1601 (goto-char (match-end 0))) 1615 (goto-char (match-end 0)))
1602 (t 1616 (t
1603 (c-invalidate-state-cache (1- (point))) 1617 (c-invalidate-state-cache (1- (point)))