all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* avoid interpretation of \n, \t, ... in string
@ 2009-01-27 17:13 Peter Tury
  2009-01-27 18:26 ` Peter Dyballa
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Peter Tury @ 2009-01-27 17:13 UTC (permalink / raw)
  To: help-gnu-emacs

Hi,

I would like to pass paths to shell (extrenal command line programs)
on MS Windows. The paths may contain \n, \t etc. (Eg. c:
\directory-1\new-dir\temp...). However, the string is "evaluated" and
only the result arrives to the shell program. (In the above example: c:
\directory-1
ew-dir	emp...)

I try to use `call-process-shell-command'.

I know I could use double back-slash (e.g. c:\directory-1\\new-dir\
\temp...), but I want to be able to handle any paths in their
"natural" form. How to do it?

Thanks,
P


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

* Re: avoid interpretation of \n, \t, ... in string
  2009-01-27 17:13 avoid interpretation of \n, \t, ... in string Peter Tury
@ 2009-01-27 18:26 ` Peter Dyballa
       [not found] ` <mailman.5991.1233080786.26697.help-gnu-emacs@gnu.org>
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Peter Dyballa @ 2009-01-27 18:26 UTC (permalink / raw)
  To: Peter Tury; +Cc: help-gnu-emacs


Am 27.01.2009 um 18:13 schrieb Peter Tury:

> I would like to pass paths to shell (extrenal command line programs)
> on MS Windows. The paths may contain \n, \t etc.

Why? For what?

> (Eg. c:\directory-1\new-dir\temp...).


You can use / here ...

--
Greetings

   Pete

And always remember the last words of my grandfather, who said: “A  
truck!”
				— Emo Phillips







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

* Re: avoid interpretation of \n, \t, ... in string
       [not found] ` <mailman.5991.1233080786.26697.help-gnu-emacs@gnu.org>
@ 2009-01-27 18:38   ` Peter Tury
  0 siblings, 0 replies; 8+ messages in thread
From: Peter Tury @ 2009-01-27 18:38 UTC (permalink / raw)
  To: help-gnu-emacs

Hi,

thanks for the tip, but it doesn't work in this case. I want to pass
"vob tags" to clearcase to mount. cleartool doesn't accept "/" instead
of "\" :-(
(vob tags look like simple paths, that is why I wrote about paths
above)

Thanks,
P


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

* Re: avoid interpretation of \n, \t, ... in string
  2009-01-27 17:13 avoid interpretation of \n, \t, ... in string Peter Tury
  2009-01-27 18:26 ` Peter Dyballa
       [not found] ` <mailman.5991.1233080786.26697.help-gnu-emacs@gnu.org>
@ 2009-01-28  7:52 ` Kevin Rodgers
  2009-01-28  9:59 ` Pascal J. Bourguignon
       [not found] ` <mailman.6050.1233129149.26697.help-gnu-emacs@gnu.org>
  4 siblings, 0 replies; 8+ messages in thread
From: Kevin Rodgers @ 2009-01-28  7:52 UTC (permalink / raw)
  To: help-gnu-emacs

Peter Tury wrote:
> I would like to pass paths to shell (extrenal command line programs)
> on MS Windows. The paths may contain \n, \t etc. (Eg. c:
> \directory-1\new-dir\temp...). However, the string is "evaluated" and
> only the result arrives to the shell program. (In the above example: c:
> \directory-1
> ew-dir	emp...)
> 
> I try to use `call-process-shell-command'.
> 
> I know I could use double back-slash (e.g. c:\directory-1\\new-dir\
> \temp...), but I want to be able to handle any paths in their
> "natural" form. How to do it?

Where do these strings come from?

-- 
Kevin Rodgers
Denver, Colorado, USA





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

* Re: avoid interpretation of \n, \t, ... in string
  2009-01-27 17:13 avoid interpretation of \n, \t, ... in string Peter Tury
                   ` (2 preceding siblings ...)
  2009-01-28  7:52 ` Kevin Rodgers
@ 2009-01-28  9:59 ` Pascal J. Bourguignon
  2009-01-28 12:24   ` Peter Tury
       [not found] ` <mailman.6050.1233129149.26697.help-gnu-emacs@gnu.org>
  4 siblings, 1 reply; 8+ messages in thread
From: Pascal J. Bourguignon @ 2009-01-28  9:59 UTC (permalink / raw)
  To: help-gnu-emacs

Peter Tury <tury.peter@gmail.com> writes:
> I would like to pass paths to shell (extrenal command line programs)
> on MS Windows. The paths may contain \n, \t etc. (Eg. c:
> \directory-1\new-dir\temp...). However, the string is "evaluated" and
> only the result arrives to the shell program. (In the above example: c:
> \directory-1
> ew-dir	emp...)
>
> I try to use `call-process-shell-command'.
>
> I know I could use double back-slash (e.g. c:\directory-1\\new-dir\
> \temp...), but I want to be able to handle any paths in their
> "natural" form. How to do it?


Switch to Common Lisp.  There's no reader macro in emacs lisp, so you
cannot do much about it.  In Common Lisp, you can trivially implement
a reader macro to read strings with no, or with a different escape
character.  And there are also various "emacsen" written in Common
Lisp ;-)



Ok, another way to do it would be to store your paths in a file, and
to read it:

(defun read-paths (file)
  (with-temp-buffer
    (insert-file-contents file)
    (delete "" (split-string (buffer-substring-no-properties
                              (point-min) (point-max))
                   "[\n\r]+"))))

Then with a file dirs.txt containing:

c:\test\directory\file.txt
D:\ANOTHER\DIRECTORY\FILE.TXT
RELATIVE\DIRECTORY\FILE.TXT


(read-paths "dirs.txt")
--> ("c:\\test\\directory\\file.txt" "D:\\ANOTHER\\DIRECTORY\\FILE.TXT" "RELATIVE\\DIRECTORY\\FILE.TXT")




Note that this is a serrious proposition. Myself, I use a
directories.txt file containing keyed paths:

KEY        /some/dir
OTHER_KEY  /some/other/dir

that I read with:

(defvar *directories* '())

(defun get-directory (key &optional subpath)
  (setf subpath (or subpath ""))
  (unless  (getf *directories* key)
    (error "get-directory: No directory keyed %s" key))
  (concat (getf *directories* key) subpath))

(defun load-directories ()
  (interactive)
  (setf *directories*
        (progn
          (find-file "~/directories.txt")
          (prog1
              (loop
                 for (k v)
                 on (split-string (buffer-substring-no-properties
                                   (point-min) (point-max)))
                 by (function cddr)
                 nconc (list (intern
                              (format ":%s"
                                      (substitute ?- ?_ (downcase k))))
                             v))
            (kill-buffer (current-buffer))))))

(load-directories)

in emacs lisp, and something similar in Common Lisp, and with '~/bin/get-directory':

#!/bin/bash
awk '/^ *'"$1"'  */{print $2}' ~/directories.txt

in shell:

    get-directory HYPERSPEC
--> /usr/share/doc/hyperspec/HyperSpec/


so I can write all my scripts, whatever the language, independently of
any directory location, and thus they can run identically on the
various systems I use (each having its own ~/directories.txt file with
its specific directories).

-- 
__Pascal Bourguignon__


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

* Re: avoid interpretation of \n, \t, ... in string
       [not found] ` <mailman.6050.1233129149.26697.help-gnu-emacs@gnu.org>
@ 2009-01-28 10:16   ` Peter Tury
  0 siblings, 0 replies; 8+ messages in thread
From: Peter Tury @ 2009-01-28 10:16 UTC (permalink / raw)
  To: help-gnu-emacs

Hi,

On Jan 28, 8:52 am, Kevin Rodgers <kevin.d.rodg...@gmail.com> wrote:

> Where do these strings come from?

You see the key! I would like to have my "elisp script" usable by
people knowing nothing about Emacs. That is why I would like to avoid
the evident solution: work as if paths are always in correct elisp
form (i.e., in the example above: "c:\\directory-1\\new-dir\\temp").

While I type the paths myself I can put the extra backslashes of
course. However, it would be nice to have this functionality
automated.

At first step the paths would come from .el files, e.g. one elisp
function would get a list of paths, so when you call it you should
pass something like `(list "c:\\directory-1\\new-dir\\temp")'. Later
they might come from external .txt files...

Thanks,
P


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

* Re: avoid interpretation of \n, \t, ... in string
  2009-01-28  9:59 ` Pascal J. Bourguignon
@ 2009-01-28 12:24   ` Peter Tury
  2009-01-28 14:02     ` Pascal J. Bourguignon
  0 siblings, 1 reply; 8+ messages in thread
From: Peter Tury @ 2009-01-28 12:24 UTC (permalink / raw)
  To: help-gnu-emacs

Hi,

Pascal J. Bourguignon wrote:

> Switch to Common Lisp.  There's no reader macro in emacs lisp, so you
> cannot do much about it.  In Common Lisp, you can trivially implement

I think this will be a longer journey sometime in the future. CL is on
my "todo" list for some time ;-)

> Ok, another way to do it would be to store your paths in a file, and
> to read it:
>
> (defun read-paths (file)
>   (with-temp-buffer
>     (insert-file-contents file)
>     (delete "" (split-string (buffer-substring-no-properties
>                               (point-min) (point-max))
>                    "[\n\r]+"))))

Great, thanks!
I've checked it and found that in fact `buffer-substring-no-
properties' does the trick here. So my original question can be
reformulated now:

---> is there a way to get string (text) representation in a form as
`buffer-substring-no-properties' do it, i.e. duplicating single `\'-s
automatically (without(!) interpreting "pseudo-escape-sequences" (\n,
\t, ...) in the original text)?

BTW
when we come to external files (e.g. directories.txt) I have to
mention that my current workaround is to automate the problematic step
outside of Emacs: I have a simple .bat file (what does the vob
mounting) and call it from Emacs...

> Note that this is a serrious proposition. Myself, I use a
[...]
> so I can write all my scripts, whatever the language, independently of
> any directory location, and thus they can run identically on the

Very nice, thanks for the idea! I'll keep this way-of-working in my
mind.

Thanks,
P


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

* Re: avoid interpretation of \n, \t, ... in string
  2009-01-28 12:24   ` Peter Tury
@ 2009-01-28 14:02     ` Pascal J. Bourguignon
  0 siblings, 0 replies; 8+ messages in thread
From: Pascal J. Bourguignon @ 2009-01-28 14:02 UTC (permalink / raw)
  To: help-gnu-emacs

Peter Tury <tury.peter@gmail.com> writes:

> Hi,
>
> Pascal J. Bourguignon wrote:
>
>> Switch to Common Lisp.  There's no reader macro in emacs lisp, so you
>> cannot do much about it.  In Common Lisp, you can trivially implement
>
> I think this will be a longer journey sometime in the future. CL is on
> my "todo" list for some time ;-)
>
>> Ok, another way to do it would be to store your paths in a file, and
>> to read it:
>>
>> (defun read-paths (file)
>>   (with-temp-buffer
>>     (insert-file-contents file)
>>     (delete "" (split-string (buffer-substring-no-properties
>>                               (point-min) (point-max))
>>                    "[\n\r]+"))))
>
> Great, thanks!
> I've checked it and found that in fact `buffer-substring-no-
> properties' does the trick here. So my original question can be
> reformulated now:
>
> ---> is there a way to get string (text) representation in a form as
> `buffer-substring-no-properties' do it, i.e. duplicating single `\'-s
> automatically (without(!) interpreting "pseudo-escape-sequences" (\n,
> \t, ...) in the original text)?

buffer-substring-no-properties doesn't do anything.  There is
absolutely no duplicating of any character.

Try to understand that there is only one character in the string "\\".

(length "\\") --> 1

  (insert (format "%s %S" "\\" "\\")) 

inserts:

  \ "\\"


The double backslash comes from the string quoting.

Here are some characters:  abc'\"def

Now the problem is to quote these characters to be able to put them in
a program, as a string literal, so they aren't interpreted as code.
We do that by surrounding the characters with double-quotes:

                          "abc'\"def"

Oops!  That is broken because one of these characters is a
double-quote, so we'd interpret that as the string containing the
characters:
                           abc'\
followed by the symbol named:   def
and a stray double-quote           "

The problem here is that we'd need a way to escape the meaning of the
double-quote, so it doesn't mean anymore to close the string literal.
The idea is to use an 'escape' character, back-slash.

                          "abc'\\"def"

Oops!  Still a problem here.  Since there is also a back-slash in the
string, it needs to be escaped too, otherwise we will consider it
escapes the following character...

                          "abc'\\\"def"

Ok, so now we can tell that this is a string literal because of the
opening double-quote:     "
that contains the normal characters:
                           abc'                            *
then an escaped character prefixed by:
                               \
which is a back-slash character itself:
                                \                          *
then an escaped character prefixed by:
                                  \
which is a double-quote character itself:
                                   "                       *
followed by the normal characters:  def                    *
and closed by a double-quote:          "

So finally, this string literal only contains the characters:
                           abc'\"def


This algorithm of reading string literals is implemented by the emacs
lisp reader.  And of course, when you want to print (format) a string,
you can either output the characters contained in the string (format
"%s" ...), princ), or output characters that will be read a string
literal, with double-quotes and escaping back-slashes (format "%S"
...), prin1, print).

(let ((string "abc with escape: \\ and with substring: \"abc\"."))
   (terpri)
   (princ "with princ: ") (princ string)
   (terpri)
   (princ "with prin1: ") (prin1 string)
   (terpri)
   (princ "with print: ") (print string)
   (terpri))

inserts:

with princ: abc with escape: \ and with substring: "abc".
with prin1: "abc with escape: \\ and with substring: \"abc\"."
with print: 
"abc with escape: \\ and with substring: \"abc\"."

returns: t  
   
The double-quotes and back-slashes are added by prin1 and print just
to allow reading back data that has been printed.







The Common Lisp reader algorithms is more sophisticated, it allows for
hooks called reader macros, which let you implement your own string
reading algorithm.  For example, you could change the escaping
character, or not have any, and this would let  you write strings
containing back-slashes.

We would have to change the function read1 in lread.c to add this
feature.  Unfortunately we cannot just redefine in emeacs lisp such a
function, because all the code written in C is already linked to the
old function written in C, and wouldn't use our implementation in
emacs lisp.  We would have to modify the C sources (and have the patch
accepted by RMS).


-- 
__Pascal Bourguignon__


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

end of thread, other threads:[~2009-01-28 14:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-27 17:13 avoid interpretation of \n, \t, ... in string Peter Tury
2009-01-27 18:26 ` Peter Dyballa
     [not found] ` <mailman.5991.1233080786.26697.help-gnu-emacs@gnu.org>
2009-01-27 18:38   ` Peter Tury
2009-01-28  7:52 ` Kevin Rodgers
2009-01-28  9:59 ` Pascal J. Bourguignon
2009-01-28 12:24   ` Peter Tury
2009-01-28 14:02     ` Pascal J. Bourguignon
     [not found] ` <mailman.6050.1233129149.26697.help-gnu-emacs@gnu.org>
2009-01-28 10:16   ` Peter Tury

Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.