diff options
| author | Alan Mackenzie | 2016-06-27 11:34:02 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2016-06-27 11:34:02 +0000 |
| commit | 8040d99b6294ad798d4ab677ba20082b45fd2e7d (patch) | |
| tree | 9c53c471d718eb1a2028168705324ffa9501cac4 | |
| parent | 15c307417f7bc13b27f06994dd931cb04873a26f (diff) | |
| download | emacs-8040d99b6294ad798d4ab677ba20082b45fd2e7d.tar.gz emacs-8040d99b6294ad798d4ab677ba20082b45fd2e7d.zip | |
Amend a cache so that typing into C++ raw strings has no undue delay.
Also amend the code so that low-level searches to the end of literals are done
only when these positions get used.
* lisp/progmodes/cc-engine.el (c-crosses-statement-barrier-p): Use the new
c-literal-start instead of c-literal-limit.
(c-state-semi-nonlit-pos-cache): Change the structure of this cache, such that
it stores details of the literal at a point, rather than merely points outside
of literals.
(c-state-semi-pp-to-literal, c-state-full-pp-to-literal)
(c-cache-to-parse-ps-state, c-parse-ps-state-to-cache, c-ps-state-cache-pos)
(c-parse-ps-state-below, c-literal-start): New functions.
(c-state-semi-safe-place): Removed.
(c-in-literal): Use c-state-semi-pp-to-literal, so as not to scan to its end.
(c-literal-limits, c-determine-limit-get-base): consequential amendments.
(c-find-decl-spots, c-before-change-check-<>-operators, c-raw-string-pos)
(c-guess-basic-syntax (CASE 2)): Avoid needless scans to end of literals.
* lisp/progmodes/cc-fonts.el (c-font-lock-doc-comments): Avoid needless scans
to end of literals.
* lisp/progmodes/cc-mode.el (c-fl-decl-start): Avoid needless scans to end of
literals.
* lisp/progmodes/cc-cmds.el (c-beginning-of-defun, c-end-of-defun)
(c-defun-name, c-declaration-limits): Avoid needless scans to end of literals.
| -rw-r--r-- | lisp/progmodes/cc-cmds.el | 188 | ||||
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 312 | ||||
| -rw-r--r-- | lisp/progmodes/cc-fonts.el | 6 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 6 |
4 files changed, 338 insertions, 174 deletions
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 59f2729c43d..f0ad2942457 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el | |||
| @@ -1610,8 +1610,8 @@ defun." | |||
| 1610 | 1610 | ||
| 1611 | ;; Move back out of any macro/comment/string we happen to be in. | 1611 | ;; Move back out of any macro/comment/string we happen to be in. |
| 1612 | (c-beginning-of-macro) | 1612 | (c-beginning-of-macro) |
| 1613 | (setq pos (c-literal-limits)) | 1613 | (setq pos (c-literal-start)) |
| 1614 | (if pos (goto-char (car pos))) | 1614 | (if pos (goto-char pos)) |
| 1615 | 1615 | ||
| 1616 | (setq where (c-where-wrt-brace-construct)) | 1616 | (setq where (c-where-wrt-brace-construct)) |
| 1617 | 1617 | ||
| @@ -1734,8 +1734,8 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'." | |||
| 1734 | 1734 | ||
| 1735 | ;; Move back out of any macro/comment/string we happen to be in. | 1735 | ;; Move back out of any macro/comment/string we happen to be in. |
| 1736 | (c-beginning-of-macro) | 1736 | (c-beginning-of-macro) |
| 1737 | (setq pos (c-literal-limits)) | 1737 | (setq pos (c-literal-start)) |
| 1738 | (if pos (goto-char (car pos))) | 1738 | (if pos (goto-char pos)) |
| 1739 | 1739 | ||
| 1740 | (setq where (c-where-wrt-brace-construct)) | 1740 | (setq where (c-where-wrt-brace-construct)) |
| 1741 | 1741 | ||
| @@ -1793,8 +1793,8 @@ with a brace block." | |||
| 1793 | (save-excursion | 1793 | (save-excursion |
| 1794 | ;; Move back out of any macro/comment/string we happen to be in. | 1794 | ;; Move back out of any macro/comment/string we happen to be in. |
| 1795 | (c-beginning-of-macro) | 1795 | (c-beginning-of-macro) |
| 1796 | (setq pos (c-literal-limits)) | 1796 | (setq pos (c-literal-start)) |
| 1797 | (if pos (goto-char (car pos))) | 1797 | (if pos (goto-char pos)) |
| 1798 | 1798 | ||
| 1799 | (setq where (c-where-wrt-brace-construct)) | 1799 | (setq where (c-where-wrt-brace-construct)) |
| 1800 | 1800 | ||
| @@ -1880,103 +1880,103 @@ with a brace block." | |||
| 1880 | (or (save-restriction | 1880 | (or (save-restriction |
| 1881 | (c-narrow-to-most-enclosing-decl-block nil) | 1881 | (c-narrow-to-most-enclosing-decl-block nil) |
| 1882 | 1882 | ||
| 1883 | ;; Note: Some code duplication in `c-beginning-of-defun' and | 1883 | ;; Note: Some code duplication in `c-beginning-of-defun' and |
| 1884 | ;; `c-end-of-defun'. | 1884 | ;; `c-end-of-defun'. |
| 1885 | (catch 'exit | 1885 | (catch 'exit |
| 1886 | (let ((start (point)) | 1886 | (let ((start (point)) |
| 1887 | (paren-state (c-parse-state)) | 1887 | (paren-state (c-parse-state)) |
| 1888 | lim pos end-pos) | 1888 | lim pos end-pos) |
| 1889 | (unless (c-safe | 1889 | (unless (c-safe |
| 1890 | (goto-char (c-least-enclosing-brace paren-state)) | 1890 | (goto-char (c-least-enclosing-brace paren-state)) |
| 1891 | ;; If we moved to the outermost enclosing paren | 1891 | ;; If we moved to the outermost enclosing paren |
| 1892 | ;; then we can use c-safe-position to set the | 1892 | ;; then we can use c-safe-position to set the |
| 1893 | ;; limit. Can't do that otherwise since the | 1893 | ;; limit. Can't do that otherwise since the |
| 1894 | ;; earlier paren pair on paren-state might very | 1894 | ;; earlier paren pair on paren-state might very |
| 1895 | ;; well be part of the declaration we should go | 1895 | ;; well be part of the declaration we should go |
| 1896 | ;; to. | 1896 | ;; to. |
| 1897 | (setq lim (c-safe-position (point) paren-state)) | 1897 | (setq lim (c-safe-position (point) paren-state)) |
| 1898 | t) | 1898 | t) |
| 1899 | ;; At top level. Make sure we aren't inside a literal. | 1899 | ;; At top level. Make sure we aren't inside a literal. |
| 1900 | (setq pos (c-literal-limits | 1900 | (setq pos (c-literal-start |
| 1901 | (c-safe-position (point) paren-state))) | 1901 | (c-safe-position (point) paren-state))) |
| 1902 | (if pos (goto-char (car pos)))) | 1902 | (if pos (goto-char pos))) |
| 1903 | 1903 | ||
| 1904 | (when (c-beginning-of-macro) | 1904 | (when (c-beginning-of-macro) |
| 1905 | (throw 'exit | 1905 | (throw 'exit |
| 1906 | (cons (point) | 1906 | (cons (point) |
| 1907 | (save-excursion | 1907 | (save-excursion |
| 1908 | (c-end-of-macro) | 1908 | (c-end-of-macro) |
| 1909 | (forward-line 1) | 1909 | (forward-line 1) |
| 1910 | (point))))) | 1910 | (point))))) |
| 1911 | 1911 | ||
| 1912 | (setq pos (point)) | ||
| 1913 | (when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous) | ||
| 1914 | (= pos (point))) | ||
| 1915 | ;; We moved back over the previous defun. Skip to the next | ||
| 1916 | ;; one. Not using c-forward-syntactic-ws here since we | ||
| 1917 | ;; should not skip a macro. We can also be directly after | ||
| 1918 | ;; the block in a `c-opt-block-decls-with-vars-key' | ||
| 1919 | ;; declaration, but then we won't move significantly far | ||
| 1920 | ;; here. | ||
| 1921 | (goto-char pos) | ||
| 1922 | (c-forward-comments) | ||
| 1923 | |||
| 1924 | (when (and near (c-beginning-of-macro)) | ||
| 1925 | (throw 'exit | ||
| 1926 | (cons (point) | ||
| 1927 | (save-excursion | ||
| 1928 | (c-end-of-macro) | ||
| 1929 | (forward-line 1) | ||
| 1930 | (point)))))) | ||
| 1931 | |||
| 1932 | (if (eobp) (throw 'exit nil)) | ||
| 1933 | |||
| 1934 | ;; Check if `c-beginning-of-decl-1' put us after the block in a | ||
| 1935 | ;; declaration that doesn't end there. We're searching back and | ||
| 1936 | ;; forth over the block here, which can be expensive. | ||
| 1937 | (setq pos (point)) | ||
| 1938 | (if (and c-opt-block-decls-with-vars-key | ||
| 1939 | (progn | ||
| 1940 | (c-backward-syntactic-ws) | ||
| 1941 | (eq (char-before) ?})) | ||
| 1942 | (eq (car (c-beginning-of-decl-1)) | ||
| 1943 | 'previous) | ||
| 1944 | (save-excursion | ||
| 1945 | (c-end-of-decl-1) | ||
| 1946 | (and (> (point) pos) | ||
| 1947 | (setq end-pos (point))))) | ||
| 1948 | nil | ||
| 1949 | (goto-char pos)) | ||
| 1950 | |||
| 1951 | (if (and (not near) (> (point) start)) | ||
| 1952 | nil | ||
| 1953 | |||
| 1954 | ;; Try to be line oriented; position the limits at the | ||
| 1955 | ;; closest preceding boi, and after the next newline, that | ||
| 1956 | ;; isn't inside a comment, but if we hit a neighboring | ||
| 1957 | ;; declaration then we instead use the exact declaration | ||
| 1958 | ;; limit in that direction. | ||
| 1959 | (cons (progn | ||
| 1960 | (setq pos (point)) | 1912 | (setq pos (point)) |
| 1961 | (while (and (/= (point) (c-point 'boi)) | 1913 | (when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous) |
| 1962 | (c-backward-single-comment))) | 1914 | (= pos (point))) |
| 1963 | (if (/= (point) (c-point 'boi)) | 1915 | ;; We moved back over the previous defun. Skip to the next |
| 1964 | pos | 1916 | ;; one. Not using c-forward-syntactic-ws here since we |
| 1965 | (point))) | 1917 | ;; should not skip a macro. We can also be directly after |
| 1966 | (progn | 1918 | ;; the block in a `c-opt-block-decls-with-vars-key' |
| 1967 | (if end-pos | 1919 | ;; declaration, but then we won't move significantly far |
| 1968 | (goto-char end-pos) | 1920 | ;; here. |
| 1969 | (c-end-of-decl-1)) | 1921 | (goto-char pos) |
| 1922 | (c-forward-comments) | ||
| 1923 | |||
| 1924 | (when (and near (c-beginning-of-macro)) | ||
| 1925 | (throw 'exit | ||
| 1926 | (cons (point) | ||
| 1927 | (save-excursion | ||
| 1928 | (c-end-of-macro) | ||
| 1929 | (forward-line 1) | ||
| 1930 | (point)))))) | ||
| 1931 | |||
| 1932 | (if (eobp) (throw 'exit nil)) | ||
| 1933 | |||
| 1934 | ;; Check if `c-beginning-of-decl-1' put us after the block in a | ||
| 1935 | ;; declaration that doesn't end there. We're searching back and | ||
| 1936 | ;; forth over the block here, which can be expensive. | ||
| 1970 | (setq pos (point)) | 1937 | (setq pos (point)) |
| 1971 | (while (and (not (bolp)) | 1938 | (if (and c-opt-block-decls-with-vars-key |
| 1972 | (not (looking-at "\\s *$")) | 1939 | (progn |
| 1973 | (c-forward-single-comment))) | 1940 | (c-backward-syntactic-ws) |
| 1974 | (cond ((bolp) | 1941 | (eq (char-before) ?})) |
| 1975 | (point)) | 1942 | (eq (car (c-beginning-of-decl-1)) |
| 1976 | ((looking-at "\\s *$") | 1943 | 'previous) |
| 1977 | (forward-line 1) | 1944 | (save-excursion |
| 1978 | (point)) | 1945 | (c-end-of-decl-1) |
| 1979 | (t | 1946 | (and (> (point) pos) |
| 1947 | (setq end-pos (point))))) | ||
| 1948 | nil | ||
| 1949 | (goto-char pos)) | ||
| 1950 | |||
| 1951 | (if (and (not near) (> (point) start)) | ||
| 1952 | nil | ||
| 1953 | |||
| 1954 | ;; Try to be line oriented; position the limits at the | ||
| 1955 | ;; closest preceding boi, and after the next newline, that | ||
| 1956 | ;; isn't inside a comment, but if we hit a neighboring | ||
| 1957 | ;; declaration then we instead use the exact declaration | ||
| 1958 | ;; limit in that direction. | ||
| 1959 | (cons (progn | ||
| 1960 | (setq pos (point)) | ||
| 1961 | (while (and (/= (point) (c-point 'boi)) | ||
| 1962 | (c-backward-single-comment))) | ||
| 1963 | (if (/= (point) (c-point 'boi)) | ||
| 1964 | pos | ||
| 1965 | (point))) | ||
| 1966 | (progn | ||
| 1967 | (if end-pos | ||
| 1968 | (goto-char end-pos) | ||
| 1969 | (c-end-of-decl-1)) | ||
| 1970 | (setq pos (point)) | ||
| 1971 | (while (and (not (bolp)) | ||
| 1972 | (not (looking-at "\\s *$")) | ||
| 1973 | (c-forward-single-comment))) | ||
| 1974 | (cond ((bolp) | ||
| 1975 | (point)) | ||
| 1976 | ((looking-at "\\s *$") | ||
| 1977 | (forward-line 1) | ||
| 1978 | (point)) | ||
| 1979 | (t | ||
| 1980 | pos)))))))) | 1980 | pos)))))))) |
| 1981 | (and (not near) | 1981 | (and (not near) |
| 1982 | (goto-char (point-min)) | 1982 | (goto-char (point-min)) |
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 17415a259b6..4bc4056081b 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -1300,7 +1300,7 @@ comment at the start of cc-engine.el for more info." | |||
| 1300 | c-stmt-delim-chars)) | 1300 | c-stmt-delim-chars)) |
| 1301 | (non-skip-list | 1301 | (non-skip-list |
| 1302 | (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:) | 1302 | (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:) |
| 1303 | lit-range vsemi-pos) | 1303 | lit-range lit-start vsemi-pos) |
| 1304 | (save-restriction | 1304 | (save-restriction |
| 1305 | (widen) | 1305 | (widen) |
| 1306 | (save-excursion | 1306 | (save-excursion |
| @@ -1315,8 +1315,8 @@ comment at the start of cc-engine.el for more info." | |||
| 1315 | ((and (bolp) | 1315 | ((and (bolp) |
| 1316 | (save-excursion | 1316 | (save-excursion |
| 1317 | (progn | 1317 | (progn |
| 1318 | (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment? | 1318 | (if (setq lit-start (c-literal-start from)) ; Have we landed in a string/comment? |
| 1319 | (goto-char (car lit-range))) | 1319 | (goto-char lit-start)) |
| 1320 | (c-backward-syntactic-ws) ; ? put a limit here, maybe? | 1320 | (c-backward-syntactic-ws) ; ? put a limit here, maybe? |
| 1321 | (setq vsemi-pos (point)) | 1321 | (setq vsemi-pos (point)) |
| 1322 | (c-at-vsemi-p)))) | 1322 | (c-at-vsemi-p)))) |
| @@ -2279,15 +2279,110 @@ comment at the start of cc-engine.el for more info." | |||
| 2279 | 2279 | ||
| 2280 | (defvar c-state-semi-nonlit-pos-cache nil) | 2280 | (defvar c-state-semi-nonlit-pos-cache nil) |
| 2281 | (make-variable-buffer-local 'c-state-semi-nonlit-pos-cache) | 2281 | (make-variable-buffer-local 'c-state-semi-nonlit-pos-cache) |
| 2282 | ;; A list of buffer positions which are known not to be in a literal. This is | 2282 | ;; A list of elements which are either buffer positions (when such positions |
| 2283 | ;; ordered with higher positions at the front of the list. Only those which | 2283 | ;; are not in literals) or lists of the form (POS TYPE START), where POS is |
| 2284 | ;; are less than `c-state-semi-nonlit-pos-cache-limit' are valid. | 2284 | ;; a buffer position inside a literal, TYPE is the type of the literal |
| 2285 | ;; ('string, 'c, or 'c++) and START is the start of the literal. | ||
| 2285 | 2286 | ||
| 2286 | (defvar c-state-semi-nonlit-pos-cache-limit 1) | 2287 | (defvar c-state-semi-nonlit-pos-cache-limit 1) |
| 2287 | (make-variable-buffer-local 'c-state-semi-nonlit-pos-cache-limit) | 2288 | (make-variable-buffer-local 'c-state-semi-nonlit-pos-cache-limit) |
| 2288 | ;; An upper limit on valid entries in `c-state-semi-nonlit-pos-cache'. This is | 2289 | ;; An upper limit on valid entries in `c-state-semi-nonlit-pos-cache'. This |
| 2289 | ;; reduced by buffer changes, and increased by invocations of | 2290 | ;; is reduced by buffer changes, and increased by invocations of |
| 2290 | ;; `c-state-literal-at'. FIXME!!! | 2291 | ;; `c-parse-ps-state-below'. |
| 2292 | |||
| 2293 | (defun c-state-semi-pp-to-literal (here &optional not-in-delimiter) | ||
| 2294 | ;; Do a parse-partial-sexp from a position in the buffer before HERE which | ||
| 2295 | ;; isn't in a literal, and return information about HERE, either: | ||
| 2296 | ;; (STATE TYPE BEG) if HERE is in a literal; or | ||
| 2297 | ;; (STATE) otherwise, | ||
| 2298 | ;; where STATE is the parsing state at HERE, TYPE is the type of the literal | ||
| 2299 | ;; enclosing HERE, (one of 'string, 'c, 'c++) and BEG is the starting | ||
| 2300 | ;; position of that literal (including the delimiter). | ||
| 2301 | ;; | ||
| 2302 | ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character | ||
| 2303 | ;; comment opener, this is recognized as being in a comment literal. | ||
| 2304 | ;; | ||
| 2305 | ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote), 7 | ||
| 2306 | ;; (comment type), and 8 (start of comment/string), and possibly 10 (in | ||
| 2307 | ;; newer Emacsen only, the syntax of a position after a potential first char | ||
| 2308 | ;; of a two char construct) of STATE are valid. | ||
| 2309 | (save-excursion | ||
| 2310 | (save-match-data | ||
| 2311 | (let* ((base-and-state (c-parse-ps-state-below here)) | ||
| 2312 | (base (car base-and-state)) | ||
| 2313 | (s (cdr base-and-state)) | ||
| 2314 | (s (parse-partial-sexp base here nil nil s)) | ||
| 2315 | ty) | ||
| 2316 | (cond | ||
| 2317 | ((or (nth 3 s) (nth 4 s)) ; in a string or comment | ||
| 2318 | (setq ty (cond | ||
| 2319 | ((nth 3 s) 'string) | ||
| 2320 | ((nth 7 s) 'c++) | ||
| 2321 | (t 'c))) | ||
| 2322 | (list s ty (nth 8 s))) | ||
| 2323 | |||
| 2324 | ((and (not not-in-delimiter) ; inside a comment starter | ||
| 2325 | (not (bobp)) | ||
| 2326 | (progn (backward-char) | ||
| 2327 | (and (not (and (memq 'category-properties c-emacs-features) | ||
| 2328 | (looking-at "\\s!"))) | ||
| 2329 | (looking-at c-comment-start-regexp)))) | ||
| 2330 | (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)) | ||
| 2331 | (list s ty (point))) | ||
| 2332 | |||
| 2333 | (t (list s))))))) | ||
| 2334 | |||
| 2335 | (defun c-state-full-pp-to-literal (here &optional not-in-delimiter) | ||
| 2336 | ;; This function will supersede c-state-pp-to-literal. | ||
| 2337 | ;; | ||
| 2338 | ;; Do a parse-partial-sexp from a position in the buffer before HERE which | ||
| 2339 | ;; isn't in a literal, and return information about HERE, either: | ||
| 2340 | ;; (STATE TYPE (BEG . END)) if HERE is in a literal; or | ||
| 2341 | ;; (STATE) otherwise, | ||
| 2342 | ;; where STATE is the parsing state at HERE, TYPE is the type of the literal | ||
| 2343 | ;; enclosing HERE, (one of 'string, 'c, 'c++) and (BEG . END) is the | ||
| 2344 | ;; boundaries of that literal (including the delimiters). | ||
| 2345 | ;; | ||
| 2346 | ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character | ||
| 2347 | ;; comment opener, this is recognized as being in a comment literal. | ||
| 2348 | ;; | ||
| 2349 | ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote), 7 | ||
| 2350 | ;; (comment type), and 8 (start of comment/string), and possibly 10 (in | ||
| 2351 | ;; newer Emacsen only, the syntax of a position after a potential first char | ||
| 2352 | ;; of a two char construct) of STATE are valid. | ||
| 2353 | (save-excursion | ||
| 2354 | (save-match-data | ||
| 2355 | (let* ((base-and-state (c-parse-ps-state-below here)) | ||
| 2356 | (base (car base-and-state)) | ||
| 2357 | (s (cdr base-and-state)) | ||
| 2358 | (s (parse-partial-sexp base here nil nil s)) | ||
| 2359 | ty start) | ||
| 2360 | (cond | ||
| 2361 | ((or (nth 3 s) (nth 4 s)) ; in a string or comment | ||
| 2362 | (setq ty (cond | ||
| 2363 | ((nth 3 s) 'string) | ||
| 2364 | ((nth 7 s) 'c++) | ||
| 2365 | (t 'c))) | ||
| 2366 | (setq start (nth 8 s)) | ||
| 2367 | (parse-partial-sexp here (point-max) | ||
| 2368 | nil ; TARGETDEPTH | ||
| 2369 | nil ; STOPBEFORE | ||
| 2370 | s ; OLDSTATE | ||
| 2371 | 'syntax-table) ; stop at end of literal | ||
| 2372 | (list s ty (cons start (point)))) | ||
| 2373 | |||
| 2374 | ((and (not not-in-delimiter) ; inside a comment starter | ||
| 2375 | (not (bobp)) | ||
| 2376 | (progn (backward-char) | ||
| 2377 | (and (not (and (memq 'category-properties c-emacs-features) | ||
| 2378 | (looking-at "\\s!"))) | ||
| 2379 | (looking-at c-comment-start-regexp)))) | ||
| 2380 | (setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++) | ||
| 2381 | start (point)) | ||
| 2382 | (forward-comment 1) | ||
| 2383 | (list s ty (cons start (point)))) | ||
| 2384 | |||
| 2385 | (t (list s))))))) | ||
| 2291 | 2386 | ||
| 2292 | (defsubst c-state-pp-to-literal (from to &optional not-in-delimiter) | 2387 | (defsubst c-state-pp-to-literal (from to &optional not-in-delimiter) |
| 2293 | ;; Do a parse-partial-sexp from FROM to TO, returning either | 2388 | ;; Do a parse-partial-sexp from FROM to TO, returning either |
| @@ -2332,6 +2427,103 @@ comment at the start of cc-engine.el for more info." | |||
| 2332 | 2427 | ||
| 2333 | (t `(,s))))))) | 2428 | (t `(,s))))))) |
| 2334 | 2429 | ||
| 2430 | (defun c-cache-to-parse-ps-state (elt) | ||
| 2431 | ;; Create a list suitable to use as the old-state parameter to | ||
| 2432 | ;; `parse-partial-sexp', out of ELT. ELT is either just a number, a buffer | ||
| 2433 | ;; position, or it is a list (POS TYPE STARTING-POS). Here POS is the | ||
| 2434 | ;; buffer position the other elements are pertinent for, TYPE is either 'c | ||
| 2435 | ;; or 'c++ (for a comment) or a character (for a string delimiter) or t | ||
| 2436 | ;; (meaning a string fence opened the string), STARTING-POS is the starting | ||
| 2437 | ;; position of the comment or string. | ||
| 2438 | (if (consp elt) | ||
| 2439 | (let ((depth 0) (containing nil) (last nil) | ||
| 2440 | in-string in-comment (after-quote nil) | ||
| 2441 | (min-depth 0) com-style com-str-start (intermediate nil) | ||
| 2442 | (between-syntax nil) | ||
| 2443 | (type (cadr elt))) | ||
| 2444 | (setq com-str-start (car (cddr elt))) | ||
| 2445 | (cond | ||
| 2446 | ((or (numberp type) (eq type t)) ; A string | ||
| 2447 | (setq in-string type)) | ||
| 2448 | ((memq type '(c c++)) ; A comment | ||
| 2449 | (setq in-comment t | ||
| 2450 | com-style (if (eq type 'c++) 1 nil))) | ||
| 2451 | (t (c-benign-error "Invalid type %s in c-cache-to-parse-ps-state" | ||
| 2452 | elt))) | ||
| 2453 | (list depth containing last | ||
| 2454 | in-string in-comment after-quote | ||
| 2455 | min-depth com-style com-str-start | ||
| 2456 | intermediate nil)) | ||
| 2457 | (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil)))) | ||
| 2458 | |||
| 2459 | (defun c-parse-ps-state-to-cache (state) | ||
| 2460 | ;; Convert STATE, a `parse-partial-sexp' state valid at POINT, to an element | ||
| 2461 | ;; for the `c-state-semi-nonlit-pos-cache' cache. This is either POINT | ||
| 2462 | ;; (when point is not in a literal) or a list (POINT TYPE STARTING-POS), | ||
| 2463 | ;; where TYPE is the type of the literal, either 'string, 'c, or 'c++, and | ||
| 2464 | ;; STARTING-POS is the starting position of the comment or string. | ||
| 2465 | (cond | ||
| 2466 | ((nth 3 state) ; A string | ||
| 2467 | (list (point) (nth 3 state) (nth 8 state))) | ||
| 2468 | ((nth 4 state) ; A comment | ||
| 2469 | (list (point) | ||
| 2470 | (if (eq (nth 7 state) 1) 'c++ 'c) | ||
| 2471 | (nth 8 state))) | ||
| 2472 | (t ; Neither string nor comment. | ||
| 2473 | (point)))) | ||
| 2474 | |||
| 2475 | (defsubst c-ps-state-cache-pos (elt) | ||
| 2476 | ;; Get the buffer position from ELT, an element from the cache | ||
| 2477 | ;; `c-state-semi-nonlit-pos-cache'. | ||
| 2478 | (if (atom elt) | ||
| 2479 | elt | ||
| 2480 | (car elt))) | ||
| 2481 | |||
| 2482 | (defun c-parse-ps-state-below (here) | ||
| 2483 | ;; Given a buffer position HERE, Return a cons (CACHE-POS . STATE), where | ||
| 2484 | ;; CACHE-POS is a position not very far before HERE for which the | ||
| 2485 | ;; parse-partial-sexp STATE is valid. Note that the only valid elements of | ||
| 2486 | ;; STATE are those concerning comments and strings; STATE is the state of a | ||
| 2487 | ;; null `parse-partial-sexp' scan when CACHE-POS is not in a comment or | ||
| 2488 | ;; string. | ||
| 2489 | (save-restriction | ||
| 2490 | (widen) | ||
| 2491 | (save-excursion | ||
| 2492 | (let ((c c-state-semi-nonlit-pos-cache) | ||
| 2493 | elt state pos npos high-elt) | ||
| 2494 | ;; Trim the cache to take account of buffer changes. | ||
| 2495 | (while (and c (> (c-ps-state-cache-pos (c-ps-state-cache-pos (car c))) | ||
| 2496 | c-state-semi-nonlit-pos-cache-limit)) | ||
| 2497 | (setq c (cdr c))) | ||
| 2498 | (setq c-state-semi-nonlit-pos-cache c) | ||
| 2499 | |||
| 2500 | (while (and c (> (c-ps-state-cache-pos (car c)) here)) | ||
| 2501 | (setq high-elt (car c)) | ||
| 2502 | (setq c (cdr c))) | ||
| 2503 | (setq pos (or (and c (c-ps-state-cache-pos (car c))) | ||
| 2504 | (point-min))) | ||
| 2505 | |||
| 2506 | (if high-elt | ||
| 2507 | (setq state (c-cache-to-parse-ps-state (car c))) | ||
| 2508 | (setq elt (if c (car c) (point-min))) | ||
| 2509 | (setq state | ||
| 2510 | (if c | ||
| 2511 | (c-cache-to-parse-ps-state (car c)) | ||
| 2512 | (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil)))) | ||
| 2513 | (while | ||
| 2514 | ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration. | ||
| 2515 | (<= (setq npos (+ pos c-state-nonlit-pos-interval)) here) | ||
| 2516 | (setq state (parse-partial-sexp pos npos nil nil state)) | ||
| 2517 | (setq elt (c-parse-ps-state-to-cache state)) | ||
| 2518 | (setq c-state-semi-nonlit-pos-cache | ||
| 2519 | (cons elt c-state-semi-nonlit-pos-cache)) | ||
| 2520 | (setq pos npos))) | ||
| 2521 | |||
| 2522 | (if (> pos c-state-semi-nonlit-pos-cache-limit) | ||
| 2523 | (setq c-state-semi-nonlit-pos-cache-limit pos)) | ||
| 2524 | |||
| 2525 | (cons pos state))))) | ||
| 2526 | |||
| 2335 | (defun c-state-safe-place (here) | 2527 | (defun c-state-safe-place (here) |
| 2336 | ;; Return a buffer position before HERE which is "safe", i.e. outside any | 2528 | ;; Return a buffer position before HERE which is "safe", i.e. outside any |
| 2337 | ;; string, comment, or macro. | 2529 | ;; string, comment, or macro. |
| @@ -2397,45 +2589,6 @@ comment at the start of cc-engine.el for more info." | |||
| 2397 | (setq c-state-nonlit-pos-cache-limit pos)) | 2589 | (setq c-state-nonlit-pos-cache-limit pos)) |
| 2398 | pos)))) | 2590 | pos)))) |
| 2399 | 2591 | ||
| 2400 | (defun c-state-semi-safe-place (here) | ||
| 2401 | ;; Return a buffer position before HERE which is "safe", i.e. outside any | ||
| 2402 | ;; string or comment. It may be in a macro. | ||
| 2403 | (save-restriction | ||
| 2404 | (widen) | ||
| 2405 | (save-excursion | ||
| 2406 | (let ((c c-state-semi-nonlit-pos-cache) | ||
| 2407 | pos npos high-pos lit macro-beg macro-end) | ||
| 2408 | ;; Trim the cache to take account of buffer changes. | ||
| 2409 | (while (and c (> (car c) c-state-semi-nonlit-pos-cache-limit)) | ||
| 2410 | (setq c (cdr c))) | ||
| 2411 | (setq c-state-semi-nonlit-pos-cache c) | ||
| 2412 | |||
| 2413 | (while (and c (> (car c) here)) | ||
| 2414 | (setq high-pos (car c)) | ||
| 2415 | (setq c (cdr c))) | ||
| 2416 | (setq pos (or (car c) (point-min))) | ||
| 2417 | |||
| 2418 | (unless high-pos | ||
| 2419 | (while | ||
| 2420 | ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration. | ||
| 2421 | (and | ||
| 2422 | (<= (setq npos (+ pos c-state-nonlit-pos-interval)) here) | ||
| 2423 | |||
| 2424 | ;; Test for being in a literal. If so, go to after it. | ||
| 2425 | (progn | ||
| 2426 | (setq lit (car (cddr (c-state-pp-to-literal pos npos)))) | ||
| 2427 | (or (null lit) | ||
| 2428 | (prog1 (<= (cdr lit) here) | ||
| 2429 | (setq npos (cdr lit)))))) | ||
| 2430 | |||
| 2431 | (setq pos npos) | ||
| 2432 | (setq c-state-semi-nonlit-pos-cache | ||
| 2433 | (cons pos c-state-semi-nonlit-pos-cache)))) | ||
| 2434 | |||
| 2435 | (if (> pos c-state-semi-nonlit-pos-cache-limit) | ||
| 2436 | (setq c-state-semi-nonlit-pos-cache-limit pos)) | ||
| 2437 | pos)))) | ||
| 2438 | |||
| 2439 | (defun c-state-literal-at (here) | 2592 | (defun c-state-literal-at (here) |
| 2440 | ;; If position HERE is inside a literal, return (START . END), the | 2593 | ;; If position HERE is inside a literal, return (START . END), the |
| 2441 | ;; boundaries of the literal (which may be outside the accessible bit of the | 2594 | ;; boundaries of the literal (which may be outside the accessible bit of the |
| @@ -4633,8 +4786,7 @@ Note that this function might do hidden buffer changes. See the | |||
| 4633 | comment at the start of cc-engine.el for more info." | 4786 | comment at the start of cc-engine.el for more info." |
| 4634 | (save-restriction | 4787 | (save-restriction |
| 4635 | (widen) | 4788 | (widen) |
| 4636 | (let* ((safe-place (c-state-semi-safe-place (point))) | 4789 | (let ((lit (c-state-semi-pp-to-literal (point)))) |
| 4637 | (lit (c-state-pp-to-literal safe-place (point)))) | ||
| 4638 | (or (cadr lit) | 4790 | (or (cadr lit) |
| 4639 | (and detect-cpp | 4791 | (and detect-cpp |
| 4640 | (save-excursion (c-beginning-of-macro)) | 4792 | (save-excursion (c-beginning-of-macro)) |
| @@ -4656,14 +4808,19 @@ Note that this function might do hidden buffer changes. See the | |||
| 4656 | comment at the start of cc-engine.el for more info." | 4808 | comment at the start of cc-engine.el for more info." |
| 4657 | 4809 | ||
| 4658 | (save-excursion | 4810 | (save-excursion |
| 4659 | (let* ((pos (point)) | 4811 | (let* |
| 4660 | (lim (or lim (c-state-semi-safe-place pos))) | 4812 | ((pos (point)) |
| 4661 | (pp-to-lit (save-restriction | 4813 | (lit-limits |
| 4662 | (widen) | 4814 | (if lim |
| 4663 | (c-state-pp-to-literal lim pos not-in-delimiter))) | 4815 | (let ((s (parse-partial-sexp lim (point)))) |
| 4664 | (state (car pp-to-lit)) | 4816 | (when (or (nth 3 s) (nth 4 s)) |
| 4665 | (lit-limits (car (cddr pp-to-lit)))) | 4817 | (cons (nth 8 s) |
| 4666 | 4818 | (progn (parse-partial-sexp (point) (point-max) | |
| 4819 | nil 'syntax-table | ||
| 4820 | s) | ||
| 4821 | (point))))) | ||
| 4822 | (let ((pp-to-lit (c-state-full-pp-to-literal pos not-in-delimiter))) | ||
| 4823 | (car (cddr pp-to-lit)))))) | ||
| 4667 | (cond | 4824 | (cond |
| 4668 | (lit-limits) | 4825 | (lit-limits) |
| 4669 | 4826 | ||
| @@ -4702,6 +4859,16 @@ comment at the start of cc-engine.el for more info." | |||
| 4702 | (if beg (cons beg end)))))) | 4859 | (if beg (cons beg end)))))) |
| 4703 | )))) | 4860 | )))) |
| 4704 | 4861 | ||
| 4862 | (defun c-literal-start (&optional safe-pos) | ||
| 4863 | "Return the start of the string or comment surrounding point, or nil if | ||
| 4864 | point isn't in one. SAFE-POS, if non-nil, is a position before point which is | ||
| 4865 | a known \"safe position\", i.e. outside of any string or comment." | ||
| 4866 | (if safe-pos | ||
| 4867 | (let ((s (parse-partial-sexp safe-pos (point)))) | ||
| 4868 | (and (or (nth 3 s) (nth 4 s)) | ||
| 4869 | (nth 8 s))) | ||
| 4870 | (car (cddr (c-state-semi-pp-to-literal (point)))))) | ||
| 4871 | |||
| 4705 | ;; In case external callers use this; it did have a docstring. | 4872 | ;; In case external callers use this; it did have a docstring. |
| 4706 | (defalias 'c-literal-limits-fast 'c-literal-limits) | 4873 | (defalias 'c-literal-limits-fast 'c-literal-limits) |
| 4707 | 4874 | ||
| @@ -4766,13 +4933,10 @@ comment at the start of cc-engine.el for more info." | |||
| 4766 | 4933 | ||
| 4767 | (defsubst c-determine-limit-get-base (start try-size) | 4934 | (defsubst c-determine-limit-get-base (start try-size) |
| 4768 | ;; Get a "safe place" approximately TRY-SIZE characters before START. | 4935 | ;; Get a "safe place" approximately TRY-SIZE characters before START. |
| 4769 | ;; This doesn't preserve point. | 4936 | ;; This defsubst doesn't preserve point. |
| 4770 | (let* ((pos (max (- start try-size) (point-min))) | 4937 | (let* ((pos (max (- start try-size) (point-min))) |
| 4771 | (base (c-state-semi-safe-place pos)) | 4938 | (s (c-state-semi-pp-to-literal pos))) |
| 4772 | (s (parse-partial-sexp base pos))) | 4939 | (or (car (cddr s)) pos))) |
| 4773 | (if (or (nth 4 s) (nth 3 s)) ; comment or string | ||
| 4774 | (nth 8 s) | ||
| 4775 | (point)))) | ||
| 4776 | 4940 | ||
| 4777 | (defun c-determine-limit (how-far-back &optional start try-size) | 4941 | (defun c-determine-limit (how-far-back &optional start try-size) |
| 4778 | ;; Return a buffer position HOW-FAR-BACK non-literal characters from START | 4942 | ;; Return a buffer position HOW-FAR-BACK non-literal characters from START |
| @@ -5152,8 +5316,9 @@ comment at the start of cc-engine.el for more info." | |||
| 5152 | ;; arrived at something that looks like a start or else | 5316 | ;; arrived at something that looks like a start or else |
| 5153 | ;; resort to `c-literal-limits'. | 5317 | ;; resort to `c-literal-limits'. |
| 5154 | (unless (looking-at c-literal-start-regexp) | 5318 | (unless (looking-at c-literal-start-regexp) |
| 5155 | (let ((range (c-literal-limits))) | 5319 | (let ((lit-start (c-literal-start))) |
| 5156 | (if range (goto-char (car range))))) | 5320 | (if lit-start (goto-char lit-start))) |
| 5321 | ) | ||
| 5157 | 5322 | ||
| 5158 | (setq start-in-literal (point))) ; end of `and' arm. | 5323 | (setq start-in-literal (point))) ; end of `and' arm. |
| 5159 | 5324 | ||
| @@ -5690,12 +5855,12 @@ comment at the start of cc-engine.el for more info." | |||
| 5690 | ;; 2010-01-29. | 5855 | ;; 2010-01-29. |
| 5691 | (save-excursion | 5856 | (save-excursion |
| 5692 | (c-save-buffer-state | 5857 | (c-save-buffer-state |
| 5693 | ((beg-lit-limits (progn (goto-char beg) (c-literal-limits))) | 5858 | ((beg-lit-start (progn (goto-char beg) (c-literal-start))) |
| 5694 | (end-lit-limits (progn (goto-char end) (c-literal-limits))) | 5859 | (end-lit-limits (progn (goto-char end) (c-literal-limits))) |
| 5695 | new-beg new-end beg-limit end-limit) | 5860 | new-beg new-end beg-limit end-limit) |
| 5696 | ;; Locate the earliest < after the barrier before the changed region, | 5861 | ;; Locate the earliest < after the barrier before the changed region, |
| 5697 | ;; which isn't already marked as a paren. | 5862 | ;; which isn't already marked as a paren. |
| 5698 | (goto-char (if beg-lit-limits (car beg-lit-limits) beg)) | 5863 | (goto-char (or beg-lit-start beg)) |
| 5699 | (setq beg-limit (c-determine-limit 512)) | 5864 | (setq beg-limit (c-determine-limit 512)) |
| 5700 | 5865 | ||
| 5701 | ;; Remove the syntax-table/category properties from each pertinent <...> | 5866 | ;; Remove the syntax-table/category properties from each pertinent <...> |
| @@ -5854,9 +6019,8 @@ comment at the start of cc-engine.el for more info." | |||
| 5854 | ;; | 6019 | ;; |
| 5855 | ;; Note: this routine is dependant upon the correct syntax-table text | 6020 | ;; Note: this routine is dependant upon the correct syntax-table text |
| 5856 | ;; properties being set. | 6021 | ;; properties being set. |
| 5857 | (let* ((safe (c-state-semi-safe-place (point))) | 6022 | (let ((state (c-state-semi-pp-to-literal (point))) |
| 5858 | (state (c-state-pp-to-literal safe (point))) | 6023 | open-quote-pos open-paren-pos close-paren-pos close-quote-pos id) |
| 5859 | open-quote-pos open-paren-pos close-paren-pos close-quote-pos id) | ||
| 5860 | (save-excursion | 6024 | (save-excursion |
| 5861 | (when | 6025 | (when |
| 5862 | (and | 6026 | (and |
| @@ -5865,7 +6029,7 @@ comment at the start of cc-engine.el for more info." | |||
| 5865 | (or (eq (char-after) ?\") | 6029 | (or (eq (char-after) ?\") |
| 5866 | (search-backward "\"" (max (- (point) 17) (point-min)) t))) | 6030 | (search-backward "\"" (max (- (point) 17) (point-min)) t))) |
| 5867 | ((and (eq (cadr state) 'string) | 6031 | ((and (eq (cadr state) 'string) |
| 5868 | (goto-char (car (nth 2 state))) | 6032 | (goto-char (nth 2 state)) |
| 5869 | (or (eq (char-after) ?\") | 6033 | (or (eq (char-after) ?\") |
| 5870 | (search-backward "\"" (max (- (point) 17) (point-min)) t)) | 6034 | (search-backward "\"" (max (- (point) 17) (point-min)) t)) |
| 5871 | (not (bobp))))) | 6035 | (not (bobp))))) |
| @@ -10551,8 +10715,8 @@ comment at the start of cc-engine.el for more info." | |||
| 10551 | ;; versions, which results in that we get nil from | 10715 | ;; versions, which results in that we get nil from |
| 10552 | ;; `c-literal-limits' even when `c-in-literal' claims | 10716 | ;; `c-literal-limits' even when `c-in-literal' claims |
| 10553 | ;; we're inside a comment. | 10717 | ;; we're inside a comment. |
| 10554 | (setq placeholder (c-literal-limits lim))) | 10718 | (setq placeholder (c-literal-start lim))) |
| 10555 | (c-add-syntax literal (car placeholder))) | 10719 | (c-add-syntax literal placeholder)) |
| 10556 | 10720 | ||
| 10557 | ;; CASE 3: in a cpp preprocessor macro continuation. | 10721 | ;; CASE 3: in a cpp preprocessor macro continuation. |
| 10558 | ((and (save-excursion | 10722 | ((and (save-excursion |
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 3a8c9ec0ec4..52f0b0d8696 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el | |||
| @@ -2480,10 +2480,10 @@ need for `pike-font-lock-extra-types'.") | |||
| 2480 | 'font-lock-comment-face) | 2480 | 'font-lock-comment-face) |
| 2481 | ;; Handle the case when the fontified region starts inside a | 2481 | ;; Handle the case when the fontified region starts inside a |
| 2482 | ;; comment. | 2482 | ;; comment. |
| 2483 | (let ((range (c-literal-limits))) | 2483 | (let ((start (c-literal-start))) |
| 2484 | (setq region-beg (point)) | 2484 | (setq region-beg (point)) |
| 2485 | (when range | 2485 | (when start |
| 2486 | (goto-char (car range))) | 2486 | (goto-char start)) |
| 2487 | (when (looking-at prefix) | 2487 | (when (looking-at prefix) |
| 2488 | (setq comment-beg (point))))) | 2488 | (setq comment-beg (point))))) |
| 2489 | 2489 | ||
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 80ac08fb9e0..5ad7a010641 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -1299,12 +1299,12 @@ Note that the style variables are always made local to the buffer." | |||
| 1299 | ;; This function is called indirectly from font locking stuff - either from | 1299 | ;; This function is called indirectly from font locking stuff - either from |
| 1300 | ;; c-after-change (to prepare for after-change font-locking) or from font | 1300 | ;; c-after-change (to prepare for after-change font-locking) or from font |
| 1301 | ;; lock context (etc.) fontification. | 1301 | ;; lock context (etc.) fontification. |
| 1302 | (let ((lit-limits (c-literal-limits)) | 1302 | (let ((lit-start (c-literal-start)) |
| 1303 | (new-pos pos) | 1303 | (new-pos pos) |
| 1304 | bod-lim bo-decl) | 1304 | bod-lim bo-decl) |
| 1305 | (goto-char (c-point 'bol new-pos)) | 1305 | (goto-char (c-point 'bol new-pos)) |
| 1306 | (when lit-limits ; Comment or string. | 1306 | (when lit-start ; Comment or string. |
| 1307 | (goto-char (car lit-limits))) | 1307 | (goto-char lit-start)) |
| 1308 | (setq bod-lim (c-determine-limit 500)) | 1308 | (setq bod-lim (c-determine-limit 500)) |
| 1309 | 1309 | ||
| 1310 | (while | 1310 | (while |