unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* save-match-data woes
@ 2002-02-21 11:36 Juanma Barranquero
  2002-02-21 11:54 ` Eli Zaretskii
  2002-02-22 16:43 ` Stefan Monnier
  0 siblings, 2 replies; 11+ messages in thread
From: Juanma Barranquero @ 2002-02-21 11:36 UTC (permalink / raw)


I was trying something with ielm (which I use a lot), and found that:

ELISP> (setq var "12334")
"12334"
ELISP> (string-match "34+" var)
3
ELISP> (match-data)
(3 5)

ELISP> (match-data)
(0 0)

After digging around I've found that ielm has non-protected calls to
string-match and looking-for, and is also calling pp-to-string, which
does not preserve the match data either.

From a recent change to bibtex.el by Eli I suppose the intent is to make
functions preserve match data unless their interface specifically says
they don't.

So I'm including patches to ielm.el and pp.el protecting the offending
code with save-match-data (the changes seem bigger because of
indentation, but in all cases is just a matter of adding a call to
save-match-data or equivalent).

Incidentally, the above example with ielm still does not work for me
(on a patched Emacs) if I get the second call to match-data via M-p,
because that invokes an offending comint function. AFAICS comint.el does
only a half-hearted attempt to preserve match data. It should be
modified also, but I won't try that unless someone says that it is OK to
do so.

Only somewhat related: several tiny patches I've sent on the past week
or so haven't received any comment. Should I assume silence is
equivalent to rejection, or lack of interest? (Not a complain, just
curiosity)


                                                           /L/e/k/t/u




2002-02-21  Juanma Barranquero  <lektu@terra.es>

	* ielm.el (ielm-return): Protect match data.
	(ielm-is-whitespace): Ditto.
	(ielm-get-old-input): Ditto.

	* emacs-lisp/pp.el (pp-to-string): Ditto.
	(pp-eval-last-sexp): Ditto.



Index: ielm.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/ielm.el,v
retrieving revision 1.22
diff -u -r1.22 ielm.el
--- ielm.el	10 Oct 2000 17:27:38 -0000	1.22
+++ ielm.el	21 Feb 2002 11:03:35 -0000
@@ -225,7 +225,7 @@
 	  (if (and ielm-dynamic-multiline-inputs
 		   (save-excursion
 		     (beginning-of-line)
-		     (looking-at comint-prompt-regexp)))
+		     (save-match-data (looking-at comint-prompt-regexp))))
 	      (save-excursion
 		(goto-char (ielm-pm))
 		(newline 1)))
@@ -251,7 +251,8 @@
 
 (defun ielm-is-whitespace (string)
   "Return non-nil if STRING is all whitespace."
-  (or (string= string "") (string-match "\\`[ \t\n]+\\'" string)))
+  (or (string= string "")
+      (save-match-data (string-match "\\`[ \t\n]+\\'" string))))
 
 (defun ielm-format-errors (errlist)
   (let ((result ""))
@@ -473,11 +474,12 @@
 (defun ielm-get-old-input nil
   ;; Return the previous input surrounding point
   (save-excursion
-    (beginning-of-line)
-    (if (looking-at comint-prompt-regexp) nil
-      (re-search-backward comint-prompt-regexp))
-    (comint-skip-prompt)
-    (buffer-substring (point) (progn (forward-sexp 1) (point)))))
+    (save-match-data
+      (beginning-of-line)
+      (if (looking-at comint-prompt-regexp) nil
+        (re-search-backward comint-prompt-regexp))
+      (comint-skip-prompt)
+      (buffer-substring (point) (progn (forward-sexp 1) (point))))))
 
 ;;; User command
 
Index: emacs-lisp/pp.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/emacs-lisp/pp.el,v
retrieving revision 1.18
diff -u -r1.18 pp.el
--- emacs-lisp/pp.el	14 Feb 2002 16:47:11 -0000	1.18
+++ emacs-lisp/pp.el	21 Feb 2002 11:03:35 -0000
@@ -44,7 +44,7 @@
   (save-excursion
     (set-buffer (generate-new-buffer " pp-to-string"))
     (unwind-protect
-	(progn
+	(save-match-data
 	  (lisp-mode-variables nil)
 	  (set-syntax-table emacs-lisp-mode-syntax-table)
 	  (let ((print-escape-newlines pp-escape-newlines)
@@ -136,17 +136,18 @@
   (let ((stab (syntax-table)) (pt (point)) start exp)
     (set-syntax-table emacs-lisp-mode-syntax-table)
     (save-excursion
-      (forward-sexp -1)
-      ;; If first line is commented, ignore all leading comments:
-      (if (save-excursion (beginning-of-line) (looking-at "[ \t]*;"))
-	  (progn
-	    (setq exp (buffer-substring (point) pt))
-	    (while (string-match "\n[ \t]*;+" exp start)
-	      (setq start (1+ (match-beginning 0))
-		    exp (concat (substring exp 0 start)
-				(substring exp (match-end 0)))))
-	    (setq exp (read exp)))
-	(setq exp (read (current-buffer)))))
+      (save-match-data
+        (forward-sexp -1)
+        ;; If first line is commented, ignore all leading comments:
+        (if (save-excursion (beginning-of-line) (looking-at "[ \t]*;"))
+            (progn
+              (setq exp (buffer-substring (point) pt))
+              (while (string-match "\n[ \t]*;+" exp start)
+                (setq start (1+ (match-beginning 0))
+                      exp (concat (substring exp 0 start)
+                                  (substring exp (match-end 0)))))
+              (setq exp (read exp)))
+          (setq exp (read (current-buffer))))))
     (set-syntax-table stab)
     (if arg
 	(insert (pp-to-string (eval exp)))


_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-21 11:36 save-match-data woes Juanma Barranquero
@ 2002-02-21 11:54 ` Eli Zaretskii
  2002-02-22 16:43 ` Stefan Monnier
  1 sibling, 0 replies; 11+ messages in thread
From: Eli Zaretskii @ 2002-02-21 11:54 UTC (permalink / raw)
  Cc: emacs-devel


On Thu, 21 Feb 2002, Juanma Barranquero wrote:

> >From a recent change to bibtex.el by Eli I suppose the intent is to make
> functions preserve match data unless their interface specifically says
> they don't.

Yes, I think this is true.

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-21 11:36 save-match-data woes Juanma Barranquero
  2002-02-21 11:54 ` Eli Zaretskii
@ 2002-02-22 16:43 ` Stefan Monnier
  2002-02-23  5:26   ` Richard Stallman
  2002-02-25  8:10   ` Juanma Barranquero
  1 sibling, 2 replies; 11+ messages in thread
From: Stefan Monnier @ 2002-02-22 16:43 UTC (permalink / raw)
  Cc: emacs-devel

> I was trying something with ielm (which I use a lot), and found that:
> 
> ELISP> (setq var "12334")
> "12334"
> ELISP> (string-match "34+" var)
> 3
> ELISP> (match-data)
> (3 5)
> 
> ELISP> (match-data)
> (0 0)
> 
> After digging around I've found that ielm has non-protected calls to
> string-match and looking-for, and is also calling pp-to-string, which
> does not preserve the match data either.
> 
> From a recent change to bibtex.el by Eli I suppose the intent is to make
> functions preserve match data unless their interface specifically says
> they don't.

I think this is a wrong approach.  The match-data need only be saved
in a few particular circumstances and I'd rather handle those cases
in a special way.

For ielm, the problem is that the user might invoke any random command
between two inputs, so fixing M-p and M-n is not enough.  Also fixing
"any random command" is just not possible since that command might not
even be part of Emacs.

I.e. it seems better to fix ielm to save the match data before calling
the pretty printer and to restore it before executing the next command.
See patch below.  Any objection ?


	Stefan


--- ielm.el.~1.22.~	Wed Oct 11 17:26:53 2000
+++ ielm.el	Fri Feb 22 11:40:15 2002
@@ -103,6 +103,9 @@
 (defvar *** nil
   "Third-most-recent value evaluated in IELM.")
 
+(defvar ielm-match-data nil
+  "Match data saved at the end of last command.")
+
 ;;; System variables
 
 (defvar ielm-working-buffer nil
@@ -313,6 +316,7 @@
 		  (let ((*save *)
 			(**save **)
 			(***save ***))
+		    (set-match-data ielm-match-data)
 		    (save-excursion
 		      (set-buffer ielm-working-buffer)
 		      (condition-case err
@@ -330,7 +334,8 @@
 			(error (setq ielm-result (ielm-format-error err))
 			       (setq ielm-error-type "Eval error"))
 			(quit (setq ielm-result "Quit during evaluation")
-			      (setq ielm-error-type "Eval error")))))
+			      (setq ielm-error-type "Eval error"))))
+		    (setq ielm-match-data (match-data)))
 		(setq ielm-error-type "IELM error")
 		(setq ielm-result "More than one sexp in input"))))
 
@@ -451,6 +456,7 @@
   (make-local-variable '**)
   (setq *** nil)
   (make-local-variable '***)
+  (set (make-local-variable 'ielm-match-data) nil)
 
   ;; font-lock support
   (make-local-variable 'font-lock-defaults)


_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-22 16:43 ` Stefan Monnier
@ 2002-02-23  5:26   ` Richard Stallman
  2002-02-25  8:10   ` Juanma Barranquero
  1 sibling, 0 replies; 11+ messages in thread
From: Richard Stallman @ 2002-02-23  5:26 UTC (permalink / raw)
  Cc: lektu, emacs-devel

This seems clean--please install it.

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-22 16:43 ` Stefan Monnier
  2002-02-23  5:26   ` Richard Stallman
@ 2002-02-25  8:10   ` Juanma Barranquero
  2002-02-25  8:21     ` Stefan Monnier
  2002-02-26 20:14     ` Richard Stallman
  1 sibling, 2 replies; 11+ messages in thread
From: Juanma Barranquero @ 2002-02-25  8:10 UTC (permalink / raw)
  Cc: emacs-devel


On Fri, 22 Feb 2002 11:43:03 -0500, "Stefan Monnier" <monnier+gnu/emacs@RUM.cs.yale.edu> wrote:

> I think this is a wrong approach.  The match-data need only be saved
> in a few particular circumstances and I'd rather handle those cases
> in a special way.

Well, I'm not so sure about the "few particular circumstances". I think
is bad for a function to arbitrarily change the match data and not
saving it and not even documenting that it does modify it. That's bound
to cause trouble somewhere far away, where perhaps the trouble won't be
so easily connected with match data. I have no hard data, but my gut
feeling is that you will end saving/restoring match-data in many places
just to protect you against the relatively few functions that do not do
that now. What if one of your elisp modules is safely using a function
in another module and its maintainer just modifies slightly the
implementation, using now pp-to-string where he didn't before? Probably
you weren't saving match data because you didn't see the reason... and I
fail to see *why* you should have any reason now. It is not you who
changed anything.

> For ielm, the problem is that the user might invoke any random command
> between two inputs, so fixing M-p and M-n is not enough.

You're right. In the case of ielm.el, your fix is much better than mine.

(Unrelated:) On the matter of ielm, is there any objection to my patch
of a few days back that makes ielm-prompt customizable and read-only?


                                                           /L/e/k/t/u


_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-25  8:10   ` Juanma Barranquero
@ 2002-02-25  8:21     ` Stefan Monnier
  2002-02-25 10:19       ` Juanma Barranquero
  2002-02-26 20:15       ` Richard Stallman
  2002-02-26 20:14     ` Richard Stallman
  1 sibling, 2 replies; 11+ messages in thread
From: Stefan Monnier @ 2002-02-25  8:21 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

> 
> On Fri, 22 Feb 2002 11:43:03 -0500, "Stefan Monnier" <monnier+gnu/emacs@RUM.cs.yale.edu> wrote:
> 
> > I think this is a wrong approach.  The match-data need only be saved
> > in a few particular circumstances and I'd rather handle those cases
> > in a special way.
> 
> Well, I'm not so sure about the "few particular circumstances". I think
> is bad for a function to arbitrarily change the match data and not
> saving it and not even documenting that it does modify it. That's bound
> to cause trouble somewhere far away, where perhaps the trouble won't be
> so easily connected with match data. I have no hard data, but my gut
> feeling is that you will end saving/restoring match-data in many places
> just to protect you against the relatively few functions that do not do
> that now. What if one of your elisp modules is safely using a function
> in another module and its maintainer just modifies slightly the
> implementation, using now pp-to-string where he didn't before? Probably
> you weren't saving match data because you didn't see the reason... and I
> fail to see *why* you should have any reason now. It is not you who
> changed anything.

My experience is quite different: the match data is in 99% of the cases
used right after a call to a regexp-match function, with almost no
other functions called inbetween apart from some very primitive ones.

Why this is so is because many functions do regexp-matching and thus
destroy the match-data: the match-data is just very volatile.  Another
reason why it's volatile is because any buffer modification can make
the match-data stale.

There are cases where it is important for the match-data to be preserved,
most notably in file-name-handlers (since various pieces of code rely
on the fact that the default implementation of file operations do not
do any regexp-matching).  But for most other cases, preserving the
match-data is just a waste of time and it's almost always easier to
use the match-data right after pattern-matching rather than rely on
the match-data being preserved (and still meaningful) by a function
whose behavior might be changed without your knowing.

> (Unrelated:) On the matter of ielm, is there any objection to my patch
> of a few days back that makes ielm-prompt customizable and read-only?

I don't have any, hence my non-response.


	Stefan


_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-25  8:21     ` Stefan Monnier
@ 2002-02-25 10:19       ` Juanma Barranquero
  2002-02-26 20:15       ` Richard Stallman
  1 sibling, 0 replies; 11+ messages in thread
From: Juanma Barranquero @ 2002-02-25 10:19 UTC (permalink / raw)
  Cc: emacs-devel


On Mon, 25 Feb 2002 03:21:07 -0500, "Stefan Monnier" <monnier+gnu/emacs@RUM.cs.yale.edu> wrote:

> My experience is quite different: the match data is in 99% of the cases
> used right after a call to a regexp-match function, with almost no
> other functions called inbetween apart from some very primitive ones.

I think (after a cursory look to lisp/*.el) you're right.


                                                           /L/e/k/t/u


_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-25  8:10   ` Juanma Barranquero
  2002-02-25  8:21     ` Stefan Monnier
@ 2002-02-26 20:14     ` Richard Stallman
  1 sibling, 0 replies; 11+ messages in thread
From: Richard Stallman @ 2002-02-26 20:14 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

    (Unrelated:) On the matter of ielm, is there any objection to my patch
    of a few days back that makes ielm-prompt customizable and read-only?

It seems good to me.

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-25  8:21     ` Stefan Monnier
  2002-02-25 10:19       ` Juanma Barranquero
@ 2002-02-26 20:15       ` Richard Stallman
  2002-02-27 10:00         ` Eli Zaretskii
  1 sibling, 1 reply; 11+ messages in thread
From: Richard Stallman @ 2002-02-26 20:15 UTC (permalink / raw)
  Cc: lektu, monnier+gnu/emacs, emacs-devel

    My experience is quite different: the match data is in 99% of the cases
    used right after a call to a regexp-match function, with almost no
    other functions called inbetween apart from some very primitive ones.

That is my experience too.

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-26 20:15       ` Richard Stallman
@ 2002-02-27 10:00         ` Eli Zaretskii
  2002-02-28  4:08           ` Richard Stallman
  0 siblings, 1 reply; 11+ messages in thread
From: Eli Zaretskii @ 2002-02-27 10:00 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, lektu, emacs-devel


On Tue, 26 Feb 2002, Richard Stallman wrote:

>     My experience is quite different: the match data is in 99% of the cases
>     used right after a call to a regexp-match function, with almost no
>     other functions called inbetween apart from some very primitive ones.
> 
> That is my experience too.

That's true for application code, but what about functions that
implement core functionality?  The latter can be run from unusual
places, like all kinds of hooks we have around, in which case it
should preserve the match data, right?

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: save-match-data woes
  2002-02-27 10:00         ` Eli Zaretskii
@ 2002-02-28  4:08           ` Richard Stallman
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Stallman @ 2002-02-28  4:08 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, lektu, emacs-devel

    That's true for application code, but what about functions that
    implement core functionality?  The latter can be run from unusual
    places, like all kinds of hooks we have around, in which case it
    should preserve the match data, right?

Some functions have the spirit of a general-purpose facility.  People
will expect those functions to be "clean"--in various ways, so we need
to make them so.  But it is not worth making all functions be "clean"
like that, and people won't expect it.


_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/emacs-devel


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2002-02-28  4:08 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-02-21 11:36 save-match-data woes Juanma Barranquero
2002-02-21 11:54 ` Eli Zaretskii
2002-02-22 16:43 ` Stefan Monnier
2002-02-23  5:26   ` Richard Stallman
2002-02-25  8:10   ` Juanma Barranquero
2002-02-25  8:21     ` Stefan Monnier
2002-02-25 10:19       ` Juanma Barranquero
2002-02-26 20:15       ` Richard Stallman
2002-02-27 10:00         ` Eli Zaretskii
2002-02-28  4:08           ` Richard Stallman
2002-02-26 20:14     ` Richard Stallman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).