diff options
| author | Alan Mackenzie | 2019-03-30 13:19:47 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2019-03-30 13:19:47 +0000 |
| commit | b619777dd67e271d639c6fb1d031650af8fd79e6 (patch) | |
| tree | 59d47a1b9a5ce06d4bcde293979ba670fc5fd9aa | |
| parent | dd7d83e1dbe5c308384f92689d6eb27c9cde1c20 (diff) | |
| download | emacs-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.el | 12 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 52 |
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 | |||
| 604 | Note 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))) |