Importing Gnus v5.8.6.
[elisp/gnus.git-] / lisp / gnus-util.el
index 6c329c0..1df730a 100644 (file)
@@ -1,5 +1,6 @@
 ;;; gnus-util.el --- utility functions for Gnus
-;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
        (and (string-match "(.*" from)
             (setq name (substring from (1+ (match-beginning 0))
                                   (match-end 0)))))
-    ;; Fix by Hallvard B Furuseth <h.b.furuseth@usit.uio.no>.
-    (list (or name from) (or address from))))
+    (list (if (string= name "") nil name) (or address from))))
+
 
 (defun gnus-fetch-field (field)
   "Return the value of the header FIELD of current article."
 
 (defun gnus-dd-mmm (messy-date)
   "Return a string like DD-MMM from a big messy string."
-  (format-time-string "%d-%b" (safe-date-to-time messy-date)))
+  (condition-case ()
+      (format-time-string "%d-%b" (safe-date-to-time messy-date))
+    (error "  -   ")))
 
 (defmacro gnus-date-get-time (date)
   "Convert DATE string to Emacs time.
@@ -504,9 +507,10 @@ If N, return the Nth ancestor instead."
              first 't2
              last 't1))
        ((gnus-functionp function)
+       ;; Do nothing.
        )
        (t
-       (error "Invalid sort spec: %s" function))))if
+       (error "Invalid sort spec: %s" function))))
     (if (cdr funs)
        `(or (,function ,first ,last)
             (and (not (,function ,last ,first))
@@ -688,7 +692,7 @@ with potentially long computations."
       ;; Decide whether to append to a file or to an Emacs buffer.
       (let ((outbuf (get-file-buffer filename)))
        (if (not outbuf)
-           (append-to-file (point-min) (point-max) filename)
+           (mm-append-to-file (point-min) (point-max) filename)
          ;; File has been visited, in buffer OUTBUF.
          (set-buffer outbuf)
          (let ((buffer-read-only nil)
@@ -756,7 +760,7 @@ with potentially long computations."
                    (insert "\n"))
                  (insert "\n"))
                (goto-char (point-max))
-               (append-to-file (point-min) (point-max) filename)))
+               (mm-append-to-file (point-min) (point-max) filename)))
          ;; File has been visited, in buffer OUTBUF.
          (set-buffer outbuf)
          (let ((buffer-read-only nil))
@@ -797,84 +801,82 @@ ARG is passed to the first function."
 ;;; .netrc and .authinforc parsing
 ;;;
 
-(defvar gnus-netrc-syntax-table
-  (let ((table (copy-syntax-table text-mode-syntax-table)))
-    (modify-syntax-entry ?@ "w" table)
-    (modify-syntax-entry ?- "w" table)
-    (modify-syntax-entry ?_ "w" table)
-    (modify-syntax-entry ?! "w" table)
-    (modify-syntax-entry ?. "w" table)
-    (modify-syntax-entry ?, "w" table)
-    (modify-syntax-entry ?: "w" table)
-    (modify-syntax-entry ?\; "w" table)
-    (modify-syntax-entry ?% "w" table)
-    (modify-syntax-entry ?) "w" table)
-    (modify-syntax-entry ?( "w" table)
-    table)
-  "Syntax table when parsing .netrc files.")
-
 (defun gnus-parse-netrc (file)
   "Parse FILE and return an list of all entries in the file."
-  (if (not (file-exists-p file))
-      ()
-    (save-excursion
+  (when (file-exists-p file)
+    (with-temp-buffer
       (let ((tokens '("machine" "default" "login"
-                     "password" "account" "macdef" "force"))
+                     "password" "account" "macdef" "force"
+                     "port"))
            alist elem result pair)
-       (nnheader-set-temp-buffer " *netrc*")
-       (unwind-protect
-           (progn
-             (set-syntax-table gnus-netrc-syntax-table)
-             (insert-file-contents file)
-             (goto-char (point-min))
-             ;; Go through the file, line by line.
-             (while (not (eobp))
-               (narrow-to-region (point) (gnus-point-at-eol))
-               ;; For each line, get the tokens and values.
-               (while (not (eobp))
-                 (skip-chars-forward "\t ")
-                 (unless (eobp)
-                   (setq elem (buffer-substring
-                               (point) (progn (forward-sexp 1) (point))))
-                   (cond
-                    ((equal elem "macdef")
-                     ;; We skip past the macro definition.
-                     (widen)
-                     (while (and (zerop (forward-line 1))
-                                 (looking-at "$")))
-                     (narrow-to-region (point) (point)))
-                    ((member elem tokens)
-                     ;; Tokens that don't have a following value are ignored,
-                     ;; except "default".
-                     (when (and pair (or (cdr pair)
-                                         (equal (car pair) "default")))
-                       (push pair alist))
-                     (setq pair (list elem)))
-                    (t
-                     ;; Values that haven't got a preceding token are ignored.
-                     (when pair
-                       (setcdr pair elem)
-                       (push pair alist)
-                       (setq pair nil))))))
-               (if alist
-                   (push (nreverse alist) result))
-               (setq alist nil
-                     pair nil)
-               (widen)
-               (forward-line 1))
-             (nreverse result))
-         (kill-buffer " *netrc*"))))))
-
-(defun gnus-netrc-machine (list machine)
+       (insert-file-contents file)
+       (goto-char (point-min))
+       ;; Go through the file, line by line.
+       (while (not (eobp))
+         (narrow-to-region (point) (gnus-point-at-eol))
+         ;; For each line, get the tokens and values.
+         (while (not (eobp))
+           (skip-chars-forward "\t ")
+           ;; Skip lines that begin with a "#".
+           (if (eq (char-after) ?#)
+               (goto-char (point-max))
+             (unless (eobp)
+               (setq elem
+                     (if (= (following-char) ?\")
+                         (read (current-buffer))
+                       (buffer-substring
+                        (point) (progn (skip-chars-forward "^\t ")
+                                       (point)))))
+               (cond
+                ((equal elem "macdef")
+                 ;; We skip past the macro definition.
+                 (widen)
+                 (while (and (zerop (forward-line 1))
+                             (looking-at "$")))
+                 (narrow-to-region (point) (point)))
+                ((member elem tokens)
+                 ;; Tokens that don't have a following value are ignored,
+                 ;; except "default".
+                 (when (and pair (or (cdr pair)
+                                     (equal (car pair) "default")))
+                   (push pair alist))
+                 (setq pair (list elem)))
+                (t
+                 ;; Values that haven't got a preceding token are ignored.
+                 (when pair
+                   (setcdr pair elem)
+                   (push pair alist)
+                   (setq pair nil)))))))
+         (when alist
+           (push (nreverse alist) result))
+         (setq alist nil
+               pair nil)
+         (widen)
+         (forward-line 1))
+       (nreverse result)))))
+
+(defun gnus-netrc-machine (list machine &optional port)
   "Return the netrc values from LIST for MACHINE or for the default entry."
-  (let ((rest list))
-    (while (and list
-               (not (equal (cdr (assoc "machine" (car list))) machine)))
+  (let ((rest list)
+       result)
+    (while list
+      (when (equal (cdr (assoc "machine" (car list))) machine)
+       (push (car list) result))
       (pop list))
-    (car (or list
-            (progn (while (and rest (not (assoc "default" (car rest))))
-                     (pop rest))
-                   rest)))))
+    (unless result
+      ;; No machine name matches, so we look for default entries.
+      (while rest
+       (when (assoc "default" (car rest))
+         (push (car rest) result))
+       (pop rest)))
+    (when result
+      (setq result (nreverse result))
+      (while (and result
+                 (not (equal (or port "nntp")
+                             (or (gnus-netrc-get (car result) "port")
+                                 "nntp"))))
+       (pop result))
+      (car result))))
 
 (defun gnus-netrc-get (alist type)
   "Return the value of token TYPE from ALIST."
@@ -939,6 +941,40 @@ ARG is passed to the first function."
       (eq (cadr (memq 'gnus-undeletable (text-properties-at b))) t)
     (text-property-any b e 'gnus-undeletable t)))
 
+(defun gnus-or (&rest elems)
+  "Return non-nil if any of the elements are non-nil."
+  (catch 'found
+    (while elems
+      (when (pop elems)
+       (throw 'found t)))))
+
+(defun gnus-and (&rest elems)
+  "Return non-nil if all of the elements are non-nil."
+  (catch 'found
+    (while elems
+      (unless (pop elems)
+       (throw 'found nil)))
+    t))
+
+(defun gnus-write-active-file (file hashtb &optional full-names)
+  (with-temp-file file
+    (mapatoms
+     (lambda (sym)
+       (when (and sym
+                 (boundp sym)
+                 (symbol-value sym))
+        (insert (format "%S %d %d y\n"
+                        (if full-names
+                            sym
+                          (intern (gnus-group-real-name (symbol-name sym))))
+                        (or (cdr (symbol-value sym))
+                            (car (symbol-value sym)))
+                        (car (symbol-value sym))))))
+     hashtb)
+    (goto-char (point-max))
+    (while (search-backward "\\." nil t)
+      (delete-char 1))))
+
 (provide 'gnus-util)
 
 ;;; gnus-util.el ends here