diff options
| author | Alan Mackenzie | 2019-01-28 10:54:42 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2019-01-28 10:54:42 +0000 |
| commit | 239386806ec637419786bd1ab21e002bf2d501c1 (patch) | |
| tree | c04efa021c81a23a913728189355ae83f0b059b4 | |
| parent | d81aa8516ef6df79d6d602d4f732d8a65bf1677c (diff) | |
| download | emacs-239386806ec637419786bd1ab21e002bf2d501c1.tar.gz emacs-239386806ec637419786bd1ab21e002bf2d501c1.zip | |
Detect when we hit limit in backward search in c-just-after-func-arglist-p
This fixes a bug reported by Yasushi SHOJI <yasushi.shoji@gmail.com> to
emacs-devel on 2018-11-26, where wrong analysis and fontification occurred.
* lisp/progmodes/cc-engine.el (c-beginning-of-statement-1): Add new parameter
HIT-LIM which, if non-nil causes the function to return nil rather than 'same
when we reach the backward search limit without finding the beginning of
statement.
(c-just-after-func-arglist-p): Supply argument t to this new parameter in call
to c-beginning-of-statement-1.
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 90e4438ea4c..b4c12896f36 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -665,10 +665,12 @@ comment at the start of cc-engine.el for more info." | |||
| 665 | stack (cdr stack)) | 665 | stack (cdr stack)) |
| 666 | t | 666 | t |
| 667 | ,do-if-done | 667 | ,do-if-done |
| 668 | (setq pre-stmt-found t) | ||
| 668 | (throw 'loop nil))) | 669 | (throw 'loop nil))) |
| 669 | (defmacro c-bos-pop-state-and-retry () | 670 | (defmacro c-bos-pop-state-and-retry () |
| 670 | '(throw 'loop (setq state (car (car stack)) | 671 | '(throw 'loop (setq state (car (car stack)) |
| 671 | saved-pos (cdr (car stack)) | 672 | saved-pos (cdr (car stack)) |
| 673 | pre-stmt-found (not (cdr stack)) | ||
| 672 | ;; Throw nil if stack is empty, else throw non-nil. | 674 | ;; Throw nil if stack is empty, else throw non-nil. |
| 673 | stack (cdr stack)))) | 675 | stack (cdr stack)))) |
| 674 | (defmacro c-bos-save-pos () | 676 | (defmacro c-bos-save-pos () |
| @@ -694,7 +696,7 @@ comment at the start of cc-engine.el for more info." | |||
| 694 | (c-point 'bol (elt saved-pos 0)))))))) | 696 | (c-point 'bol (elt saved-pos 0)))))))) |
| 695 | 697 | ||
| 696 | (defun c-beginning-of-statement-1 (&optional lim ignore-labels | 698 | (defun c-beginning-of-statement-1 (&optional lim ignore-labels |
| 697 | noerror comma-delim) | 699 | noerror comma-delim hit-lim) |
| 698 | "Move to the start of the current statement or declaration, or to | 700 | "Move to the start of the current statement or declaration, or to |
| 699 | the previous one if already at the beginning of one. Only | 701 | the previous one if already at the beginning of one. Only |
| 700 | statements/declarations on the same level are considered, i.e. don't | 702 | statements/declarations on the same level are considered, i.e. don't |
| @@ -729,14 +731,16 @@ Return: | |||
| 729 | `up' if stepped to a containing statement; | 731 | `up' if stepped to a containing statement; |
| 730 | `previous' if stepped to a preceding statement; | 732 | `previous' if stepped to a preceding statement; |
| 731 | `beginning' if stepped from a statement continuation clause to | 733 | `beginning' if stepped from a statement continuation clause to |
| 732 | its start clause; or | 734 | its start clause; |
| 733 | `macro' if stepped to a macro start. | 735 | `macro' if stepped to a macro start; or |
| 736 | nil if HIT-LIM is non-nil, and we hit the limit. | ||
| 734 | Note that `same' and not `label' is returned if stopped at the same | 737 | Note that `same' and not `label' is returned if stopped at the same |
| 735 | label without crossing the colon character. | 738 | label without crossing the colon character. |
| 736 | 739 | ||
| 737 | LIM may be given to limit the search. If the search hits the limit, | 740 | LIM may be given to limit the search. If the search hits the limit, |
| 738 | point will be left at the closest following token, or at the start | 741 | point will be left at the closest following token, or at the start |
| 739 | position if that is less (`same' is returned in this case). | 742 | position if that is less. If HIT-LIM is non-nil, nil is returned in |
| 743 | this case, otherwise `same'. | ||
| 740 | 744 | ||
| 741 | NOERROR turns off error logging to `c-parsing-error'. | 745 | NOERROR turns off error logging to `c-parsing-error'. |
| 742 | 746 | ||
| @@ -840,6 +844,10 @@ comment at the start of cc-engine.el for more info." | |||
| 840 | pos | 844 | pos |
| 841 | ;; Position of last stmt boundary character (e.g. ;). | 845 | ;; Position of last stmt boundary character (e.g. ;). |
| 842 | boundary-pos | 846 | boundary-pos |
| 847 | ;; Non-nil when a construct has been found which delimits the search | ||
| 848 | ;; for a statement start, e.g. an opening brace or a macro start, or a | ||
| 849 | ;; keyword like `if' when the PDA stack is empty. | ||
| 850 | pre-stmt-found | ||
| 843 | ;; The position of the last sexp or bound that follows the | 851 | ;; The position of the last sexp or bound that follows the |
| 844 | ;; first found colon, i.e. the start of the nonlabel part of | 852 | ;; first found colon, i.e. the start of the nonlabel part of |
| 845 | ;; the statement. It's `start' if a colon is found just after | 853 | ;; the statement. It's `start' if a colon is found just after |
| @@ -877,7 +885,10 @@ comment at the start of cc-engine.el for more info." | |||
| 877 | tok ptok pptok) | 885 | tok ptok pptok) |
| 878 | 886 | ||
| 879 | (save-restriction | 887 | (save-restriction |
| 880 | (if lim (narrow-to-region lim (point-max))) | 888 | (setq lim (if lim |
| 889 | (max lim (point-min)) | ||
| 890 | (point-min))) | ||
| 891 | (widen) | ||
| 881 | 892 | ||
| 882 | (if (save-excursion | 893 | (if (save-excursion |
| 883 | (and (c-beginning-of-macro) | 894 | (and (c-beginning-of-macro) |
| @@ -923,9 +934,10 @@ comment at the start of cc-engine.el for more info." | |||
| 923 | ;; The loop is exited only by throwing nil to the (catch 'loop ...): | 934 | ;; The loop is exited only by throwing nil to the (catch 'loop ...): |
| 924 | ;; 1. On reaching the start of a macro; | 935 | ;; 1. On reaching the start of a macro; |
| 925 | ;; 2. On having passed a stmt boundary with the PDA stack empty; | 936 | ;; 2. On having passed a stmt boundary with the PDA stack empty; |
| 926 | ;; 3. On reaching the start of an Objective C method def; | 937 | ;; 3. Going backwards past the search limit. |
| 927 | ;; 4. From macro `c-bos-pop-state'; when the stack is empty; | 938 | ;; 4. On reaching the start of an Objective C method def; |
| 928 | ;; 5. From macro `c-bos-pop-state-and-retry' when the stack is empty. | 939 | ;; 5. From macro `c-bos-pop-state'; when the stack is empty; |
| 940 | ;; 6. From macro `c-bos-pop-state-and-retry' when the stack is empty. | ||
| 929 | (while | 941 | (while |
| 930 | (catch 'loop ;; Throw nil to break, non-nil to continue. | 942 | (catch 'loop ;; Throw nil to break, non-nil to continue. |
| 931 | (cond | 943 | (cond |
| @@ -950,6 +962,7 @@ comment at the start of cc-engine.el for more info." | |||
| 950 | (setq pos saved | 962 | (setq pos saved |
| 951 | ret 'macro | 963 | ret 'macro |
| 952 | ignore-labels t)) | 964 | ignore-labels t)) |
| 965 | (setq pre-stmt-found t) | ||
| 953 | (throw 'loop nil)) ; 1. Start of macro. | 966 | (throw 'loop nil)) ; 1. Start of macro. |
| 954 | 967 | ||
| 955 | ;; Do a round through the automaton if we've just passed a | 968 | ;; Do a round through the automaton if we've just passed a |
| @@ -959,6 +972,7 @@ comment at the start of cc-engine.el for more info." | |||
| 959 | (setq sym (intern (match-string 1))))) | 972 | (setq sym (intern (match-string 1))))) |
| 960 | 973 | ||
| 961 | (when (and (< pos start) (null stack)) | 974 | (when (and (< pos start) (null stack)) |
| 975 | (setq pre-stmt-found t) | ||
| 962 | (throw 'loop nil)) ; 2. Statement boundary. | 976 | (throw 'loop nil)) ; 2. Statement boundary. |
| 963 | 977 | ||
| 964 | ;; The PDA state handling. | 978 | ;; The PDA state handling. |
| @@ -1071,7 +1085,8 @@ comment at the start of cc-engine.el for more info." | |||
| 1071 | ;; Step to the previous sexp, but not if we crossed a | 1085 | ;; Step to the previous sexp, but not if we crossed a |
| 1072 | ;; boundary, since that doesn't consume an sexp. | 1086 | ;; boundary, since that doesn't consume an sexp. |
| 1073 | (if (eq sym 'boundary) | 1087 | (if (eq sym 'boundary) |
| 1074 | (setq ret 'previous) | 1088 | (when (>= (point) lim) |
| 1089 | (setq ret 'previous)) | ||
| 1075 | 1090 | ||
| 1076 | ;; HERE IS THE SINGLE PLACE INSIDE THE PDA LOOP WHERE WE MOVE | 1091 | ;; HERE IS THE SINGLE PLACE INSIDE THE PDA LOOP WHERE WE MOVE |
| 1077 | ;; BACKWARDS THROUGH THE SOURCE. | 1092 | ;; BACKWARDS THROUGH THE SOURCE. |
| @@ -1093,6 +1108,7 @@ comment at the start of cc-engine.el for more info." | |||
| 1093 | ;; Give up if we hit an unbalanced block. Since the | 1108 | ;; Give up if we hit an unbalanced block. Since the |
| 1094 | ;; stack won't be empty the code below will report a | 1109 | ;; stack won't be empty the code below will report a |
| 1095 | ;; suitable error. | 1110 | ;; suitable error. |
| 1111 | (setq pre-stmt-found t) | ||
| 1096 | (throw 'loop nil)) | 1112 | (throw 'loop nil)) |
| 1097 | (cond | 1113 | (cond |
| 1098 | ;; Have we moved into a macro? | 1114 | ;; Have we moved into a macro? |
| @@ -1162,12 +1178,17 @@ comment at the start of cc-engine.el for more info." | |||
| 1162 | ;; Like a C "continue". Analyze the next sexp. | 1178 | ;; Like a C "continue". Analyze the next sexp. |
| 1163 | (throw 'loop t)))) | 1179 | (throw 'loop t)))) |
| 1164 | 1180 | ||
| 1181 | ;; Have we gone past the limit? | ||
| 1182 | (when (< (point) lim) | ||
| 1183 | (throw 'loop nil)) ; 3. Gone back over the limit. | ||
| 1184 | |||
| 1165 | ;; ObjC method def? | 1185 | ;; ObjC method def? |
| 1166 | (when (and c-opt-method-key | 1186 | (when (and c-opt-method-key |
| 1167 | (setq saved (c-in-method-def-p))) | 1187 | (setq saved (c-in-method-def-p))) |
| 1168 | (setq pos saved | 1188 | (setq pos saved |
| 1189 | pre-stmt-found t | ||
| 1169 | ignore-labels t) ; Avoid the label check on exit. | 1190 | ignore-labels t) ; Avoid the label check on exit. |
| 1170 | (throw 'loop nil)) ; 3. ObjC method def. | 1191 | (throw 'loop nil)) ; 4. ObjC method def. |
| 1171 | 1192 | ||
| 1172 | ;; Might we have a bitfield declaration, "<type> <id> : <size>"? | 1193 | ;; Might we have a bitfield declaration, "<type> <id> : <size>"? |
| 1173 | (if c-has-bitfields | 1194 | (if c-has-bitfields |
| @@ -1228,9 +1249,15 @@ comment at the start of cc-engine.el for more info." | |||
| 1228 | ptok tok | 1249 | ptok tok |
| 1229 | tok (point) | 1250 | tok (point) |
| 1230 | pos tok) ; always non-nil | 1251 | pos tok) ; always non-nil |
| 1231 | ) ; end of (catch loop ....) | 1252 | ) ; end of (catch 'loop ....) |
| 1232 | ) ; end of sexp-at-a-time (while ....) | 1253 | ) ; end of sexp-at-a-time (while ....) |
| 1233 | 1254 | ||
| 1255 | (when (and hit-lim | ||
| 1256 | (or (not pre-stmt-found) | ||
| 1257 | (< pos lim) | ||
| 1258 | (>= pos start))) | ||
| 1259 | (setq ret nil)) | ||
| 1260 | |||
| 1234 | ;; If the stack isn't empty there might be errors to report. | 1261 | ;; If the stack isn't empty there might be errors to report. |
| 1235 | (while stack | 1262 | (while stack |
| 1236 | (if (and (vectorp saved-pos) (eq (length saved-pos) 3)) | 1263 | (if (and (vectorp saved-pos) (eq (length saved-pos) 3)) |
| @@ -9659,7 +9686,7 @@ comment at the start of cc-engine.el for more info." | |||
| 9659 | 9686 | ||
| 9660 | (let ((beg (point)) id-start) | 9687 | (let ((beg (point)) id-start) |
| 9661 | (and | 9688 | (and |
| 9662 | (eq (c-beginning-of-statement-1 lim) 'same) | 9689 | (eq (c-beginning-of-statement-1 lim nil nil nil t) 'same) |
| 9663 | 9690 | ||
| 9664 | (not (and (c-major-mode-is 'objc-mode) | 9691 | (not (and (c-major-mode-is 'objc-mode) |
| 9665 | (c-forward-objc-directive))) | 9692 | (c-forward-objc-directive))) |