emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

format conversion and local variables


From: Stephen Berman
Subject: format conversion and local variables
Date: Tue, 17 Oct 2006 23:02:33 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

I'm working on a library that uses format conversion and I would like
to have a variable that undergoes format conversion be able to take on
different values in different buffers.  It doesn't work to make the
variable buffer-local, I guess because the decoding is attempted
before the file is loaded into a buffer, hence the variable cannot be
given a buffer-local value before it is decoded (is that right?).  So
I thought the next best alternative is to use file local variables.
But this also doesn't work, though there's a difference depending on
how the variables are specified: with a local variables list, when I
invoke find-file, Emacs apparently goes into an infinite loop (see
below); but when the local variables are specified on the first line
of the file, find-file succeeds but no format conversion happens.  I
don't know whether this behavior is expected or I'm coding the format
conversion wrong or there is an Emacs bug.

Here's a scenario to illustrate and expand on the above.  Save the
following text to a file, e.g. fc-test0:
--------------8<--------------
SRB_ENCODED

This is a test of format conversion.
-------------->8--------------

and save this to fc-test1:
--------------8<--------------
SRB_ENCODED

This is a test of format conversion.

Local Variables:
srb-decoding-string: "SRB_DECODED"
srb-encoding-string: "SRB_ENCODED"
End:
-------------->8--------------

and save this to fc-test2:
--------------8<--------------
-*- srb-decoding-string: "SRB_DECODED"; srb-encoding-string: "SRB_ENCODED"; -*-

SRB_ENCODED

This is a test of format-alist.
-------------->8--------------

And save the following to fc-test.el:
--------------8<--------------
(add-to-list
 'format-alist
 (list 'srb-test "Test format-alist." "SRB_ENCODED" 'srb-decode-region
       'srb-encode-region t nil))

(defvar srb-decoding-string nil)
(defvar srb-encoding-string nil)

;; (make-variable-buffer-local 'srb-decoding-string)
;; (make-variable-buffer-local 'srb-encoding-string)

(defun srb-decode-region (beg end)
  "Test format-alist decoding."
  (if srb-encoding-string
      (while (search-forward srb-encoding-string (point-max) t)
        (replace-match srb-decoding-string)))
  end)
  
(defun srb-encode-region (beg end &optional buffer)
  "Test format-alist encoding."
  (if srb-decoding-string
      (while (search-forward srb-decoding-string (point-max) t)
        (replace-match srb-encoding-string)))
  end)
-------------->8--------------

First, the sanity test: start emacs -Q, load fc-test.el, then do `M-:
(setq srb-decoding-string "SRB_DECODED")' and `M-x: (setq
srb-encoding-string "SRB_ENCODED")' and then `C-x C-f fc-test0'.  The
resulting buffer visiting fc-test0 shows the format conversion, as
expected: 
--------------8<--------------
SRB_DECODED

This is a test of format conversion.
-------------->8--------------
(In contrast, visiting fc-test0 with find-file-literally shows it
without format conversion, as expected.)

Now do `C-x C-f fc-test1' and Emacs asks if you want to apply the
local variables, and then visits the file with format conversion --
whether you apply the local variables or not.  That is, the local
binding has no effect, the conversion is due to the global binding
still in effect.

Now do `C-x C-f fc-test2' and Emacs again asks if you want to apply
the local variables, but then visits the file without format
conversion, regardless of how you answer the question.

Now kill the buffers of fc-test0, fc-test1, and fc-test2 and do `M-:
(setq srb-decoding-string nil)' and `M-x: (setq srb-encoding-string
nil)'.  Now doing `C-x C-f fc-test2' is exactly as before: query about
applying local variables but no format conversion in any case.  But
with `C-x C-f fc-test1' it's different: Emacs goes into an infinite
loop as soon as it hits insert-file-contents in find-file-noselect-1.
I did this under gdb and set a breakpoint at Finsert_file_contents and
stepped through the code until line 4722 of fileio.c, where it hung:
(gdb) n
4722          insval = call3 (Qformat_decode,
(gdb) n
n
n
n

Program received signal SIGTSTP, Stopped (user).
0x0815c0f6 in internal_equal (o1=137439433, o2=137439433, depth=0, props=0)
    at fns.c:2173
2173      if (EQ (o1, o2))

By the way, the same infinite loop happens when trying to visit
fc-test0 with the two variables set to nil, as well as if they are
made buffer-local.

In view of these observations, I would like to know (i) if the
infinite loops are expected in the given circumstances and if so, why,
or if they indicate a bug, (ii) what accounts for the different
behavior of the two forms of file local variable specification, and
especially (iii) if there is a way to allow variables that occur in
format conversion, like srb-decoding-string and srb-encoding-string
above, to have different values in different buffers, or at least in
different files.

Steve Berman





reply via email to

[Prev in Thread] Current Thread [Next in Thread]