aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2017-07-01 15:43:07 +0000
committerAlan Mackenzie2017-07-01 15:43:07 +0000
commit59d07875df9d44568d93a7517853e6a5ccaf1e5b (patch)
treeec96cf9039ad80fefc6756aee7fbddc05b44ae13
parente620bbe38ed5e3e2a77f01eac2814c01dfa41c2d (diff)
downloademacs-59d07875df9d44568d93a7517853e6a5ccaf1e5b.tar.gz
emacs-59d07875df9d44568d93a7517853e6a5ccaf1e5b.zip
Make C++ digit separators work. Amend the handling of single quotes generally
Single quotes, even in strings and comments, are now marked with the "punctuation" syntax-table property, except where they are validly bounding a character literal. They are font locked with font-lock-warning-face except where they are valid. This is done in C, C++, ObjC, and Java Modes. * lisp/progmodes/cc-defs.el (c-clear-char-property-with-value-on-char-function) (c-clear-char-property-with-value-on-char, c-put-char-properties-on-char): New functions/macros. * lisp/progmodes/cc-fonts.el (c-font-lock-invalid-single-quotes): New function. (c-basic-matchers-before): invoke c-font-lock-invalid-single-quotes. * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): Remove c-before-after-change-digit-quote from wherever it occurs. Insert c-parse-quotes-before-change into the entries for the languages where it is needed. (c-before-font-lock-functions): Remove c-before-after-change-digit-quote from wherever it occurs. Insert c-parse-quotes-after-change into the entries for the languages which need it. (c-has-quoted-numbers): New lang-defconst/-defvar. * lisp/progmodes/cc-mode.el (c-before-after-change-digit-quote): Remove. (c-maybe-quoted-number-head, c-maybe-quoted-number-tail) (c-maybe-quoted-number): New defconsts. (c-quoted-number-head-before-point, c-quoted-number-tail-after-point) (c-quoted-number-straddling-point, c-parse-quotes-before-change) (c-parse-quotes-after-change): New functions.
-rw-r--r--lisp/progmodes/cc-defs.el59
-rw-r--r--lisp/progmodes/cc-fonts.el33
-rw-r--r--lisp/progmodes/cc-langs.el22
-rw-r--r--lisp/progmodes/cc-mode.el294
4 files changed, 311 insertions, 97 deletions
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 377a981598a..85a4085e490 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -1171,6 +1171,63 @@ been put there by c-put-char-property. POINT remains unchanged."
1171 nil ,from ,to ,value nil -property-)) 1171 nil ,from ,to ,value nil -property-))
1172 ;; GNU Emacs 1172 ;; GNU Emacs
1173 `(c-clear-char-property-with-value-function ,from ,to ,property ,value))) 1173 `(c-clear-char-property-with-value-function ,from ,to ,property ,value)))
1174
1175(defun c-clear-char-property-with-value-on-char-function (from to property
1176 value char)
1177 "Remove all text-properties PROPERTY with value VALUE on
1178characters with value CHAR from the region [FROM, TO), as tested
1179by `equal'. These properties are assumed to be over individual
1180characters, having been put there by c-put-char-property. POINT
1181remains unchanged."
1182 (let ((place from)
1183 )
1184 (while ; loop round occurrences of (PROPERTY VALUE)
1185 (progn
1186 (while ; loop round changes in PROPERTY till we find VALUE
1187 (and
1188 (< place to)
1189 (not (equal (get-text-property place property) value)))
1190 (setq place (c-next-single-property-change place property nil to)))
1191 (< place to))
1192 (if (eq (char-after place) char)
1193 (remove-text-properties place (1+ place) (cons property nil)))
1194 ;; Do we have to do anything with stickiness here?
1195 (setq place (1+ place)))))
1196
1197(defmacro c-clear-char-property-with-value-on-char (from to property value char)
1198 "Remove all text-properties PROPERTY with value VALUE on
1199characters with value CHAR from the region [FROM, TO), as tested
1200by `equal'. These properties are assumed to be over individual
1201characters, having been put there by c-put-char-property. POINT
1202remains unchanged."
1203 (if c-use-extents
1204 ;; XEmacs
1205 `(let ((-property- ,property)
1206 (-char- ,char))
1207 (map-extents (lambda (ext val)
1208 (if (and (equal (extent-property ext -property-) val)
1209 (eq (char-after
1210 (extent-start-position ext))
1211 -char-))
1212 (delete-extent ext)))
1213 nil ,from ,to ,value nil -property-))
1214 ;; Gnu Emacs
1215 `(c-clear-char-property-with-value-on-char-function ,from ,to ,property
1216 ,value ,char)))
1217
1218(defmacro c-put-char-properties-on-char (from to property value char)
1219 ;; This needs to be a macro because `property' passed to
1220 ;; `c-put-char-property' must be a constant.
1221 "Put the text property PROPERTY with value VALUE on characters
1222with value CHAR in the region [FROM to)."
1223 `(let ((skip-string (concat "^" (list ,char)))
1224 (-to- ,to))
1225 (save-excursion
1226 (goto-char ,from)
1227 (while (progn (skip-chars-forward skip-string -to-)
1228 (< (point) -to-))
1229 (c-put-char-property (point) ,property ,value)
1230 (forward-char)))))
1174 1231
1175;; Macros to put overlays (Emacs) or extents (XEmacs) on buffer text. 1232;; Macros to put overlays (Emacs) or extents (XEmacs) on buffer text.
1176;; For our purposes, these are characterized by being possible to 1233;; For our purposes, these are characterized by being possible to
@@ -1228,6 +1285,8 @@ been put there by c-put-char-property. POINT remains unchanged."
1228(def-edebug-spec c-put-char-property t) 1285(def-edebug-spec c-put-char-property t)
1229(def-edebug-spec c-get-char-property t) 1286(def-edebug-spec c-get-char-property t)
1230(def-edebug-spec c-clear-char-property t) 1287(def-edebug-spec c-clear-char-property t)
1288(def-edebug-spec c-clear-char-property-with-value-on-char t)
1289(def-edebug-spec c-put-char-properties-on-char t)
1231(def-edebug-spec c-clear-char-properties t) 1290(def-edebug-spec c-clear-char-properties t)
1232(def-edebug-spec c-put-overlay t) 1291(def-edebug-spec c-put-overlay t)
1233(def-edebug-spec c-delete-overlay t) 1292(def-edebug-spec c-delete-overlay t)
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 00812530357..66f2575f49f 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -702,6 +702,36 @@ stuff. Used on level 1 and higher."
702 t) 702 t)
703 (c-put-font-lock-face start (1+ start) 'font-lock-warning-face))))) 703 (c-put-font-lock-face start (1+ start) 'font-lock-warning-face)))))
704 704
705(defun c-font-lock-invalid-single-quotes (limit)
706 ;; This function will be called from font-lock for a region bounded by POINT
707 ;; and LIMIT, as though it were to identify a keyword for
708 ;; font-lock-keyword-face. It always returns NIL to inhibit this and
709 ;; prevent a repeat invocation. See elisp/lispref page "Search-based
710 ;; Fontification".
711 ;;
712 ;; This function fontifies invalid single quotes with
713 ;; `font-lock-warning-face'. These are the single quotes which
714 ;; o - aren't inside a literal;
715 ;; o - are marked with a syntax-table text property value '(1); and
716 ;; o - are NOT marked with a non-null c-digit-separator property.
717 (let ((limits (c-literal-limits))
718 state beg end)
719 (if limits
720 (goto-char (cdr limits))) ; Even for being in a ' '
721 (while (< (point) limit)
722 (setq beg (point))
723 (setq state (parse-partial-sexp (point) limit nil nil nil 'syntax-table))
724 (setq end (point))
725 (goto-char beg)
726 (while (progn (skip-chars-forward "^'" end)
727 (< (point) end))
728 (if (and (equal (c-get-char-property (point) 'syntax-table) '(1))
729 (not (c-get-char-property (point) 'c-digit-separator)))
730 (c-put-font-lock-face (point) (1+ (point)) font-lock-warning-face))
731 (forward-char))
732 (parse-partial-sexp end limit nil nil state 'syntax-table)))
733 nil)
734
705(c-lang-defconst c-basic-matchers-before 735(c-lang-defconst c-basic-matchers-before
706 "Font lock matchers for basic keywords, labels, references and various 736 "Font lock matchers for basic keywords, labels, references and various
707other easily recognizable things that should be fontified before generic 737other easily recognizable things that should be fontified before generic
@@ -723,6 +753,9 @@ casts and declarations are fontified. Used on level 2 and higher."
723 (concat ".\\(" c-string-limit-regexp "\\)") 753 (concat ".\\(" c-string-limit-regexp "\\)")
724 '((c-font-lock-invalid-string))) 754 '((c-font-lock-invalid-string)))
725 755
756 ;; Invalid single quotes.
757 c-font-lock-invalid-single-quotes
758
726 ;; Fontify C++ raw strings. 759 ;; Fontify C++ raw strings.
727 ,@(when (c-major-mode-is 'c++-mode) 760 ,@(when (c-major-mode-is 'c++-mode)
728 '(c-font-lock-raw-strings)) 761 '(c-font-lock-raw-strings))
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 1ce0fbf7d05..8be806094cd 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -474,18 +474,19 @@ so that all identifiers are recognized as words.")
474 ;; The value here may be a list of functions or a single function. 474 ;; The value here may be a list of functions or a single function.
475 t nil 475 t nil
476 c++ '(c-extend-region-for-CPP 476 c++ '(c-extend-region-for-CPP
477; c-before-after-change-extend-region-for-lambda-capture ; doesn't seem needed.
478 c-before-change-check-raw-strings 477 c-before-change-check-raw-strings
479 c-before-change-check-<>-operators 478 c-before-change-check-<>-operators
480 c-depropertize-CPP 479 c-depropertize-CPP
481 c-before-after-change-digit-quote
482 c-invalidate-macro-cache 480 c-invalidate-macro-cache
483 c-truncate-bs-cache) 481 c-truncate-bs-cache
482 c-parse-quotes-before-change)
484 (c objc) '(c-extend-region-for-CPP 483 (c objc) '(c-extend-region-for-CPP
485 c-depropertize-CPP 484 c-depropertize-CPP
486 c-invalidate-macro-cache 485 c-invalidate-macro-cache
487 c-truncate-bs-cache) 486 c-truncate-bs-cache
488 ;; java 'c-before-change-check-<>-operators 487 c-parse-quotes-before-change)
488 java 'c-parse-quotes-before-change
489 ;; 'c-before-change-check-<>-operators
489 awk 'c-awk-record-region-clear-NL) 490 awk 'c-awk-record-region-clear-NL)
490(c-lang-defvar c-get-state-before-change-functions 491(c-lang-defvar c-get-state-before-change-functions
491 (let ((fs (c-lang-const c-get-state-before-change-functions))) 492 (let ((fs (c-lang-const c-get-state-before-change-functions)))
@@ -515,18 +516,19 @@ parameters \(point-min) and \(point-max).")
515 t '(c-depropertize-new-text 516 t '(c-depropertize-new-text
516 c-change-expand-fl-region) 517 c-change-expand-fl-region)
517 (c objc) '(c-depropertize-new-text 518 (c objc) '(c-depropertize-new-text
519 c-parse-quotes-after-change
518 c-extend-font-lock-region-for-macros 520 c-extend-font-lock-region-for-macros
519 c-neutralize-syntax-in-and-mark-CPP 521 c-neutralize-syntax-in-and-mark-CPP
520 c-change-expand-fl-region) 522 c-change-expand-fl-region)
521 c++ '(c-depropertize-new-text 523 c++ '(c-depropertize-new-text
524 c-parse-quotes-after-change
522 c-extend-font-lock-region-for-macros 525 c-extend-font-lock-region-for-macros
523; c-before-after-change-extend-region-for-lambda-capture ; doesn't seem needed.
524 c-before-after-change-digit-quote
525 c-after-change-re-mark-raw-strings 526 c-after-change-re-mark-raw-strings
526 c-neutralize-syntax-in-and-mark-CPP 527 c-neutralize-syntax-in-and-mark-CPP
527 c-restore-<>-properties 528 c-restore-<>-properties
528 c-change-expand-fl-region) 529 c-change-expand-fl-region)
529 java '(c-depropertize-new-text 530 java '(c-depropertize-new-text
531 c-parse-quotes-after-change
530 c-restore-<>-properties 532 c-restore-<>-properties
531 c-change-expand-fl-region) 533 c-change-expand-fl-region)
532 awk '(c-depropertize-new-text 534 awk '(c-depropertize-new-text
@@ -609,6 +611,12 @@ EOL terminated statements."
609 (c c++ objc) t) 611 (c c++ objc) t)
610(c-lang-defvar c-has-bitfields (c-lang-const c-has-bitfields)) 612(c-lang-defvar c-has-bitfields (c-lang-const c-has-bitfields))
611 613
614(c-lang-defconst c-has-quoted-numbers
615 "Whether the language has numbers quoted like 4'294'967'295."
616 t nil
617 c++ t)
618(c-lang-defvar c-has-quoted-numbers (c-lang-const c-has-quoted-numbers))
619
612(c-lang-defconst c-modified-constant 620(c-lang-defconst c-modified-constant
613 "Regexp that matches a “modified” constant literal such as \"L\\='a\\='\", 621 "Regexp that matches a “modified” constant literal such as \"L\\='a\\='\",
614a “long character”. In particular, this recognizes forms of constant 622a “long character”. In particular, this recognizes forms of constant
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index a501ebba256..c5ee60f7d79 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1083,101 +1083,215 @@ Note that the style variables are always made local to the buffer."
1083 (forward-line)) ; no infinite loop with, e.g., "#//" 1083 (forward-line)) ; no infinite loop with, e.g., "#//"
1084 ))))) 1084 )))))
1085 1085
1086(defun c-before-after-change-digit-quote (beg end &optional old-len) 1086;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1087 ;; This function either removes or applies the punctuation value ('(1)) of 1087;; Parsing of quotes.
1088 ;; the `syntax-table' text property on single quote marks which are 1088;;
1089 ;; separator characters in long integer literals, e.g. "4'294'967'295". It 1089;; Valid digit separators in numbers will get the syntax-table "punctuation"
1090 ;; applies to both decimal/octal and hex literals. (FIXME (2016-06-10): it 1090;; property, '(1), and also the text property `c-digit-separator' value t.
1091 ;; should also apply to binary literals.) 1091;;
1092;; Invalid other quotes (i.e. those not validly bounding a single character,
1093;; or escaped character) will get the syntax-table "punctuation" property,
1094;; '(1), too.
1095;;
1096;; Note that, for convenience, these properties are applied even inside
1097;; comments and strings.
1098
1099(defconst c-maybe-quoted-number-head
1100 (concat
1101 "\\(0\\("
1102 "\\([Xx]\\([0-9a-fA-F]\\('[0-9a-fA-F]\\|[0-9a-fA-F]\\)*'?\\)?\\)"
1103 "\\|"
1104 "\\([Bb]\\([01]\\('[01]\\|[01]\\)*'?\\)?\\)"
1105 "\\|"
1106 "\\('[0-7]\\|[0-7]\\)*'?"
1107 "\\)"
1108 "\\|"
1109 "[1-9]\\('[0-9]\\|[0-9]\\)*'?"
1110 "\\)")
1111 "Regexp matching the head of a numeric literal, including with digit separators.")
1112
1113(defun c-quoted-number-head-before-point ()
1114 ;; Return non-nil when the head of a possibly quoted number is found
1115 ;; immediately before point. The value returned in this case is the buffer
1116 ;; position of the start of the head.
1117 (when c-has-quoted-numbers
1118 (save-excursion
1119 (let ((here (point))
1120 )
1121 (skip-chars-backward "0-9a-fA-F'")
1122 (if (and (memq (char-before) '(?x ?X))
1123 (eq (char-before (1- (point))) ?0))
1124 (backward-char 2))
1125 (while (and (search-forward-regexp c-maybe-quoted-number-head here t)
1126 (< (match-end 0) here)))
1127 (and (eq (match-end 0) here) (match-beginning 0))))))
1128
1129(defconst c-maybe-quoted-number-tail
1130 (concat
1131 "\\("
1132 "\\([xX']?[0-9a-fA-F]\\('[0-9a-fA-F]\\|[0-9a-fA-F]\\)*\\)"
1133 "\\|"
1134 "\\([bB']?[01]\\('[01]\\|[01]\\)*\\)"
1135 "\\|"
1136 "\\('?[0-9]\\('[0-9]\\|[0-9]\\)*\\)"
1137 "\\)")
1138 "Regexp matching the tail of a numeric literal, including with digit separators.
1139Note that this is a strict tail, so won't match, e.g. \"0x....\".")
1140
1141(defun c-quoted-number-tail-after-point ()
1142 ;; Return non-nil when a proper tail of a possibly quoted number is found
1143 ;; immediately after point. The value returned in this case is the buffer
1144 ;; position of the end of the tail.
1145 (when c-has-quoted-numbers
1146 (and (looking-at c-maybe-quoted-number-tail)
1147 (match-end 0))))
1148
1149(defconst c-maybe-quoted-number
1150 (concat
1151 "\\(0\\("
1152 "\\([Xx][0-9a-fA-F]\\('[0-9a-fA-F]\\|[0-9a-fA-F]\\)*\\)"
1153 "\\|"
1154 "\\([Bb][01]\\('[01]\\|[01]\\)*\\)"
1155 "\\|"
1156 "\\('[0-7]\\|[0-7]\\)*"
1157 "\\)"
1158 "\\|"
1159 "[1-9]\\('[0-9]\\|[0-9]\\)*"
1160 "\\)")
1161 "Regexp matching a numeric literal, including with digit separators.")
1162
1163(defun c-quoted-number-straddling-point ()
1164 ;; Return non-nil if a definitely quoted number starts before point and ends
1165 ;; after point. In this case the number is bounded by (match-beginning 0)
1166 ;; and (match-end 0).
1167 (when c-has-quoted-numbers
1168 (save-excursion
1169 (let ((here (point))
1170 (bound (progn (skip-chars-forward "0-9a-fA-F'") (point))))
1171 (goto-char here)
1172 (when (< (skip-chars-backward "0-9a-fA-F'") 0)
1173 (if (and (memq (char-before) '(?x ?X))
1174 (eq (char-before (1- (point))) ?0))
1175 (backward-char 2))
1176 (while (and (search-forward-regexp c-maybe-quoted-number bound t)
1177 (<= (match-end 0) here)))
1178 (and (< (match-beginning 0) here)
1179 (> (match-end 0) here)
1180 (save-match-data
1181 (goto-char (match-beginning 0))
1182 (save-excursion (search-forward "'" (match-end 0) t)))))))))
1183
1184(defun c-parse-quotes-before-change (beg end)
1185 ;; This function analyzes 's near the region (c-new-BEG c-new-END), amending
1186 ;; those two variables as needed to include 's into that region when they
1187 ;; might be syntactically relevant to the change in progress.
1092 ;; 1188 ;;
1093 ;; In both uses of the function, the `syntax-table' properties are 1189 ;; Having amended that region, the function removes pertinent text
1094 ;; removed/applied only on quote marks which appear to be digit separators. 1190 ;; properties (syntax-table properties with value '(1) and c-digit-separator
1191 ;; props with value t) from 's in it. This operation is performed even
1192 ;; within strings and comments.
1095 ;; 1193 ;;
1096 ;; Point is undefined on both entry and exit to this function, and the 1194 ;; This function is called exclusively as a before-change function via the
1097 ;; return value has no significance. The function is called solely as a 1195 ;; variable `c-get-state-before-change-functions'.
1098 ;; before-change function (see `c-get-state-before-change-functions') and as 1196 (c-save-buffer-state (p-limit limits found)
1099 ;; an after change function (see `c-before-font-lock-functions', with the 1197 ;; Special consideraton for deleting \ from '\''.
1100 ;; parameters BEG, END, and (optionally) OLD-LEN being given the standard 1198 (if (and (> end beg)
1101 ;; values for before/after-change functions. 1199 (eq (char-before end) ?\\)
1102 (c-save-buffer-state ((num-begin c-new-BEG) digit-re try-end) 1200 (<= c-new-END end))
1201 (setq c-new-END (min (1+ end) (point-max))))
1202
1203 ;; Do we have a ' (or something like ',',',',',') within range of
1204 ;; c-new-BEG?
1205 (goto-char c-new-BEG)
1206 (setq p-limit (max (- (point) 2) (point-min)))
1207 (while (and (skip-chars-backward "^\\\\'" p-limit)
1208 (> (point) p-limit))
1209 (when (eq (char-before) ?\\)
1210 (setq p-limit (max (1- p-limit) (point-min))))
1211 (backward-char)
1212 (setq c-new-BEG (point)))
1213 (beginning-of-line)
1214 (while (and
1215 (setq found (search-forward-regexp "\\('\\([^'\\]\\|\\\\.\\)\\)*'"
1216 c-new-BEG 'limit))
1217 (< (point) (1- c-new-BEG))))
1218 (if found
1219 (setq c-new-BEG
1220 (if (and (eq (point) (1- c-new-BEG))
1221 (eq (char-after) ?')) ; "''" before c-new-BEG.
1222 (1- c-new-BEG)
1223 (match-beginning 0))))
1224
1225 ;; Check for a number with quote separators straddling c-new-BEG
1226 (when c-has-quoted-numbers
1227 (goto-char c-new-BEG)
1228 (when ;; (c-quoted-number-straddling-point)
1229 (c-quoted-number-head-before-point)
1230 (setq c-new-BEG (match-beginning 0))))
1231
1232 ;; Do we have a ' (or something like ',',',',...,',') within range of
1233 ;; c-new-END?
1103 (goto-char c-new-END) 1234 (goto-char c-new-END)
1104 (when (looking-at "\\(x\\)?[0-9a-fA-F']+") 1235 (setq p-limit (min (+ (point) 2) (point-max)))
1105 (setq c-new-END (match-end 0))) 1236 (while (and (skip-chars-forward "^\\\\'" p-limit)
1237 (< (point) p-limit))
1238 (when (eq (char-after) ?\\)
1239 (setq p-limit (min (1+ p-limit) (point-max))))
1240 (forward-char)
1241 (setq c-new-END (point)))
1242 (if (looking-at "[^']?\\('\\([^'\\]\\|\\\\.\\)\\)*'")
1243 (setq c-new-END (match-end 0)))
1244
1245 ;; Check for a number with quote separators straddling c-new-END.
1246 (when c-has-quoted-numbers
1247 (goto-char c-new-END)
1248 (when ;; (c-quoted-number-straddling-point)
1249 (c-quoted-number-tail-after-point)
1250 (setq c-new-END (match-end 0))))
1251
1252 ;; Remove the '(1) syntax-table property from all "'"s within (c-new-BEG
1253 ;; c-new-END).
1254 (c-clear-char-property-with-value-on-char
1255 c-new-BEG c-new-END
1256 'syntax-table '(1)
1257 ?')
1258 ;; Remove the c-digit-separator text property from the same "'"s.
1259 (when c-has-quoted-numbers
1260 (c-clear-char-property-with-value-on-char
1261 c-new-BEG c-new-END
1262 'c-digit-separator t
1263 ?'))))
1264
1265(defun c-parse-quotes-after-change (beg end old-len)
1266 ;; This function applies syntax-table properties (value '(1)) and
1267 ;; c-digit-separator properties as needed to 's within the range (c-new-BEG
1268 ;; c-new-END). This operation is performed even within strings and
1269 ;; comments.
1270 ;;
1271 ;; This function is called exclusively as an after-change function via the
1272 ;; variable `c-before-font-lock-functions'.
1273 (c-save-buffer-state (p-limit limits num-beg num-end clear-from-BEG-to)
1274 ;; Apply the needed syntax-table and c-digit-separator text properties to
1275 ;; quotes.
1106 (goto-char c-new-BEG) 1276 (goto-char c-new-BEG)
1107 (when (looking-at "\\(x?\\)[0-9a-fA-F']") 1277 (while (and (< (point) c-new-END)
1108 (if (re-search-backward "\\(0x\\)?[0-9a-fA-F]*\\=" nil t) 1278 (search-forward "'" c-new-END 'limit))
1109 (setq c-new-BEG (point)))) 1279 (cond ((and (eq (char-before (1- (point))) ?\\)
1110 1280 ;; Check we've got an odd number of \s, here.
1111 (while
1112 (re-search-forward "[0-9a-fA-F]'[0-9a-fA-F]" c-new-END t)
1113 (setq try-end (1- (point)))
1114 (re-search-backward "[^0-9a-fA-F']" num-begin t)
1115 (setq digit-re
1116 (cond
1117 ((and (not (bobp)) (eq (char-before) ?0) (memq (char-after) '(?x ?X)))
1118 "[0-9a-fA-F]")
1119 ((and (eq (char-after (1+ (point))) ?0)
1120 (memq (char-after (+ 2 (point))) '(?b ?B)))
1121 "[01]")
1122 ((memq (char-after (1+ (point))) '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
1123 "[0-9]")
1124 (t nil)))
1125 (when digit-re
1126 (cond ((eq (char-after) ?x) (forward-char))
1127 ((looking-at ".?0[Bb]") (goto-char (match-end 0)))
1128 ((looking-at digit-re))
1129 (t (forward-char)))
1130 (when (not (c-in-literal))
1131 (let ((num-end ; End of valid sequence of digits/quotes.
1132 (save-excursion
1133 (re-search-forward
1134 (concat "\\=\\(" digit-re "+'\\)*" digit-re "+") nil t)
1135 (point))))
1136 (setq try-end ; End of sequence of digits/quotes
1137 (save-excursion 1281 (save-excursion
1138 (re-search-forward 1282 (backward-char)
1139 (concat "\\=\\(" digit-re "\\|'\\)+") nil t) 1283 (eq (logand (skip-chars-backward "\\\\") 1) 1)))) ; not a real '.
1140 (point))) 1284 ((c-quoted-number-straddling-point)
1141 (while (re-search-forward 1285 (setq num-beg (match-beginning 0)
1142 (concat digit-re "\\('\\)" digit-re) num-end t) 1286 num-end (match-end 0))
1143 (if old-len ; i.e. are we in an after-change function? 1287 (c-put-char-properties-on-char num-beg num-end
1144 (c-put-char-property (match-beginning 1) 'syntax-table '(1)) 1288 'syntax-table '(1) ?')
1145 (c-clear-char-property (match-beginning 1) 'syntax-table)) 1289 (c-put-char-properties-on-char num-beg num-end
1146 (backward-char))))) 1290 'c-digit-separator t ?')
1147 (goto-char try-end) 1291 (goto-char num-end))
1148 (setq num-begin (point))))) 1292 ((looking-at "\\([^\\']\\|\\\\.\\)'") ; balanced quoted expression.
1149 1293 (goto-char (match-end 0)))
1150;; The following doesn't seem needed at the moment (2016-08-15). 1294 (t (c-put-char-property (1- (point)) 'syntax-table '(1)))))))
1151;; (defun c-before-after-change-extend-region-for-lambda-capture
1152;; (_beg _end &optional _old-len)
1153;; ;; In C++ Mode, extend the region (c-new-BEG c-new-END) to cover any lambda
1154;; ;; function capture lists we happen to be inside. This function is expected
1155;; ;; to be called both as a before-change and after change function.
1156;; ;;
1157;; ;; Note that these things _might_ be nested, with a capture list looking
1158;; ;; like:
1159;; ;;
1160;; ;; [ ...., &foo = [..](){...}(..), ... ]
1161;; ;;
1162;; ;; . What a wonderful language is C++. ;-)
1163;; (c-save-buffer-state (paren-state pos)
1164;; (goto-char c-new-BEG)
1165;; (setq paren-state (c-parse-state))
1166;; (while (setq pos (c-pull-open-brace paren-state))
1167;; (goto-char pos)
1168;; (when (c-looking-at-c++-lambda-capture-list)
1169;; (setq c-new-BEG (min c-new-BEG pos))
1170;; (if (c-go-list-forward)
1171;; (setq c-new-END (max c-new-END (point))))))
1172
1173;; (goto-char c-new-END)
1174;; (setq paren-state (c-parse-state))
1175;; (while (setq pos (c-pull-open-brace paren-state))
1176;; (goto-char pos)
1177;; (when (c-looking-at-c++-lambda-capture-list)
1178;; (setq c-new-BEG (min c-new-BEG pos))
1179;; (if (c-go-list-forward)
1180;; (setq c-new-END (max c-new-END (point))))))))
1181 1295
1182(defun c-before-change (beg end) 1296(defun c-before-change (beg end)
1183 ;; Function to be put on `before-change-functions'. Primarily, this calls 1297 ;; Function to be put on `before-change-functions'. Primarily, this calls