GNU bug report logs -
#37045
lisp-indent-region hangs in lisp-indent-calc-next when indenting the three characters "|#\n"
Previous Next
Reported by: eschulte <at> grammatech.com
Date: Fri, 16 Aug 2019 04:50:03 UTC
Severity: normal
Tags: fixed, patch
Found in version 26.1
Fixed in version 26.3
Done: Noam Postavsky <npostavs <at> gmail.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 37045 in the body.
You can then email your comments to 37045 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#37045
; Package
emacs
.
(Fri, 16 Aug 2019 04:50:03 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
eschulte <at> grammatech.com
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Fri, 16 Aug 2019 04:50:03 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
Hi,
Indent-region sometimes hangs when indenting a lisp file. A minimal
example is the file just containing the characters "|#" followed by a
newline. This hang is due to an infinite loop in the while loop in the
`lisp-indent-calc-next' function. The following version of this
function fixes this problem, but is certainly not the appropriate
long-term fix.
[lisp-indent-calc-next-workaround.lisp (text/x-lisp, inline)]
;;; Work around a bug in `lisp-indent-calc-next' in which it can hang
;;; on a dangling '|#'. The change in the code below against the
;;; original is the addition of a block and a throw to this block when
;;; we're infinite looping (when the newly added last-last-sexp
;;; matches last-sexp). On the off chance it is possible in normal
;;; execution for last-sexp to stay the same for some number of loop
;;; iterations this patch only aborts if they're equal 100 times in a
;;; row.
(defun lisp-indent-calc-next (state)
"Move to next line and return calculated indent for it.
STATE is updated by side effect, the first state should be
created by `lisp-indent-initial-state'. This function may move
by more than one line to cross a string literal."
(pcase-let* (((cl-struct lisp-indent-state
(stack indent-stack) ppss ppss-point)
state)
(indent-depth (car ppss)) ; Corresponding to indent-stack.
(depth indent-depth)
(last-last-sexp nil) (counter 0))
(block nil
;; Parse this line so we can learn the state to indent the
;; next line.
(while (let ((last-sexp (nth 2 ppss)))
(setq ppss (parse-partial-sexp
ppss-point (progn (end-of-line) (point))
nil nil ppss))
;; Preserve last sexp of state (position 2) for
;; `calculate-lisp-indent', if we're at the same depth.
(if (and (not (nth 2 ppss)) (= depth (car ppss)))
(setf (nth 2 ppss) last-sexp)
(setq last-sexp (nth 2 ppss)))
(setq depth (car ppss))
(if (and (>= counter 100) (equal last-sexp last-last-sexp))
(progn (setf indent-stack nil) (return))
(setq last-last-sexp last-sexp
counter (1+ counter)))
;; Skip over newlines within strings.
(nth 3 ppss))
(let ((string-start (nth 8 ppss)))
(setq ppss (parse-partial-sexp (point) (point-max)
nil nil ppss 'syntax-table))
(setf (nth 2 ppss) string-start) ; Finished a complete string.
(setq depth (car ppss)))
(setq ppss-point (point)))
(setq ppss-point (point))
(let* ((depth-delta (- depth indent-depth)))
(cond ((< depth-delta 0)
(setq indent-stack (nthcdr (- depth-delta) indent-stack)))
((> depth-delta 0)
(setq indent-stack (nconc (make-list depth-delta nil)
indent-stack))))))
(prog1
(let (indent)
(cond ((= (forward-line 1) 1) nil)
;; Negative depth, probably some kind of syntax error.
((null indent-stack)
;; Reset state.
(setq ppss (parse-partial-sexp (point) (point))))
((car indent-stack))
((integerp (setq indent (calculate-lisp-indent ppss)))
(setf (car indent-stack) indent))
((consp indent) ; (COLUMN CONTAINING-SEXP-START)
(car indent))
;; This only happens if we're in a string.
(t (error "This shouldn't happen"))))
(setf (lisp-indent-state-stack state) indent-stack)
(setf (lisp-indent-state-ppss-point state) ppss-point)
(setf (lisp-indent-state-ppss state) ppss))))
[Message part 3 (text/plain, inline)]
Thanks,
Eric
P.S. I hope this isn't a duplicate report, I tried to search both the
archive https://lists.gnu.org/archive/html/bug-gnu-emacs/ and the
previous bug reports https://debbugs.gnu.org/ but I didn't find anything
relevant.
--
Eric Schulte, Ph.D.
Director of Automated Software Engineering
GrammaTech, Inc.
PGP Fingerprint: FA8D C2C3 E8A0 A749 34CD 9DCF 3C1B 8581 614C A05D
Pronouns: he, him, his
[signature.asc (application/pgp-signature, inline)]
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#37045
; Package
emacs
.
(Fri, 16 Aug 2019 11:48:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 37045 <at> debbugs.gnu.org (full text, mbox):
[Message part 1 (text/plain, inline)]
found 37045 26.1
tags 37045 + patch
quit
eschulte <at> grammatech.com writes:
> Indent-region sometimes hangs when indenting a lisp file. A minimal
> example is the file just containing the characters "|#" followed by a
> newline.
It's actually any unfinished string literal (in Common Lisp, |...| is
treated by Emacs as a string literal, though technically it's an escaped
symbol).
> This hang is due to an infinite loop in the while loop in the
> `lisp-indent-calc-next' function. The following version of this
> function fixes this problem, but is certainly not the appropriate
> long-term fix.
I think the right fix is just to check for end of buffer:
@@ -810,7 +810,7 @@ lisp-indent-calc-next
(setq last-sexp (nth 2 ppss)))
(setq depth (car ppss))
;; Skip over newlines within strings.
- (nth 3 ppss))
+ (and (not (eobp)) (nth 3 ppss)))
(let ((string-start (nth 8 ppss)))
(setq ppss (parse-partial-sexp (point) (point-max)
nil nil ppss 'syntax-table))
Full patch with test (and some other comment updates) attached below.
Is this okay for emacs-26? The bug is a regression from Emacs 25.
[0001-Fix-lisp-indent-infloop-on-unfinished-strings-Bug-37.patch (text/plain, attachment)]
bug Marked as found in versions 26.1.
Request was from
Noam Postavsky <npostavs <at> gmail.com>
to
control <at> debbugs.gnu.org
.
(Fri, 16 Aug 2019 11:48:02 GMT)
Full text and
rfc822 format available.
Added tag(s) patch.
Request was from
Noam Postavsky <npostavs <at> gmail.com>
to
control <at> debbugs.gnu.org
.
(Fri, 16 Aug 2019 11:48:02 GMT)
Full text and
rfc822 format available.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#37045
; Package
emacs
.
(Fri, 16 Aug 2019 12:56:02 GMT)
Full text and
rfc822 format available.
Message #15 received at 37045 <at> debbugs.gnu.org (full text, mbox):
> From: Noam Postavsky <npostavs <at> gmail.com>
> Date: Fri, 16 Aug 2019 07:47:20 -0400
> Cc: 37045 <at> debbugs.gnu.org
>
> Is this okay for emacs-26? The bug is a regression from Emacs 25.
Yes, thanks.
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#37045
; Package
emacs
.
(Sat, 17 Aug 2019 13:53:01 GMT)
Full text and
rfc822 format available.
Message #18 received at 37045 <at> debbugs.gnu.org (full text, mbox):
tags 37045 fixed
close 37045 26.3
quit
Eli Zaretskii <eliz <at> gnu.org> writes:
>> From: Noam Postavsky <npostavs <at> gmail.com>
>> Date: Fri, 16 Aug 2019 07:47:20 -0400
>> Cc: 37045 <at> debbugs.gnu.org
>>
>> Is this okay for emacs-26? The bug is a regression from Emacs 25.
>
> Yes, thanks.
Pushed to emacs-26.
bcd0115e4d 2019-08-17T09:42:34-04:00 "Fix lisp indent infloop on unfinished strings (Bug#37045)"
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=bcd0115e4db49791a77566b80fabc4384d9ebf57
Added tag(s) fixed.
Request was from
Noam Postavsky <npostavs <at> gmail.com>
to
control <at> debbugs.gnu.org
.
(Sat, 17 Aug 2019 13:53:03 GMT)
Full text and
rfc822 format available.
bug marked as fixed in version 26.3, send any further explanations to
37045 <at> debbugs.gnu.org and eschulte <at> grammatech.com
Request was from
Noam Postavsky <npostavs <at> gmail.com>
to
control <at> debbugs.gnu.org
.
(Sat, 17 Aug 2019 13:53:03 GMT)
Full text and
rfc822 format available.
bug archived.
Request was from
Debbugs Internal Request <help-debbugs <at> gnu.org>
to
internal_control <at> debbugs.gnu.org
.
(Sun, 15 Sep 2019 11:24:06 GMT)
Full text and
rfc822 format available.
This bug report was last modified 4 years and 196 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.