Fix typo.
[elisp/wanderlust.git] / elmo / elmo-util.el
index 970f39f..57f8277 100644 (file)
@@ -32,6 +32,8 @@
 (require 'elmo-vars)
 (require 'elmo-date)
 (eval-when-compile (require 'cl))
+(require 'mcharset)
+(require 'pces)
 (require 'std11)
 (require 'eword-decode)
 (require 'utf7)
@@ -235,6 +237,7 @@ File content is encoded with MIME-CHARSET."
        (setq auth (if (match-beginning 4)
                       (intern (elmo-match-substring 4 folder 1))
                     elmo-default-imap4-authenticate-type))
+       (setq auth (or auth 'clear))
        (append (list 'imap4
                      (elmo-imap4-encode-folder-string mailbox)
                      user auth)
@@ -418,6 +421,7 @@ File content is encoded with MIME-CHARSET."
       (setq auth (if (match-beginning 3)
                     (intern (elmo-match-substring 3 folder 1))
                   elmo-default-pop3-authenticate-type))
+      (setq auth (or auth 'user))
       (append (list 'pop3 user auth)
              (cdr spec)))))
 
@@ -472,6 +476,12 @@ File content is encoded with MIME-CHARSET."
          (elmo-match-string 2 folder)
          (elmo-match-string 3 folder))))
 
+(defsubst elmo-pipe-spec-src (spec)
+  (nth 1 spec))
+
+(defsubst elmo-pipe-spec-dst (spec)
+  (nth 2 spec))
+
 (defun elmo-folder-get-spec (folder)
   "Return spec of FOLDER."
   (let ((type (elmo-folder-get-type folder)))
@@ -500,7 +510,7 @@ File content is encoded with MIME-CHARSET."
                                   "Since" "Before" "ToCc"
                                   "!From" "!Subject" "!To" "!Cc" "!Body"
                                   "!Since" "!Before" "!ToCc")
-                                elmo-msgdb-extra-fields)) nil t))
+                                elmo-msgdb-extra-fields))))
         value)
     (setq field (if (string= field "")
                    (setq field default)
@@ -674,6 +684,20 @@ Return value is a cons cell of (STRUCTURE . REST)"
                                          (cdr tmp)))))))
   lst)
 
+(defun elmo-list-insert (list element after)
+  "Insert an ELEMENT to the LIST, just after AFTER."
+  (let ((li list)
+       (curn 0)
+       p pn)
+    (while li
+      (if (eq (car li) after)
+         (setq p li pn curn li nil)
+       (incf curn))
+      (setq li (cdr li)))
+    (if pn
+       (setcdr (nthcdr pn list) (cons element (cdr p)))
+      (nconc list (list element)))))
+
 (defun elmo-string-partial-p (string)
   (and (stringp string) (string-match "message/partial" string)))
 
@@ -1110,8 +1134,12 @@ Otherwise treat \\ in NEWTEXT string as special:
 
 (defun elmo-folder-local-p (folder)
   "Return whether FOLDER is a local folder or not."
-  (let ((type (elmo-folder-get-type folder)))
-    (memq type '(localdir localnews archive maildir internal cache))))
+  (let ((spec (elmo-folder-get-spec folder)))
+    (case (car spec)
+      (filter (elmo-folder-local-p (nth 2 spec)))
+      (pipe (elmo-folder-local-p (elmo-pipe-spec-dst spec)))
+      (t (memq (car spec)
+              '(localdir localnews archive maildir internal cache))))))
 
 (defun elmo-folder-writable-p (folder)
   (let ((type (elmo-folder-get-type folder)))
@@ -1230,6 +1258,14 @@ Otherwise treat \\ in NEWTEXT string as special:
        (t
         (elmo-folder-direct-copy-p folder1 folder2))))
 
+(defun elmo-folder-get-store-type (folder)
+  (let ((spec (elmo-folder-get-spec folder)))
+    (case (car spec)
+      (filter (elmo-folder-get-store-type (nth 2 spec)))
+      (pipe (elmo-folder-get-store-type (elmo-pipe-spec-dst spec)))
+      (multi (elmo-folder-get-store-type (nth 1 spec)))
+      (t (car spec)))))
+
 (defconst elmo-folder-direct-copy-alist
   '((localdir  . (localdir localnews archive))
     (maildir   . (maildir  localdir localnews archive))
@@ -1238,8 +1274,8 @@ Otherwise treat \\ in NEWTEXT string as special:
     (cache     . (localdir localnews archive))))
 
 (defun elmo-folder-direct-copy-p (src-folder dst-folder)
-  (let ((src-type (car (elmo-folder-get-spec src-folder)))
-       (dst-type (car (elmo-folder-get-spec dst-folder)))
+  (let ((src-type (elmo-folder-get-store-type src-folder))
+       (dst-type (elmo-folder-get-store-type dst-folder))
        dst-copy-type)
     (and (setq dst-copy-type
               (cdr (assq src-type elmo-folder-direct-copy-alist)))
@@ -1305,20 +1341,25 @@ Otherwise treat \\ in NEWTEXT string as special:
        (setq result (not result)))
     result))
 
-(defun elmo-condition-find-key-internal (condition key)
+(defun elmo-condition-in-msgdb-p-internal (condition fields)
   (cond
    ((vectorp condition)
-    (if (string= (elmo-filter-key condition) key)
+    (if (not (member (elmo-filter-key condition) fields))
        (throw 'found t)))
    ((or (eq (car condition) 'and)
        (eq (car condition) 'or))
-    (elmo-condition-find-key-internal (nth 1 condition) key)
-    (elmo-condition-find-key-internal (nth 2 condition) key))))
-
-(defun elmo-condition-find-key (condition key)
-  (catch 'found
-    (elmo-condition-find-key-internal condition key)))
-
+    (elmo-condition-in-msgdb-p-internal (nth 1 condition) fields)
+    (elmo-condition-in-msgdb-p-internal (nth 2 condition) fields))))
+
+(defun elmo-condition-in-msgdb-p (condition)
+  (not (catch 'found
+        (elmo-condition-in-msgdb-p-internal condition
+                                            (append
+                                             elmo-msgdb-extra-fields
+                                             '("last" "first" "from"
+                                               "subject" "to" "cc" "since"
+                                               "before"))))))
 (defun elmo-buffer-field-condition-match (condition number number-list)
   (cond
    ((vectorp condition)
@@ -1335,13 +1376,48 @@ Otherwise treat \\ in NEWTEXT string as special:
        (elmo-buffer-field-condition-match
         (nth 2 condition) number number-list)))))
 
-(defsubst elmo-file-field-condition-match (file condition number number-list)
-  (elmo-set-work-buf
-   (as-binary-input-file (insert-file-contents file))
-   (elmo-set-buffer-multibyte default-enable-multibyte-characters)
-   ;; Should consider charset?
-   (decode-mime-charset-region (point-min)(point-max) elmo-mime-charset)
-   (elmo-buffer-field-condition-match condition number number-list)))
+(defsubst elmo-file-field-primitive-condition-match (file
+                                                    condition
+                                                    number
+                                                    number-list)
+  (let (result)
+    (goto-char (point-min))
+    (cond
+     ((string= (elmo-filter-key condition) "last")
+      (setq result (<= (length (memq number number-list))
+                      (string-to-int (elmo-filter-value condition)))))
+     ((string= (elmo-filter-key condition) "first")
+      (setq result (< (- (length number-list)
+                        (length (memq number number-list)))
+                     (string-to-int (elmo-filter-value condition)))))
+     (t
+      (elmo-set-work-buf
+       (as-binary-input-file (insert-file-contents file))
+       (elmo-set-buffer-multibyte default-enable-multibyte-characters)
+       ;; Should consider charset?
+       (decode-mime-charset-region (point-min)(point-max) elmo-mime-charset)
+       (setq result
+            (elmo-buffer-field-primitive-condition-match
+             condition number number-list)))))
+    (if (eq (elmo-filter-type condition) 'unmatch)
+       (setq result (not result)))
+    result))
+
+(defun elmo-file-field-condition-match (file condition number number-list)
+  (cond
+   ((vectorp condition)
+    (elmo-file-field-primitive-condition-match
+     file condition number number-list))
+   ((eq (car condition) 'and)
+    (and (elmo-file-field-condition-match
+         file (nth 1 condition) number number-list)
+        (elmo-file-field-condition-match
+         file (nth 2 condition) number number-list)))
+   ((eq (car condition) 'or)
+    (or (elmo-file-field-condition-match
+        file (nth 1 condition) number number-list)
+       (elmo-file-field-condition-match
+        file (nth 2 condition) number number-list)))))
 
 (defmacro elmo-get-hash-val (string hashtable)
   (let ((sym (list 'intern-soft string hashtable)))
@@ -1546,10 +1622,10 @@ the value of `foo'."
                (list 'error-message doc
                      'error-conditions (cons error conds))))))
 
-(cond ((fboundp 'lprogress-display)
-       (defalias 'elmo-display-progress 'lprogress-display))
-      ((fboundp 'progress-feedback-with-label)
+(cond ((fboundp 'progress-feedback-with-label)
        (defalias 'elmo-display-progress 'progress-feedback-with-label))
+      ((fboundp 'lprogress-display)
+       (defalias 'elmo-display-progress 'lprogress-display))
       (t
        (defun elmo-display-progress (label format &optional value &rest args)
         "Print a progress message."
@@ -1573,6 +1649,14 @@ the value of `foo'."
     (defalias 'elmo-field-body 'std11-fetch-field) ;;no narrow-to-region
   (defalias 'elmo-field-body 'std11-field-body))
 
+(defun elmo-address-quote-specials (word)
+  "Make quoted string of WORD if needed."
+  (let ((lal (std11-lexical-analyze word)))
+    (if (or (assq 'specials lal)
+           (assq 'domain-literal lal))
+       (prin1-to-string word)
+      word)))
+
 (defmacro elmo-string (string)
   "STRING without text property."
   (` (let ((obj (copy-sequence (, string))))