emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] emacs/lisp/mail mailabbrev.el


From: Chong Yidong
Subject: [Emacs-diffs] emacs/lisp/mail mailabbrev.el
Date: Tue, 25 Nov 2008 22:58:01 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Chong Yidong <cyd>      08/11/25 22:58:01

Modified files:
        lisp/mail      : mailabbrev.el 

Log message:
        (define-mail-abbrev): When reading from mailrc, recognize string
        quoting.  When reading from Lisp, accept rfc822-like addresses.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/emacs/lisp/mail/mailabbrev.el?cvsroot=emacs&r1=1.90&r2=1.91

Patches:
Index: mailabbrev.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/mail/mailabbrev.el,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -b -r1.90 -r1.91
--- mailabbrev.el       27 Jun 2008 07:34:49 -0000      1.90
+++ mailabbrev.el       25 Nov 2008 22:58:01 -0000      1.91
@@ -261,7 +261,12 @@
 ;;;###autoload
 (defun define-mail-abbrev (name definition &optional from-mailrc-file)
   "Define NAME as a mail alias abbrev that translates to DEFINITION.
-If DEFINITION contains multiple addresses, separate them with commas."
+If DEFINITION contains multiple addresses, separate them with commas.
+
+Optional argument FROM-MAILRC-FILE means that DEFINITION comes
+from a mailrc file.  In that case, addresses are separated with
+spaces and addresses with embedded spaces are surrounded by
+double-quotes."
   ;; When this is called from build-mail-abbrevs, the third argument is
   ;; true, and we do some evil space->comma hacking like /bin/mail does.
   (interactive "sDefine mail alias: \nsDefine %s as mail alias for: ")
@@ -272,33 +277,62 @@
       (setq definition (substring definition (match-end 0))))
   (if (string-match "[ \t\n,]+\\'" definition)
       (setq definition (substring definition 0 (match-beginning 0))))
-  (let* ((result '())
-        (L (length definition))
+  (let* ((L (length definition))
         (start (if (> L 0) 0))
-        end)
+        end this-entry result)
     (while start
-      ;; If we're reading from the mailrc file, then addresses are delimited
-      ;; by spaces, and addresses with embedded spaces must be surrounded by
-      ;; double-quotes.  Otherwise, addresses are separated by commas.
-      (if from-mailrc-file
+      (cond
+       (from-mailrc-file
+       ;; If we're reading from the mailrc file, addresses are
+       ;; delimited by spaces, and addresses with embedded spaces are
+       ;; surrounded by non-escaped double-quotes.
          (if (eq ?\" (aref definition start))
              (setq start (1+ start)
-                   end (string-match "\"[ \t,]*" definition start))
+                 end (and (string-match
+                           "[^\\]\\(\\([\\][\\]\\)*\\)\"[ \t,]*"
+                           definition start)
+                          (match-end 1)))
            (setq end (string-match "[ \t,]+" definition start)))
-       (setq end (string-match "[ \t\n,]*,[ \t\n,]*" definition start)))
-      (let ((tem (substring definition start end)))
+       ;; Extract the address and advance the loop past it.
+       (setq this-entry (substring definition start end)
+             start (and end (/= (match-end 0) L) (match-end 0)))
+       ;; If the full name contains a problem character, quote it.
+       (and (string-match "\\(.+?\\)[ \t]*\\(<.*>\\)" this-entry)
+            (string-match "[^- !#$%&'*+/0-9=?A-Za-z^_`{|}~]"
+                          (match-string 1 this-entry))
+            (setq this-entry (replace-regexp-in-string
+                              "\\(.+?\\)[ \t]*\\(<.*>\\)"
+                              "\"\\1\" \\2"
+                              this-entry)))
+       (push this-entry result))
+       ;; When we are not reading from .mailrc, addresses are
+       ;; separated by commas.  Try to accept a rfc822-like syntax.
+       ;; (Todo: extend rfc822.el to do the work for us.)
+       ((equal (string-match
+               "[ \t,]*\\(\"\\(?:[^\"]\\|[^\\]\\(?:[\\][\\]\\)*\"\\)*\"[ \t]*\
+<[-.!#$%&'*+/0-9=?A-Za-z^_`{|address@hidden>\\)[ \t,]*"
+               definition start)
+              start)
+       ;; If an entry has a valid [ "foo bar" <address@hidden> ]
+       ;; form, use it literally .  This also allows commas in the
+       ;; quoted string, e.g.  [ "foo bar, jr" <address@hidden> ]
+       (push (match-string 1 definition) result)
+       (setq start (and (/= (match-end 0) L) (match-end 0))))
+       (t
+       ;; Otherwise, read the next address by looking for a comma.
+       (setq end (string-match "[ \t\n,]*,[ \t\n]*" definition start))
+       (setq this-entry (substring definition start end))
        ;; Advance the loop past this address.
-       (setq start (and end
-                        (/= (match-end 0) L)
-                        (match-end 0)))
+       (setq start (and end (/= (match-end 0) L) (match-end 0)))
        ;; If the full name contains a problem character, quote it.
-       (when (string-match "\\(.+?\\)[ \t]*\\(<.*>\\)" tem)
-         (if (string-match "[^- !#$%&'*+/0-9=?A-Za-z^_`{|}~]"
-                           (match-string 1 tem))
-             (setq tem (replace-regexp-in-string
+       (and (string-match "\\(.+?\\)[ \t]*\\(<.*>\\)" this-entry)
+            (string-match "[^- !#$%&'*+/0-9=?A-Za-z^_`{|}~]"
+                          (match-string 1 this-entry))
+            (setq this-entry (replace-regexp-in-string
                         "\\(.+?\\)[ \t]*\\(<.*>\\)" "\"\\1\" \\2"
-                        tem))))
-       (push tem result)))
+                              this-entry)))
+       (push this-entry result))))
+
     (setq definition (mapconcat (function identity)
                                (nreverse result)
                                mail-alias-separator-string)))




reply via email to

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