Subject: bug#45952: Correction to: Re: 27.1; Certain regexps can cause comint-redirect-results-list-from-process to loop.

From: Richard Sharman <[email-masked]>
Date: Sun, 17 Jan 2021 21:48:16 -0800

Sorry, there was a mistake on the patch on my previous message; 
the (re-search-forward regexp nil t)) was inadvertently changed to (re-search-forward regexp nil).

Sorry.

Here’s the corrected version:

--- comint.el.orig	2021-01-17 21:35:02.000000000 -0800
+++ comint.el	2021-01-17 21:36:23.000000000 -0800
@@ -3822,7 +3822,7 @@
 Return a list of expressions in the output which match REGEXP.
 REGEXP-GROUP is the regular expression group in REGEXP to use."
   (let ((output-buffer " *Comint Redirect Work Buffer*")
-	results)
+	results last-point)
     (with-current-buffer (get-buffer-create output-buffer)
       (erase-buffer)
       (comint-redirect-send-command-to-process command
@@ -3837,13 +3837,18 @@
       ;; Skip past the command, if it was echoed
       (and (looking-at command)
 	   (forward-line))
+      (setq last-point (point))
       (while (and (not (eobp))
 		  (re-search-forward regexp nil t))
-	(push (buffer-substring-no-properties
-               (match-beginning regexp-group)
-               (match-end regexp-group))
-              results))
+	(if (equal (point) last-point)
+	    (forward-line 1)
+	  (push (buffer-substring-no-properties
+		 (match-beginning regexp-group)
+		 (match-end regexp-group))
+		results))
+	(setq last-point (point)))
       (nreverse results))))
+
 
 ;; Converting process modes to use comint mode
 ;; ===========================================================================

> On Jan 17, 2021, at 5:24 PM, Richard Sharman <[email-masked]> wrote:
> 
> Certain regexps can cause comint-redirect-results-list-from-process to loop.
> 
> For example, when attempting to match whole lines with the regexp
> "^.*$" if the output buffer contains an empty line, then the
> re-search-forward expression returns (point) but does not advance point,
> and since (eobp) is false the loop never terminates. 
> 
> This could avoided by testing if point advances.  If it doesn't, one
> could either exit the loop or, preferably, advance a line which would
> allow for further matches. 
> 
> Function loop.el demonstrates the problem.  It sends to a shell buffer a
> command that outputs 4 lines, the 3rd of which is empty.  Trying to
> match all lines with "^.*$" causes it to loop. 
> 
> (defun loop ()
>  (interactive)
>  ;; create shell if not done
>  (save-window-excursion
>    (shell))
>  ;; send a command that outputs 4 lines, the 3rd of which is empty
>  (let ((p (get-process "shell"))
> 	(command "(echo a; echo b ; echo ; echo d)\n")
> 	reply)
>    (setq reply (comint-redirect-results-list-from-process p command "^.*$" 0))
>    ;; we never get to here!
>    (message (car reply))
>    reply
>    ))
> 
> Note:  Starting from emacs -Q it is necessary to run M-x shell before
> invoking loop,  otherwise the error "No prompt found or
> ‘comint-prompt-regexp’ not set properly" is produced.
> 
> With this patch correct results are obtained:
> --- comint.el.orig	2021-01-17 14:22:17.000000000 -0800
> +++ comint.el	2021-01-17 14:23:54.000000000 -0800
> @@ -3822,7 +3822,7 @@
> Return a list of expressions in the output which match REGEXP.
> REGEXP-GROUP is the regular expression group in REGEXP to use."
>   (let ((output-buffer " *Comint Redirect Work Buffer*")
> -	results)
> +	results last-point)
>     (with-current-buffer (get-buffer-create output-buffer)
>       (erase-buffer)
>       (comint-redirect-send-command-to-process command
> @@ -3837,13 +3837,18 @@
>       ;; Skip past the command, if it was echoed
>       (and (looking-at command)
> 	   (forward-line))
> +      (setq last-point (point))
>       (while (and (not (eobp))
> -		  (re-search-forward regexp nil t))
> -	(push (buffer-substring-no-properties
> -               (match-beginning regexp-group)
> -               (match-end regexp-group))
> -              results))
> +		  (re-search-forward regexp nil))
> +	(if (equal (point) last-point)
> +	    (forward-line 1)
> +	  (push (buffer-substring-no-properties
> +		 (match-beginning regexp-group)
> +		 (match-end regexp-group))
> +		results))
> +	(setq last-point (point)))
>       (nreverse results))))
> +
> 
> ;; Converting process modes to use comint mode
> ;; ===========================================================================
> 
> 
> 
> In GNU Emacs 27.1 (build 2, x86_64-apple-darwin17.7.0, NS appkit-1561.61 Version 10.13.6 (Build 17G14033))
> of 2020-12-13 built on henry.local
> Windowing system distributor 'Apple', version 10.3.1561
> System Description:  Mac OS X 10.13.6
> 
> Recent messages:
> For information about GNU Emacs and the GNU system, type C-h C-a.
> loop
> Quit
> Quit
> Configured features:
> NOTIFY KQUEUE ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES
> THREADS JSON PDUMPER GMP
> 
> Important settings:
>  value of $LANG: en_CA.UTF-8
>  locale-coding-system: utf-8-unix
> 
> Major mode: Emacs-Lisp
> 
> Minor modes in effect:
>  shell-dirtrack-mode: t
>  tooltip-mode: t
>  global-eldoc-mode: t
>  eldoc-mode: t
>  electric-indent-mode: t
>  mouse-wheel-mode: t
>  tool-bar-mode: t
>  menu-bar-mode: t
>  file-name-shadow-mode: t
>  global-font-lock-mode: t
>  font-lock-mode: t
>  blink-cursor-mode: t
>  auto-composition-mode: t
>  auto-encryption-mode: t
>  auto-compression-mode: t
>  line-number-mode: t
>  transient-mark-mode: t
> 
> Load-path shadows:
> None found.
> 
> Features:
> (shadow sort mail-extr emacsbug message rmc puny dired dired-loaddefs
> format-spec rfc822 mml easymenu mml-sec password-cache epa derived epg
> epg-config gnus-util rmail rmail-loaddefs text-property-search time-date
> subr-x seq byte-opt gv bytecomp byte-compile cconv mm-decode mm-bodies
> mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader cl-loaddefs
> cl-lib sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
> shell pcomplete comint ansi-color ring tooltip eldoc electric uniquify
> ediff-hook vc-hooks lisp-float-type mwheel term/ns-win ns-win
> ucs-normalize mule-util term/common-win tool-bar dnd fontset image
> regexp-opt fringe tabulated-list replace newcomment text-mode elisp-mode
> lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch
> timer select scroll-bar mouse jit-lock font-lock syntax facemenu
> font-core term/tty-colors frame minibuffer cl-generic cham georgian
> utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
> japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european
> ethiopic indian cyrillic chinese composite charscript charprop
> case-table epa-hook jka-cmpr-hook help simple abbrev obarray
> cl-preloaded nadvice loaddefs button faces cus-face macroexp files
> text-properties overlay sha1 md5 base64 format env code-pages mule
> custom widget hashtable-print-readable backquote threads kqueue cocoa ns
> multi-tty make-network-process emacs)
> 
> Memory information:
> ((conses 16 49326 43672)
> (symbols 48 6380 11)
> (strings 32 17163 4847)
> (string-bytes 1 570096)
> (vectors 16 10970)
> (vector-slots 8 134400 67778)
> (floats 8 19 151)
> (intervals 56 211 86)
> (buffers 1000 14))