diff options
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/progmodes/cc-defs.el | 27 | ||||
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 155 |
2 files changed, 125 insertions, 57 deletions
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 8dd56106af4..dd8f8afc6a3 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el | |||
| @@ -1914,14 +1914,18 @@ non-nil, a caret is prepended to invert the set." | |||
| 1914 | (set-buffer-modified-p nil)) | 1914 | (set-buffer-modified-p nil)) |
| 1915 | (kill-buffer buf)) | 1915 | (kill-buffer buf)) |
| 1916 | 1916 | ||
| 1917 | ;; See if `parse-partial-sexp' returns the eighth element. | 1917 | ;; Check how many elements `parse-partial-sexp' returns. |
| 1918 | (if (c-safe (>= (length (save-excursion | 1918 | (let ((ppss-size (or (c-safe (length |
| 1919 | (parse-partial-sexp (point) (point)))) | 1919 | (save-excursion |
| 1920 | 10)) | 1920 | (parse-partial-sexp (point) (point))))) |
| 1921 | (setq list (cons 'pps-extended-state list)) | 1921 | 0))) |
| 1922 | (error (concat | 1922 | (cond |
| 1923 | "CC Mode is incompatible with this version of Emacs - " | 1923 | ((>= ppss-size 11) (setq list (cons 'pps-extended-state list))) |
| 1924 | "`parse-partial-sexp' has to return at least 10 elements."))) | 1924 | ((>= ppss-size 10)) |
| 1925 | (t (error | ||
| 1926 | (concat | ||
| 1927 | "CC Mode is incompatible with this version of Emacs - " | ||
| 1928 | "`parse-partial-sexp' has to return at least 10 elements."))))) | ||
| 1925 | 1929 | ||
| 1926 | ;;(message "c-emacs-features: %S" list) | 1930 | ;;(message "c-emacs-features: %S" list) |
| 1927 | list) | 1931 | list) |
| @@ -1944,10 +1948,9 @@ might be present: | |||
| 1944 | (i.e. the syntax class `!'). | 1948 | (i.e. the syntax class `!'). |
| 1945 | `gen-string-delim' Generic string delimiters work | 1949 | `gen-string-delim' Generic string delimiters work |
| 1946 | (i.e. the syntax class `|'). | 1950 | (i.e. the syntax class `|'). |
| 1947 | `pps-extended-state' `parse-partial-sexp' returns a list with at least 10 | 1951 | `pps-extended-state' `parse-partial-sexp' returns a list with at least 11 |
| 1948 | elements, i.e. it contains the position of the start of | 1952 | elements, i.e. it indicates having stopped after the |
| 1949 | the last comment or string. It's always set - CC Mode | 1953 | first character of a potential two-char construct. |
| 1950 | no longer works in emacsen without this feature. | ||
| 1951 | `posix-char-classes' The regexp engine understands POSIX character classes. | 1954 | `posix-char-classes' The regexp engine understands POSIX character classes. |
| 1952 | `col-0-paren' It's possible to turn off the ad-hoc rule that a paren | 1955 | `col-0-paren' It's possible to turn off the ad-hoc rule that a paren |
| 1953 | in column zero is the start of a defun. | 1956 | in column zero is the start of a defun. |
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 4af7c359747..6d7bab7a65c 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -2575,17 +2575,24 @@ comment at the start of cc-engine.el for more info." | |||
| 2575 | 2575 | ||
| 2576 | (defun c-cache-to-parse-ps-state (elt) | 2576 | (defun c-cache-to-parse-ps-state (elt) |
| 2577 | ;; Create a list suitable to use as the old-state parameter to | 2577 | ;; Create a list suitable to use as the old-state parameter to |
| 2578 | ;; `parse-partial-sexp', out of ELT. ELT is either just a number, a buffer | 2578 | ;; `parse-partial-sexp', out of ELT, a member of |
| 2579 | ;; position, or it is a list (POS TYPE STARTING-POS). Here POS is the | 2579 | ;; `c-state-semi-nonlit-pos-cache'. ELT is either just a number, or a list |
| 2580 | ;; buffer position the other elements are pertinent for, TYPE is either 'c | 2580 | ;; with 2, 3, or 4 members (See `c-parse-ps-state-to-cache'). That number |
| 2581 | ;; or 'c++ (for a comment) or a character (for a string delimiter) or t | 2581 | ;; or the car of the list is the "position element" of ELT, the position |
| 2582 | ;; (meaning a string fence opened the string), STARTING-POS is the starting | 2582 | ;; where ELT is valid. |
| 2583 | ;; position of the comment or string. | 2583 | ;; |
| 2584 | (if (consp elt) | 2584 | ;; POINT is left at the postition for which the returned state is valid. It |
| 2585 | ;; will be either the position element of ELT, or one character before | ||
| 2586 | ;; that. (The latter happens in Emacs <= 25 and XEmacs, when ELT indicates | ||
| 2587 | ;; its position element directly follows a potential first character of a | ||
| 2588 | ;; two char construct (such as a comment opener or an escaped character).) | ||
| 2589 | (if (and (consp elt) (>= (length elt) 3)) | ||
| 2590 | ;; Inside a string or comment | ||
| 2585 | (let ((depth 0) (containing nil) (last nil) | 2591 | (let ((depth 0) (containing nil) (last nil) |
| 2586 | in-string in-comment (after-quote nil) | 2592 | in-string in-comment (after-quote nil) |
| 2587 | (min-depth 0) com-style com-str-start (intermediate nil) | 2593 | (min-depth 0) com-style com-str-start (intermediate nil) |
| 2588 | (between-syntax nil) | 2594 | (char-1 (nth 3 elt)) ; first char of poss. 2-char construct |
| 2595 | (pos (car elt)) | ||
| 2589 | (type (cadr elt))) | 2596 | (type (cadr elt))) |
| 2590 | (setq com-str-start (car (cddr elt))) | 2597 | (setq com-str-start (car (cddr elt))) |
| 2591 | (cond | 2598 | (cond |
| @@ -2596,28 +2603,88 @@ comment at the start of cc-engine.el for more info." | |||
| 2596 | com-style (if (eq type 'c++) 1 nil))) | 2603 | com-style (if (eq type 'c++) 1 nil))) |
| 2597 | (t (c-benign-error "Invalid type %s in c-cache-to-parse-ps-state" | 2604 | (t (c-benign-error "Invalid type %s in c-cache-to-parse-ps-state" |
| 2598 | elt))) | 2605 | elt))) |
| 2599 | (list depth containing last | 2606 | (if (memq 'pps-extended-state c-emacs-features) |
| 2600 | in-string in-comment after-quote | 2607 | (progn |
| 2601 | min-depth com-style com-str-start | 2608 | (goto-char pos) |
| 2602 | intermediate nil)) | 2609 | (list depth containing last |
| 2603 | (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil)))) | 2610 | in-string in-comment after-quote |
| 2611 | min-depth com-style com-str-start | ||
| 2612 | intermediate char-1)) | ||
| 2613 | (goto-char (if char-1 | ||
| 2614 | (1- pos) | ||
| 2615 | pos)) | ||
| 2616 | (list depth containing last | ||
| 2617 | in-string in-comment nil | ||
| 2618 | min-depth com-style com-str-start | ||
| 2619 | intermediate))) | ||
| 2620 | |||
| 2621 | ;; Not in a string or comment. | ||
| 2622 | (if (memq 'pps-extended-state c-emacs-features) | ||
| 2623 | (progn | ||
| 2624 | (goto-char (if (consp elt) (car elt) elt)) | ||
| 2625 | (list 0 nil nil nil nil | ||
| 2626 | (and (consp elt) (eq (nth 1 elt) 9)) ; 9 is syntax code for "escape". | ||
| 2627 | 0 nil nil nil | ||
| 2628 | (and (consp elt) (nth 1 elt)))) | ||
| 2629 | (goto-char (if (consp elt) (car elt) elt)) | ||
| 2630 | (if (and (consp elt) (cdr elt)) (backward-char)) | ||
| 2631 | (copy-tree '(0 nil nil nil nil | ||
| 2632 | nil | ||
| 2633 | 0 nil nil nil))))) | ||
| 2604 | 2634 | ||
| 2605 | (defun c-parse-ps-state-to-cache (state) | 2635 | (defun c-parse-ps-state-to-cache (state) |
| 2606 | ;; Convert STATE, a `parse-partial-sexp' state valid at POINT, to an element | 2636 | ;; Convert STATE, a `parse-partial-sexp' state valid at POINT, to an element |
| 2607 | ;; for the `c-state-semi-nonlit-pos-cache' cache. This is either POINT | 2637 | ;; for the `c-state-semi-nonlit-pos-cache' cache. This is one of |
| 2608 | ;; (when point is not in a literal) or a list (POINT TYPE STARTING-POS), | 2638 | ;; o - POINT (when point is not in a literal); |
| 2609 | ;; where TYPE is the type of the literal, either 'string, 'c, or 'c++, and | 2639 | ;; o - (POINT CHAR-1) (when the last character before point is potentially |
| 2610 | ;; STARTING-POS is the starting position of the comment or string. | 2640 | ;; the first of a two-character construct |
| 2611 | (cond | 2641 | ;; o - (POINT TYPE STARTING-POS) (when in a literal); |
| 2612 | ((nth 3 state) ; A string | 2642 | ;; o - (POINT TYPE STARTING-POS CHAR-1) (Combination of the previous two), |
| 2613 | (list (point) (nth 3 state) (nth 8 state))) | 2643 | ;; where TYPE is the type of the literal (either 'c, or 'c++, or the |
| 2614 | ((and (nth 4 state) ; A comment | 2644 | ;; character which closes the string), STARTING-POS is the starting |
| 2615 | (not (eq (nth 7 state) 'syntax-table))) ; but not a psuedo comment. | 2645 | ;; position of the comment or string. CHAR-1 is either the character |
| 2616 | (list (point) | 2646 | ;; potentially forming the first half of a two-char construct (in Emacs <= |
| 2617 | (if (eq (nth 7 state) 1) 'c++ 'c) | 2647 | ;; 25 and XEmacs) or the syntax of the character (in Emacs >= 26). |
| 2618 | (nth 8 state))) | 2648 | (if (memq 'pps-extended-state c-emacs-features) |
| 2619 | (t ; Neither string nor comment. | 2649 | ;; Emacs >= 26. |
| 2620 | (point)))) | 2650 | (let ((basic |
| 2651 | (cond | ||
| 2652 | ((nth 3 state) ; A string | ||
| 2653 | (list (point) (nth 3 state) (nth 8 state))) | ||
| 2654 | ((and (nth 4 state) ; A comment | ||
| 2655 | (not (eq (nth 7 state) 'syntax-table))) ; but not a psuedo comment. | ||
| 2656 | (list (point) | ||
| 2657 | (if (eq (nth 7 state) 1) 'c++ 'c) | ||
| 2658 | (nth 8 state))) | ||
| 2659 | (t ; Neither string nor comment. | ||
| 2660 | (point))))) | ||
| 2661 | (if (nth 10 state) | ||
| 2662 | (append (if (consp basic) | ||
| 2663 | basic | ||
| 2664 | (list basic)) | ||
| 2665 | (list (nth 10 state))) | ||
| 2666 | basic)) | ||
| 2667 | |||
| 2668 | ;; Emacs <= 25, XEmacs. | ||
| 2669 | (cond | ||
| 2670 | ((nth 3 state) ; A string | ||
| 2671 | (if (eq (char-before) ?\\) | ||
| 2672 | (list (point) (nth 3 state) (nth 8 state) ?\\) | ||
| 2673 | (list (point) (nth 3 state) (nth 8 state)))) | ||
| 2674 | ((and (nth 4 state) ; comment | ||
| 2675 | (not (eq (nth 7 state) 'syntax-table))) | ||
| 2676 | (if (and (eq (char-before) ?*) | ||
| 2677 | (> (- (point) (nth 8 state)) 2)) ; not "/*/". | ||
| 2678 | (list (point) | ||
| 2679 | (if (eq (nth 7 state) 1) 'c++ 'c) | ||
| 2680 | (nth 8 state) | ||
| 2681 | ?*) | ||
| 2682 | (list (point) | ||
| 2683 | (if (eq (nth 7 state) 1) 'c++ 'c) | ||
| 2684 | (nth 8 state)))) | ||
| 2685 | (t (if (memq (char-before) '(?/ ?\\)) | ||
| 2686 | (list (point) (char-before)) | ||
| 2687 | (point)))))) | ||
| 2621 | 2688 | ||
| 2622 | (defsubst c-ps-state-cache-pos (elt) | 2689 | (defsubst c-ps-state-cache-pos (elt) |
| 2623 | ;; Get the buffer position from ELT, an element from the cache | 2690 | ;; Get the buffer position from ELT, an element from the cache |
| @@ -2637,7 +2704,7 @@ comment at the start of cc-engine.el for more info." | |||
| 2637 | (save-restriction | 2704 | (save-restriction |
| 2638 | (widen) | 2705 | (widen) |
| 2639 | (let ((c c-state-semi-nonlit-pos-cache) | 2706 | (let ((c c-state-semi-nonlit-pos-cache) |
| 2640 | elt state pos npos high-elt) | 2707 | elt state npos high-elt) |
| 2641 | ;; Trim the cache to take account of buffer changes. | 2708 | ;; Trim the cache to take account of buffer changes. |
| 2642 | (while (and c (> (c-ps-state-cache-pos (car c)) | 2709 | (while (and c (> (c-ps-state-cache-pos (car c)) |
| 2643 | c-state-semi-nonlit-pos-cache-limit)) | 2710 | c-state-semi-nonlit-pos-cache-limit)) |
| @@ -2647,29 +2714,27 @@ comment at the start of cc-engine.el for more info." | |||
| 2647 | (while (and c (> (c-ps-state-cache-pos (car c)) here)) | 2714 | (while (and c (> (c-ps-state-cache-pos (car c)) here)) |
| 2648 | (setq high-elt (car c)) | 2715 | (setq high-elt (car c)) |
| 2649 | (setq c (cdr c))) | 2716 | (setq c (cdr c))) |
| 2650 | (setq pos (or (and c (c-ps-state-cache-pos (car c))) | 2717 | (goto-char (or (and c (c-ps-state-cache-pos (car c))) |
| 2651 | (point-min))) | 2718 | (point-min))) |
| 2719 | (setq state | ||
| 2720 | (if c | ||
| 2721 | (c-cache-to-parse-ps-state (car c)) | ||
| 2722 | (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil)))) | ||
| 2652 | 2723 | ||
| 2653 | (if high-elt | 2724 | (when (not high-elt) |
| 2654 | (setq state (c-cache-to-parse-ps-state (car c))) | 2725 | ;; We need to extend the cache. Add an element to |
| 2655 | (setq elt (if c (car c) (point-min))) | 2726 | ;; `c-state-semi-nonlit-pos-cache' each iteration of the following. |
| 2656 | (setq state | ||
| 2657 | (if c | ||
| 2658 | (c-cache-to-parse-ps-state (car c)) | ||
| 2659 | (copy-tree '(0 nil nil nil nil nil 0 nil nil nil nil)))) | ||
| 2660 | (while | 2727 | (while |
| 2661 | ;; Add an element to `c-state-semi-nonlit-pos-cache' each iteration. | 2728 | (<= (setq npos (+ (point) c-state-nonlit-pos-interval)) here) |
| 2662 | (<= (setq npos (+ pos c-state-nonlit-pos-interval)) here) | 2729 | (setq state (parse-partial-sexp (point) npos nil nil state)) |
| 2663 | (setq state (parse-partial-sexp pos npos nil nil state)) | ||
| 2664 | (setq elt (c-parse-ps-state-to-cache state)) | 2730 | (setq elt (c-parse-ps-state-to-cache state)) |
| 2665 | (setq c-state-semi-nonlit-pos-cache | 2731 | (setq c-state-semi-nonlit-pos-cache |
| 2666 | (cons elt c-state-semi-nonlit-pos-cache)) | 2732 | (cons elt c-state-semi-nonlit-pos-cache)))) |
| 2667 | (setq pos npos))) | ||
| 2668 | 2733 | ||
| 2669 | (if (> pos c-state-semi-nonlit-pos-cache-limit) | 2734 | (if (> (point) c-state-semi-nonlit-pos-cache-limit) |
| 2670 | (setq c-state-semi-nonlit-pos-cache-limit pos)) | 2735 | (setq c-state-semi-nonlit-pos-cache-limit (point))) |
| 2671 | 2736 | ||
| 2672 | (cons pos state))))) | 2737 | (cons (point) state))))) |
| 2673 | 2738 | ||
| 2674 | (defun c-state-safe-place (here) | 2739 | (defun c-state-safe-place (here) |
| 2675 | ;; Return a buffer position before HERE which is "safe", i.e. outside any | 2740 | ;; Return a buffer position before HERE which is "safe", i.e. outside any |