aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2002-07-13 22:10:02 +0000
committerStefan Monnier2002-07-13 22:10:02 +0000
commit6e85ef5fd113cd98b6b58a8eb7e614dc18c50ac4 (patch)
treebe0116e63f829917cfd85348c2287f908f281dcf
parent6946ae5b110a82d238c6546f29fec986f32d071b (diff)
downloademacs-6e85ef5fd113cd98b6b58a8eb7e614dc18c50ac4.tar.gz
emacs-6e85ef5fd113cd98b6b58a8eb7e614dc18c50ac4.zip
Use hash-tables.
(ange-ftp-make-hashtable, ange-ftp-map-hashtable) (ange-ftp-make-hash-key, ange-ftp-get-hash-entry) (ange-ftp-put-hash-entry, ange-ftp-del-hash-entry): Remove. Replace with make-hash-table, maphash, gethash, puthash and remhash. (ange-ftp-hash-entry-exists-p): Rewrite. (ange-ftp-vms-delete-file-entry, ange-ftp-vms-add-file-entry): Change mapatom -> maphash. (ange-ftp-file-entry-active-p, ange-ftp-file-entry-not-ignored-p): Update to new calling mode.
-rw-r--r--lisp/net/ange-ftp.el391
1 files changed, 159 insertions, 232 deletions
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index ca0a17b3dd7..f38864d743e 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -1020,60 +1020,16 @@ or nil meaning don't change it."
1020 1020
1021(require 'backquote) 1021(require 'backquote)
1022 1022
1023(defun ange-ftp-make-hashtable (&optional size)
1024 "Make an obarray suitable for use as a hashtable.
1025SIZE, if supplied, should be a prime number."
1026 (make-vector (or size 31) 0))
1027
1028(defun ange-ftp-map-hashtable (fun tbl)
1029 "Call FUNCTION on each key and value in HASHTABLE."
1030 (mapatoms
1031 (function
1032 (lambda (sym)
1033 (funcall fun (get sym 'key) (get sym 'val))))
1034 tbl))
1035
1036(defmacro ange-ftp-make-hash-key (key)
1037 "Convert KEY into a suitable key for a hashtable."
1038 `(if (stringp ,key)
1039 ,key
1040 (prin1-to-string ,key)))
1041
1042(defun ange-ftp-get-hash-entry (key tbl)
1043 "Return the value associated with KEY in HASHTABLE."
1044 (let ((sym (intern-soft (ange-ftp-make-hash-key key) tbl)))
1045 (and sym (get sym 'val))))
1046
1047(defun ange-ftp-put-hash-entry (key val tbl)
1048 "Record an association between KEY and VALUE in HASHTABLE."
1049 (let ((sym (intern (ange-ftp-make-hash-key key) tbl)))
1050 (put sym 'val val)
1051 (put sym 'key key)))
1052
1053(defun ange-ftp-del-hash-entry (key tbl)
1054 "Copy all symbols except KEY in HASHTABLE and return modified hashtable."
1055 (let* ((len (length tbl))
1056 (new-tbl (ange-ftp-make-hashtable len))
1057 (i (1- len)))
1058 (ange-ftp-map-hashtable
1059 (function
1060 (lambda (k v)
1061 (or (equal k key)
1062 (ange-ftp-put-hash-entry k v new-tbl))))
1063 tbl)
1064 (while (>= i 0)
1065 (aset tbl i (aref new-tbl i))
1066 (setq i (1- i)))
1067 tbl))
1068
1069(defun ange-ftp-hash-entry-exists-p (key tbl) 1023(defun ange-ftp-hash-entry-exists-p (key tbl)
1070 "Return whether there is an association for KEY in TABLE." 1024 "Return whether there is an association for KEY in TABLE."
1071 (intern-soft (ange-ftp-make-hash-key key) tbl)) 1025 (not (eq (gethash key tbl 'unknown) 'unknown)))
1072 1026
1073(defun ange-ftp-hash-table-keys (tbl) 1027(defun ange-ftp-hash-table-keys (tbl)
1074 "Return a sorted list of all the active keys in TABLE, as strings." 1028 "Return a sorted list of all the active keys in TABLE, as strings."
1075 (sort (all-completions "" tbl) 1029 ;; (let ((keys nil))
1076 (function string-lessp))) 1030 ;; (maphash (lambda (k v) (push k keys)) tbl)
1031 ;; (sort keys 'string-lessp))
1032 (sort (all-completions "" tbl) 'string-lessp))
1077 1033
1078;;;; ------------------------------------------------------------ 1034;;;; ------------------------------------------------------------
1079;;;; Internal variables. 1035;;;; Internal variables.
@@ -1085,20 +1041,20 @@ SIZE, if supplied, should be a prime number."
1085(defvar ange-ftp-netrc-modtime nil 1041(defvar ange-ftp-netrc-modtime nil
1086 "Last modified time of the netrc file from file-attributes.") 1042 "Last modified time of the netrc file from file-attributes.")
1087 1043
1088(defvar ange-ftp-user-hashtable (ange-ftp-make-hashtable) 1044(defvar ange-ftp-user-hashtable (make-hash-table :test 'equal)
1089 "Hash table holding associations between HOST, USER pairs.") 1045 "Hash table holding associations between HOST, USER pairs.")
1090 1046
1091(defvar ange-ftp-passwd-hashtable (ange-ftp-make-hashtable) 1047(defvar ange-ftp-passwd-hashtable (make-hash-table :test 'equal)
1092 "Mapping between a HOST, USER pair and a PASSWORD for them. 1048 "Mapping between a HOST, USER pair and a PASSWORD for them.
1093All HOST values should be in lower case.") 1049All HOST values should be in lower case.")
1094 1050
1095(defvar ange-ftp-account-hashtable (ange-ftp-make-hashtable) 1051(defvar ange-ftp-account-hashtable (make-hash-table :test 'equal)
1096 "Mapping between a HOST, USER pair and a ACCOUNT password for them.") 1052 "Mapping between a HOST, USER pair and a ACCOUNT password for them.")
1097 1053
1098(defvar ange-ftp-files-hashtable (ange-ftp-make-hashtable 97) 1054(defvar ange-ftp-files-hashtable (make-hash-table :test 'equal :size 97)
1099 "Hash table for storing directories and their respective files.") 1055 "Hash table for storing directories and their respective files.")
1100 1056
1101(defvar ange-ftp-inodes-hashtable (ange-ftp-make-hashtable 97) 1057(defvar ange-ftp-inodes-hashtable (make-hash-table :test 'equal :size 97)
1102 "Hash table for storing file names and their \"inode numbers\".") 1058 "Hash table for storing file names and their \"inode numbers\".")
1103 1059
1104(defvar ange-ftp-next-inode-number 1 1060(defvar ange-ftp-next-inode-number 1
@@ -1113,7 +1069,7 @@ All HOST values should be in lower case.")
1113(defvar ange-ftp-ls-cache-res nil 1069(defvar ange-ftp-ls-cache-res nil
1114 "Last result returned from ange-ftp-ls.") 1070 "Last result returned from ange-ftp-ls.")
1115 1071
1116(defconst ange-ftp-expand-dir-hashtable (ange-ftp-make-hashtable)) 1072(defconst ange-ftp-expand-dir-hashtable (make-hash-table :test 'equal))
1117 1073
1118(defconst ange-ftp-expand-dir-regexp "^5.0 \\([^: ]+\\):") 1074(defconst ange-ftp-expand-dir-regexp "^5.0 \\([^: ]+\\):")
1119 1075
@@ -1151,7 +1107,7 @@ All HOST values should be in lower case.")
1151(defun ange-ftp-message (fmt &rest args) 1107(defun ange-ftp-message (fmt &rest args)
1152 "Display message in echo area, but indicate if truncated. 1108 "Display message in echo area, but indicate if truncated.
1153Args are as in `message': a format string, plus arguments to be formatted." 1109Args are as in `message': a format string, plus arguments to be formatted."
1154 (let ((msg (apply (function format) fmt args)) 1110 (let ((msg (apply 'format fmt args))
1155 (max (window-width (minibuffer-window)))) 1111 (max (window-width (minibuffer-window))))
1156 (if noninteractive 1112 (if noninteractive
1157 msg 1113 msg
@@ -1183,12 +1139,12 @@ only return the directory part of FILE."
1183(defun ange-ftp-set-user (host user) 1139(defun ange-ftp-set-user (host user)
1184 "For a given HOST, set or change the default USER." 1140 "For a given HOST, set or change the default USER."
1185 (interactive "sHost: \nsUser: ") 1141 (interactive "sHost: \nsUser: ")
1186 (ange-ftp-put-hash-entry host user ange-ftp-user-hashtable)) 1142 (puthash host user ange-ftp-user-hashtable))
1187 1143
1188(defun ange-ftp-get-user (host) 1144(defun ange-ftp-get-user (host)
1189 "Given a HOST, return the default USER." 1145 "Given a HOST, return the default USER."
1190 (ange-ftp-parse-netrc) 1146 (ange-ftp-parse-netrc)
1191 (let ((user (ange-ftp-get-hash-entry host ange-ftp-user-hashtable))) 1147 (let ((user (gethash host ange-ftp-user-hashtable)))
1192 (or user 1148 (or user
1193 (prog1 1149 (prog1
1194 (setq user 1150 (setq user
@@ -1214,36 +1170,33 @@ only return the directory part of FILE."
1214 `(concat (downcase ,host) "/" ,user)) 1170 `(concat (downcase ,host) "/" ,user))
1215 1171
1216(defmacro ange-ftp-lookup-passwd (host user) 1172(defmacro ange-ftp-lookup-passwd (host user)
1217 `(ange-ftp-get-hash-entry (ange-ftp-generate-passwd-key ,host ,user) 1173 `(gethash (ange-ftp-generate-passwd-key ,host ,user)
1218 ange-ftp-passwd-hashtable)) 1174 ange-ftp-passwd-hashtable))
1219 1175
1220(defun ange-ftp-set-passwd (host user passwd) 1176(defun ange-ftp-set-passwd (host user passwd)
1221 "For a given HOST and USER, set or change the associated PASSWORD." 1177 "For a given HOST and USER, set or change the associated PASSWORD."
1222 (interactive (list (read-string "Host: ") 1178 (interactive (list (read-string "Host: ")
1223 (read-string "User: ") 1179 (read-string "User: ")
1224 (read-passwd "Password: "))) 1180 (read-passwd "Password: ")))
1225 (ange-ftp-put-hash-entry (ange-ftp-generate-passwd-key host user) 1181 (puthash (ange-ftp-generate-passwd-key host user)
1226 passwd 1182 passwd ange-ftp-passwd-hashtable))
1227 ange-ftp-passwd-hashtable))
1228 1183
1229(defun ange-ftp-get-host-with-passwd (user) 1184(defun ange-ftp-get-host-with-passwd (user)
1230 "Given a USER, return a host we know the password for." 1185 "Given a USER, return a host we know the password for."
1231 (ange-ftp-parse-netrc) 1186 (ange-ftp-parse-netrc)
1232 (catch 'found-one 1187 (catch 'found-one
1233 (ange-ftp-map-hashtable 1188 (maphash
1234 (function (lambda (host val) 1189 (lambda (host val)
1235 (if (ange-ftp-lookup-passwd host user) 1190 (if (ange-ftp-lookup-passwd host user) (throw 'found-one host)))
1236 (throw 'found-one host))))
1237 ange-ftp-user-hashtable) 1191 ange-ftp-user-hashtable)
1238 (save-match-data 1192 (save-match-data
1239 (ange-ftp-map-hashtable 1193 (maphash
1240 (function 1194 (lambda (key value)
1241 (lambda (key value) 1195 (if (string-match "^[^/]*\\(/\\).*$" key)
1242 (if (string-match "^[^/]*\\(/\\).*$" key) 1196 (let ((host (substring key 0 (match-beginning 1))))
1243 (let ((host (substring key 0 (match-beginning 1)))) 1197 (if (and (string-equal user (substring key (match-end 1)))
1244 (if (and (string-equal user (substring key (match-end 1))) 1198 value)
1245 value) 1199 (throw 'found-one host)))))
1246 (throw 'found-one host))))))
1247 ange-ftp-passwd-hashtable)) 1200 ange-ftp-passwd-hashtable))
1248 nil)) 1201 nil))
1249 1202
@@ -1310,15 +1263,14 @@ only return the directory part of FILE."
1310 (interactive (list (read-string "Host: ") 1263 (interactive (list (read-string "Host: ")
1311 (read-string "User: ") 1264 (read-string "User: ")
1312 (read-passwd "Account password: "))) 1265 (read-passwd "Account password: ")))
1313 (ange-ftp-put-hash-entry (ange-ftp-generate-passwd-key host user) 1266 (puthash (ange-ftp-generate-passwd-key host user)
1314 account 1267 account ange-ftp-account-hashtable))
1315 ange-ftp-account-hashtable))
1316 1268
1317(defun ange-ftp-get-account (host user) 1269(defun ange-ftp-get-account (host user)
1318 "Given a HOST and USER, return the FTP account." 1270 "Given a HOST and USER, return the FTP account."
1319 (ange-ftp-parse-netrc) 1271 (ange-ftp-parse-netrc)
1320 (or (ange-ftp-get-hash-entry (ange-ftp-generate-passwd-key host user) 1272 (or (gethash (ange-ftp-generate-passwd-key host user)
1321 ange-ftp-account-hashtable) 1273 ange-ftp-account-hashtable)
1322 (and (stringp ange-ftp-default-user) 1274 (and (stringp ange-ftp-default-user)
1323 (string-equal user ange-ftp-default-user) 1275 (string-equal user ange-ftp-default-user)
1324 ange-ftp-default-account) 1276 ange-ftp-default-account)
@@ -1453,17 +1405,15 @@ only return the directory part of FILE."
1453 (ange-ftp-parse-netrc) 1405 (ange-ftp-parse-netrc)
1454 (save-match-data 1406 (save-match-data
1455 (let (res) 1407 (let (res)
1456 (ange-ftp-map-hashtable 1408 (maphash
1457 (function 1409 (lambda (key value)
1458 (lambda (key value) 1410 (if (string-match "^[^/]*\\(/\\).*$" key)
1459 (if (string-match "^[^/]*\\(/\\).*$" key) 1411 (let ((host (substring key 0 (match-beginning 1)))
1460 (let ((host (substring key 0 (match-beginning 1))) 1412 (user (substring key (match-end 1))))
1461 (user (substring key (match-end 1)))) 1413 (push (concat user "@" host ":") res))))
1462 (push (concat user "@" host ":") res)))))
1463 ange-ftp-passwd-hashtable) 1414 ange-ftp-passwd-hashtable)
1464 (ange-ftp-map-hashtable 1415 (maphash
1465 (function (lambda (host user) 1416 (lambda (host user) (push (concat host ":") res))
1466 (push (concat host ":") res)))
1467 ange-ftp-user-hashtable) 1417 ange-ftp-user-hashtable)
1468 (or res (list nil))))) 1418 (or res (list nil)))))
1469 1419
@@ -1653,14 +1603,13 @@ good, skip, fatal, or unknown."
1653 (let ((kbytes (ash (* ange-ftp-hash-mark-unit 1603 (let ((kbytes (ash (* ange-ftp-hash-mark-unit
1654 ange-ftp-hash-mark-count) 1604 ange-ftp-hash-mark-count)
1655 -6))) 1605 -6)))
1656 (if (zerop ange-ftp-xfer-size) 1606 (if (zerop ange-ftp-xfer-size)
1657 (ange-ftp-message "%s...%dk" ange-ftp-process-msg kbytes) 1607 (ange-ftp-message "%s...%dk" ange-ftp-process-msg kbytes)
1658 (let ((percent (/ (* 100 kbytes) ange-ftp-xfer-size))) 1608 (let ((percent (/ (* 100 kbytes) ange-ftp-xfer-size)))
1659 ;; cut out the redisplay of identical %-age messages. 1609 ;; cut out the redisplay of identical %-age messages.
1660 (if (not (eq percent ange-ftp-last-percent)) 1610 (unless (eq percent ange-ftp-last-percent)
1661 (progn 1611 (setq ange-ftp-last-percent percent)
1662 (setq ange-ftp-last-percent percent) 1612 (ange-ftp-message "%s...%d%%" ange-ftp-process-msg percent))))))
1663 (ange-ftp-message "%s...%d%%" ange-ftp-process-msg percent)))))))
1664 str) 1613 str)
1665 1614
1666;; Call the function specified by CONT. CONT can be either a function 1615;; Call the function specified by CONT. CONT can be either a function
@@ -1781,8 +1730,8 @@ good, skip, fatal, or unknown."
1781(defun ange-ftp-make-tmp-name (host) 1730(defun ange-ftp-make-tmp-name (host)
1782 "This routine will return the name of a new file." 1731 "This routine will return the name of a new file."
1783 (make-temp-file (if (ange-ftp-use-gateway-p host) 1732 (make-temp-file (if (ange-ftp-use-gateway-p host)
1784 ange-ftp-gateway-tmp-name-template 1733 ange-ftp-gateway-tmp-name-template
1785 ange-ftp-tmp-name-template))) 1734 ange-ftp-tmp-name-template)))
1786 1735
1787(defalias 'ange-ftp-del-tmp-name 'delete-file) 1736(defalias 'ange-ftp-del-tmp-name 'delete-file)
1788 1737
@@ -2516,8 +2465,7 @@ Works by doing a pwd and examining the directory syntax."
2516 ange-ftp-fix-name-func-alist))) 2465 ange-ftp-fix-name-func-alist)))
2517 (if fix-name-func 2466 (if fix-name-func
2518 (setq dir (funcall fix-name-func dir 'reverse)))) 2467 (setq dir (funcall fix-name-func dir 'reverse))))
2519 (ange-ftp-put-hash-entry key dir 2468 (puthash key dir ange-ftp-expand-dir-hashtable))))
2520 ange-ftp-expand-dir-hashtable))))
2521 2469
2522 ;; In the special case of CMS make sure that know the 2470 ;; In the special case of CMS make sure that know the
2523 ;; expansion of the home minidisk now, because we will 2471 ;; expansion of the home minidisk now, because we will
@@ -2527,8 +2475,7 @@ Works by doing a pwd and examining the directory syntax."
2527 key ange-ftp-expand-dir-hashtable))) 2475 key ange-ftp-expand-dir-hashtable)))
2528 (let ((dir (car (ange-ftp-get-pwd host user)))) 2476 (let ((dir (car (ange-ftp-get-pwd host user))))
2529 (if dir 2477 (if dir
2530 (ange-ftp-put-hash-entry key (concat "/" dir) 2478 (puthash key (concat "/" dir) ange-ftp-expand-dir-hashtable)
2531 ange-ftp-expand-dir-hashtable)
2532 (message "Warning! Unable to get home directory") 2479 (message "Warning! Unable to get home directory")
2533 (sit-for 1)))))) 2480 (sit-for 1))))))
2534 2481
@@ -2611,7 +2558,7 @@ away in the internal cache."
2611 (if (string-equal name "") 2558 (if (string-equal name "")
2612 (setq name 2559 (setq name
2613 (ange-ftp-real-file-name-as-directory 2560 (ange-ftp-real-file-name-as-directory
2614 (ange-ftp-expand-dir host user "~")))) 2561 (ange-ftp-expand-dir host user "~"))))
2615 (if (and ange-ftp-ls-cache-file 2562 (if (and ange-ftp-ls-cache-file
2616 (string-equal key ange-ftp-ls-cache-file) 2563 (string-equal key ange-ftp-ls-cache-file)
2617 ;; Don't care about lsargs for dumb hosts. 2564 ;; Don't care about lsargs for dumb hosts.
@@ -2763,7 +2710,7 @@ The main reason for this alist is to deal with file versions in VMS.")
2763(defun ange-ftp-ls-parser () 2710(defun ange-ftp-ls-parser ()
2764 ;; Note that switches is dynamically bound. 2711 ;; Note that switches is dynamically bound.
2765 ;; Meant to be called by ange-ftp-parse-dired-listing 2712 ;; Meant to be called by ange-ftp-parse-dired-listing
2766 (let ((tbl (ange-ftp-make-hashtable)) 2713 (let ((tbl (make-hash-table :test 'equal))
2767 (used-F (and (stringp switches) 2714 (used-F (and (stringp switches)
2768 (string-match "F" switches))) 2715 (string-match "F" switches)))
2769 file-type symlink directory file) 2716 file-type symlink directory file)
@@ -2806,10 +2753,10 @@ The main reason for this alist is to deal with file versions in VMS.")
2806 (and executable (string-match "*$" file)) 2753 (and executable (string-match "*$" file))
2807 (and socket (string-match "=$" file))) 2754 (and socket (string-match "=$" file)))
2808 (setq file (substring file 0 -1))))) 2755 (setq file (substring file 0 -1)))))
2809 (ange-ftp-put-hash-entry file (or symlink directory) tbl) 2756 (puthash file (or symlink directory) tbl)
2810 (forward-line 1)) 2757 (forward-line 1))
2811 (ange-ftp-put-hash-entry "." t tbl) 2758 (puthash "." t tbl)
2812 (ange-ftp-put-hash-entry ".." t tbl) 2759 (puthash ".." t tbl)
2813 tbl)) 2760 tbl))
2814 2761
2815;;; The dl stuff for descriptive listings 2762;;; The dl stuff for descriptive listings
@@ -2836,9 +2783,9 @@ match subdirectories as well.")
2836(defmacro ange-ftp-dl-parser () 2783(defmacro ange-ftp-dl-parser ()
2837 ;; Parse the current buffer, which is assumed to be a descriptive 2784 ;; Parse the current buffer, which is assumed to be a descriptive
2838 ;; listing, and return a hashtable. 2785 ;; listing, and return a hashtable.
2839 `(let ((tbl (ange-ftp-make-hashtable))) 2786 `(let ((tbl (make-hash-table :test 'equal)))
2840 (while (not (eobp)) 2787 (while (not (eobp))
2841 (ange-ftp-put-hash-entry 2788 (puthash
2842 (buffer-substring (point) 2789 (buffer-substring (point)
2843 (progn 2790 (progn
2844 (skip-chars-forward "^ /\n") 2791 (skip-chars-forward "^ /\n")
@@ -2846,9 +2793,9 @@ match subdirectories as well.")
2846 (eq (following-char) ?/) 2793 (eq (following-char) ?/)
2847 tbl) 2794 tbl)
2848 (forward-line 1)) 2795 (forward-line 1))
2849 (ange-ftp-put-hash-entry "." t tbl) 2796 (puthash "." t tbl)
2850 (ange-ftp-put-hash-entry ".." t tbl) 2797 (puthash ".." t tbl)
2851 tbl)) 2798 tbl))
2852 2799
2853;; Parse the current buffer which is assumed to be in a dired-like listing 2800;; Parse the current buffer which is assumed to be in a dired-like listing
2854;; format, and return a hashtable as the result. If the listing is not really 2801;; format, and return a hashtable as the result. If the listing is not really
@@ -2886,15 +2833,15 @@ match subdirectories as well.")
2886 2833
2887(defun ange-ftp-set-files (directory files) 2834(defun ange-ftp-set-files (directory files)
2888 "For a given DIRECTORY, set or change the associated FILES hashtable." 2835 "For a given DIRECTORY, set or change the associated FILES hashtable."
2889 (and files (ange-ftp-put-hash-entry (file-name-as-directory directory) 2836 (and files (puthash (file-name-as-directory directory)
2890 files ange-ftp-files-hashtable))) 2837 files ange-ftp-files-hashtable)))
2891 2838
2892(defun ange-ftp-get-files (directory &optional no-error) 2839(defun ange-ftp-get-files (directory &optional no-error)
2893 "Given a given DIRECTORY, return a hashtable of file entries. 2840 "Given a given DIRECTORY, return a hashtable of file entries.
2894This will give an error or return nil, depending on the value of 2841This will give an error or return nil, depending on the value of
2895NO-ERROR, if a listing for DIRECTORY cannot be obtained." 2842NO-ERROR, if a listing for DIRECTORY cannot be obtained."
2896 (setq directory (file-name-as-directory directory)) ;normalize 2843 (setq directory (file-name-as-directory directory)) ;normalize
2897 (or (ange-ftp-get-hash-entry directory ange-ftp-files-hashtable) 2844 (or (gethash directory ange-ftp-files-hashtable)
2898 (save-match-data 2845 (save-match-data
2899 (and (ange-ftp-ls directory 2846 (and (ange-ftp-ls directory
2900 ;; This is an efficiency hack. We try to 2847 ;; This is an efficiency hack. We try to
@@ -2925,8 +2872,7 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained."
2925 dired-listing-switches 2872 dired-listing-switches
2926 "-al")) 2873 "-al"))
2927 t no-error) 2874 t no-error)
2928 (ange-ftp-get-hash-entry 2875 (gethash directory ange-ftp-files-hashtable)))))
2929 directory ange-ftp-files-hashtable)))))
2930 2876
2931;; Given NAME, return the file part that can be used for looking up the 2877;; Given NAME, return the file part that can be used for looking up the
2932;; file's entry in a hashtable. 2878;; file's entry in a hashtable.
@@ -2970,7 +2916,7 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained."
2970 "Given NAME, return whether there is a file entry for it." 2916 "Given NAME, return whether there is a file entry for it."
2971 (let* ((name (directory-file-name name)) 2917 (let* ((name (directory-file-name name))
2972 (dir (file-name-directory name)) 2918 (dir (file-name-directory name))
2973 (ent (ange-ftp-get-hash-entry dir ange-ftp-files-hashtable)) 2919 (ent (gethash dir ange-ftp-files-hashtable))
2974 (file (ange-ftp-get-file-part name))) 2920 (file (ange-ftp-get-file-part name)))
2975 (if ent 2921 (if ent
2976 (ange-ftp-hash-entry-exists-p file ent) 2922 (ange-ftp-hash-entry-exists-p file ent)
@@ -2984,7 +2930,7 @@ NO-ERROR, if a listing for DIRECTORY cannot be obtained."
2984 ;; then dumb hosts will give an ftp error. Smart unix hosts 2930 ;; then dumb hosts will give an ftp error. Smart unix hosts
2985 ;; will simply send back the ls 2931 ;; will simply send back the ls
2986 ;; error message. 2932 ;; error message.
2987 (ange-ftp-get-hash-entry "." ent)) 2933 (gethash "." ent))
2988 ;; Child lookup failed, so try the parent. 2934 ;; Child lookup failed, so try the parent.
2989 (let ((table (ange-ftp-get-files dir 'no-error))) 2935 (let ((table (ange-ftp-get-files dir 'no-error)))
2990 ;; If the dir doesn't exist, don't use it as a hash table. 2936 ;; If the dir doesn't exist, don't use it as a hash table.
@@ -2999,53 +2945,47 @@ or a string for a symlink. If the file isn't in the hashtable,
2999this also returns nil." 2945this also returns nil."
3000 (let* ((name (directory-file-name name)) 2946 (let* ((name (directory-file-name name))
3001 (dir (file-name-directory name)) 2947 (dir (file-name-directory name))
3002 (ent (ange-ftp-get-hash-entry dir ange-ftp-files-hashtable)) 2948 (ent (gethash dir ange-ftp-files-hashtable))
3003 (file (ange-ftp-get-file-part name))) 2949 (file (ange-ftp-get-file-part name)))
3004 (if ent 2950 (if ent
3005 (ange-ftp-get-hash-entry file ent) 2951 (gethash file ent)
3006 (or (and (ange-ftp-allow-child-lookup dir file) 2952 (or (and (ange-ftp-allow-child-lookup dir file)
3007 (setq ent (ange-ftp-get-files name t)) 2953 (setq ent (ange-ftp-get-files name t))
3008 (ange-ftp-get-hash-entry "." ent)) 2954 (gethash "." ent))
3009 ;; i.e. it's a directory by child lookup 2955 ;; i.e. it's a directory by child lookup
3010 (ange-ftp-get-hash-entry file 2956 (gethash file (ange-ftp-get-files dir))))))
3011 (ange-ftp-get-files dir))))))
3012 2957
3013(defun ange-ftp-internal-delete-file-entry (name &optional dir-p) 2958(defun ange-ftp-internal-delete-file-entry (name &optional dir-p)
3014 (if dir-p 2959 (when dir-p
3015 (progn 2960 (setq name (file-name-as-directory name))
3016 (setq name (file-name-as-directory name)) 2961 (remhash name ange-ftp-files-hashtable)
3017 (ange-ftp-del-hash-entry name ange-ftp-files-hashtable) 2962 (setq name (directory-file-name name)))
3018 (setq name (directory-file-name name))))
3019 ;; Note that file-name-as-directory followed by directory-file-name 2963 ;; Note that file-name-as-directory followed by directory-file-name
3020 ;; serves to canonicalize directory file names to their unix form. 2964 ;; serves to canonicalize directory file names to their unix form.
3021 ;; i.e. in VMS, FOO.DIR -> FOO/ -> FOO 2965 ;; i.e. in VMS, FOO.DIR -> FOO/ -> FOO
3022 (let ((files (ange-ftp-get-hash-entry (file-name-directory name) 2966 (let ((files (gethash (file-name-directory name) ange-ftp-files-hashtable)))
3023 ange-ftp-files-hashtable)))
3024 (if files 2967 (if files
3025 (ange-ftp-del-hash-entry (ange-ftp-get-file-part name) 2968 (remhash (ange-ftp-get-file-part name) files))))
3026 files))))
3027 2969
3028(defun ange-ftp-internal-add-file-entry (name &optional dir-p) 2970(defun ange-ftp-internal-add-file-entry (name &optional dir-p)
3029 (and dir-p 2971 (and dir-p
3030 (setq name (directory-file-name name))) 2972 (setq name (directory-file-name name)))
3031 (let ((files (ange-ftp-get-hash-entry (file-name-directory name) 2973 (let ((files (gethash (file-name-directory name) ange-ftp-files-hashtable)))
3032 ange-ftp-files-hashtable)))
3033 (if files 2974 (if files
3034 (ange-ftp-put-hash-entry (ange-ftp-get-file-part name) 2975 (puthash (ange-ftp-get-file-part name) dir-p files))))
3035 dir-p
3036 files))))
3037 2976
3038(defun ange-ftp-wipe-file-entries (host user) 2977(defun ange-ftp-wipe-file-entries (host user)
3039 "Get rid of entry for HOST, USER pair from file entry information hashtable." 2978 "Get rid of entry for HOST, USER pair from file entry information hashtable."
3040 (let ((new-tbl (ange-ftp-make-hashtable (length ange-ftp-files-hashtable)))) 2979 (let ((new-tbl (make-hash-table :test 'equal
3041 (ange-ftp-map-hashtable 2980 :size (length ange-ftp-files-hashtable))))
2981 (maphash
3042 (lambda (key val) 2982 (lambda (key val)
3043 (let ((parsed (ange-ftp-ftp-name key))) 2983 (let ((parsed (ange-ftp-ftp-name key)))
3044 (if parsed 2984 (if parsed
3045 (let ((h (nth 0 parsed)) 2985 (let ((h (nth 0 parsed))
3046 (u (nth 1 parsed))) 2986 (u (nth 1 parsed)))
3047 (or (and (equal host h) (equal user u)) 2987 (or (and (equal host h) (equal user u))
3048 (ange-ftp-put-hash-entry key val new-tbl)))))) 2988 (puthash key val new-tbl))))))
3049 ange-ftp-files-hashtable) 2989 ange-ftp-files-hashtable)
3050 (setq ange-ftp-files-hashtable new-tbl))) 2990 (setq ange-ftp-files-hashtable new-tbl)))
3051 2991
@@ -3112,7 +3052,7 @@ logged in as user USER and cd'd to directory DIR."
3112 (fix-name-func 3052 (fix-name-func
3113 (cdr (assq host-type ange-ftp-fix-name-func-alist))) 3053 (cdr (assq host-type ange-ftp-fix-name-func-alist)))
3114 (key (concat host "/" user "/" dir)) 3054 (key (concat host "/" user "/" dir))
3115 (res (ange-ftp-get-hash-entry key ange-ftp-expand-dir-hashtable))) 3055 (res (gethash key ange-ftp-expand-dir-hashtable)))
3116 (or res 3056 (or res
3117 (progn 3057 (progn
3118 (or 3058 (or
@@ -3144,8 +3084,7 @@ logged in as user USER and cd'd to directory DIR."
3144 (ange-ftp-this-host host)) 3084 (ange-ftp-this-host host))
3145 (if fix-name-func 3085 (if fix-name-func
3146 (setq res (funcall fix-name-func res 'reverse))) 3086 (setq res (funcall fix-name-func res 'reverse)))
3147 (ange-ftp-put-hash-entry 3087 (puthash key res ange-ftp-expand-dir-hashtable)))
3148 key res ange-ftp-expand-dir-hashtable)))
3149 res)))) 3088 res))))
3150 3089
3151(defun ange-ftp-canonize-filename (n) 3090(defun ange-ftp-canonize-filename (n)
@@ -3372,8 +3311,8 @@ system TYPE.")
3372 (if (or (file-exists-p filename) 3311 (if (or (file-exists-p filename)
3373 (progn 3312 (progn
3374 (setq ange-ftp-ls-cache-file nil) 3313 (setq ange-ftp-ls-cache-file nil)
3375 (ange-ftp-del-hash-entry (file-name-directory filename) 3314 (remhash (file-name-directory filename)
3376 ange-ftp-files-hashtable) 3315 ange-ftp-files-hashtable)
3377 (file-exists-p filename))) 3316 (file-exists-p filename)))
3378 (let* ((host (nth 0 parsed)) 3317 (let* ((host (nth 0 parsed))
3379 (user (nth 1 parsed)) 3318 (user (nth 1 parsed))
@@ -3447,13 +3386,13 @@ system TYPE.")
3447 (setq file (ange-ftp-expand-file-name file)) 3386 (setq file (ange-ftp-expand-file-name file))
3448 (if (ange-ftp-ftp-name file) 3387 (if (ange-ftp-ftp-name file)
3449 (let ((file-ent 3388 (let ((file-ent
3450 (ange-ftp-get-hash-entry 3389 (gethash
3451 (ange-ftp-get-file-part file) 3390 (ange-ftp-get-file-part file)
3452 (ange-ftp-get-files (file-name-directory file))))) 3391 (ange-ftp-get-files (file-name-directory file)))))
3453 (if (stringp file-ent) 3392 (if (stringp file-ent)
3454 (if (file-name-absolute-p file-ent) 3393 (if (file-name-absolute-p file-ent)
3455 (ange-ftp-replace-name-component 3394 (ange-ftp-replace-name-component
3456 (file-name-directory file) file-ent) 3395 (file-name-directory file) file-ent)
3457 file-ent))) 3396 file-ent)))
3458 (ange-ftp-real-file-symlink-p file))) 3397 (ange-ftp-real-file-symlink-p file)))
3459 3398
@@ -3516,13 +3455,12 @@ system TYPE.")
3516 (let ((host (nth 0 parsed)) 3455 (let ((host (nth 0 parsed))
3517 (user (nth 1 parsed)) 3456 (user (nth 1 parsed))
3518 (name (nth 2 parsed)) 3457 (name (nth 2 parsed))
3519 (dirp (ange-ftp-get-hash-entry part files)) 3458 (dirp (gethash part files))
3520 (inode (ange-ftp-get-hash-entry 3459 (inode (gethash file ange-ftp-inodes-hashtable)))
3521 file ange-ftp-inodes-hashtable)))
3522 (unless inode 3460 (unless inode
3523 (setq inode ange-ftp-next-inode-number 3461 (setq inode ange-ftp-next-inode-number
3524 ange-ftp-next-inode-number (1+ inode)) 3462 ange-ftp-next-inode-number (1+ inode))
3525 (ange-ftp-put-hash-entry file inode ange-ftp-inodes-hashtable)) 3463 (puthash file inode ange-ftp-inodes-hashtable))
3526 (list (if (and (stringp dirp) (file-name-absolute-p dirp)) 3464 (list (if (and (stringp dirp) (file-name-absolute-p dirp))
3527 (ange-ftp-expand-symlink dirp 3465 (ange-ftp-expand-symlink dirp
3528 (file-name-directory file)) 3466 (file-name-directory file))
@@ -3905,7 +3843,7 @@ E.g.,
3905 (and verbose-p (format "%s --> %s" from-file to-file)) 3843 (and verbose-p (format "%s --> %s" from-file to-file))
3906 (list 'ange-ftp-copy-files-async verbose-p (cdr files)) 3844 (list 'ange-ftp-copy-files-async verbose-p (cdr files))
3907 t)) 3845 t))
3908 (message "%s: done" 'ange-ftp-copy-files-async))) 3846 (message "%s: done" 'ange-ftp-copy-files-async)))
3909 3847
3910 3848
3911;;;; ------------------------------------------------------------ 3849;;;; ------------------------------------------------------------
@@ -3987,27 +3925,24 @@ E.g.,
3987 3925
3988;; If the file entry SYM is a symlink, returns whether its file exists. 3926;; If the file entry SYM is a symlink, returns whether its file exists.
3989;; Note that `ange-ftp-this-dir' is used as a free variable. 3927;; Note that `ange-ftp-this-dir' is used as a free variable.
3990(defun ange-ftp-file-entry-active-p (sym) 3928(defun ange-ftp-file-entry-active-p (key val)
3991 (let ((val (get sym 'val))) 3929 (or (not (stringp val))
3992 (or (not (stringp val)) 3930 (file-exists-p (ange-ftp-expand-symlink val ange-ftp-this-dir))))
3993 (file-exists-p (ange-ftp-expand-symlink val ange-ftp-this-dir)))))
3994 3931
3995;; If the file entry is not a directory (nor a symlink pointing to a directory) 3932;; If the file entry is not a directory (nor a symlink pointing to a directory)
3996;; returns whether the file (or file pointed to by the symlink) is ignored 3933;; returns whether the file (or file pointed to by the symlink) is ignored
3997;; by completion-ignored-extensions. 3934;; by completion-ignored-extensions.
3998;; Note that `ange-ftp-this-dir' and `ange-ftp-completion-ignored-pattern' 3935;; Note that `ange-ftp-this-dir' and `ange-ftp-completion-ignored-pattern'
3999;; are used as free variables. 3936;; are used as free variables.
4000(defun ange-ftp-file-entry-not-ignored-p (sym) 3937(defun ange-ftp-file-entry-not-ignored-p (symname val)
4001 (let ((val (get sym 'val)) 3938 (if (stringp val)
4002 (symname (symbol-name sym))) 3939 (let ((file (ange-ftp-expand-symlink val ange-ftp-this-dir)))
4003 (if (stringp val) 3940 (or (file-directory-p file)
4004 (let ((file (ange-ftp-expand-symlink val ange-ftp-this-dir))) 3941 (and (file-exists-p file)
4005 (or (file-directory-p file) 3942 (not (string-match ange-ftp-completion-ignored-pattern
4006 (and (file-exists-p file) 3943 symname)))))
4007 (not (string-match ange-ftp-completion-ignored-pattern 3944 (or val ; is a directory name
4008 symname))))) 3945 (not (string-match ange-ftp-completion-ignored-pattern symname)))))
4009 (or val ; is a directory name
4010 (not (string-match ange-ftp-completion-ignored-pattern symname))))))
4011 3946
4012(defun ange-ftp-root-dir-p (dir) 3947(defun ange-ftp-root-dir-p (dir)
4013 ;; Maybe we should use something more like 3948 ;; Maybe we should use something more like
@@ -4031,14 +3966,14 @@ E.g.,
4031 ;; see whether each matching file is a directory or not... 3966 ;; see whether each matching file is a directory or not...
4032 (mapcar 3967 (mapcar
4033 (lambda (file) 3968 (lambda (file)
4034 (let ((ent (ange-ftp-get-hash-entry file tbl))) 3969 (let ((ent (gethash file tbl)))
4035 (if (and ent 3970 (if (and ent
4036 (or (not (stringp ent)) 3971 (or (not (stringp ent))
4037 (file-directory-p 3972 (file-directory-p
4038 (ange-ftp-expand-symlink ent 3973 (ange-ftp-expand-symlink ent
4039 ange-ftp-this-dir)))) 3974 ange-ftp-this-dir))))
4040 (concat file "/") 3975 (concat file "/")
4041 file))) 3976 file)))
4042 completions))) 3977 completions)))
4043 3978
4044 (if (ange-ftp-root-dir-p ange-ftp-this-dir) 3979 (if (ange-ftp-root-dir-p ange-ftp-this-dir)
@@ -4116,7 +4051,7 @@ directory, so that Emacs will know its current contents."
4116 (if (ange-ftp-ftp-name dir) 4051 (if (ange-ftp-ftp-name dir)
4117 (progn 4052 (progn
4118 (setq ange-ftp-ls-cache-file nil) 4053 (setq ange-ftp-ls-cache-file nil)
4119 (ange-ftp-del-hash-entry dir ange-ftp-files-hashtable) 4054 (remhash dir ange-ftp-files-hashtable)
4120 (ange-ftp-get-files dir t)))) 4055 (ange-ftp-get-files dir t))))
4121 4056
4122(defun ange-ftp-make-directory (dir &optional parents) 4057(defun ange-ftp-make-directory (dir &optional parents)
@@ -4963,10 +4898,10 @@ NEWNAME should be the name to give the new compressed or uncompressed file.")
4963; (progn 4898; (progn
4964; (end-of-line 1) 4899; (end-of-line 1)
4965; (point)))) 4900; (point))))
4966; (ange-ftp-put-hash-entry file type-is-dir tbl) 4901; (puthash file type-is-dir tbl)
4967; (forward-line 1)))) 4902; (forward-line 1))))
4968; (ange-ftp-put-hash-entry "." 'vosdir tbl) 4903; (puthash "." 'vosdir tbl)
4969; (ange-ftp-put-hash-entry ".." 'vosdir tbl)) 4904; (puthash ".." 'vosdir tbl))
4970; tbl)) 4905; tbl))
4971; 4906;
4972;(or (assq 'vos ange-ftp-parse-list-func-alist) 4907;(or (assq 'vos ange-ftp-parse-list-func-alist)
@@ -5087,27 +5022,25 @@ Other orders of $ and _ seem to all work just fine.")
5087;; Parse the current buffer which is assumed to be in MultiNet FTP dir 5022;; Parse the current buffer which is assumed to be in MultiNet FTP dir
5088;; format, and return a hashtable as the result. 5023;; format, and return a hashtable as the result.
5089(defun ange-ftp-parse-vms-listing () 5024(defun ange-ftp-parse-vms-listing ()
5090 (let ((tbl (ange-ftp-make-hashtable)) 5025 (let ((tbl (make-hash-table :test 'equal))
5091 file) 5026 file)
5092 (goto-char (point-min)) 5027 (goto-char (point-min))
5093 (save-match-data 5028 (save-match-data
5094 (while (setq file (ange-ftp-parse-vms-filename)) 5029 (while (setq file (ange-ftp-parse-vms-filename))
5095 (if (string-match "\\.\\(DIR\\|dir\\);[0-9]+" file) 5030 (if (string-match "\\.\\(DIR\\|dir\\);[0-9]+" file)
5096 ;; deal with directories 5031 ;; deal with directories
5097 (ange-ftp-put-hash-entry 5032 (puthash (substring file 0 (match-beginning 0)) t tbl)
5098 (substring file 0 (match-beginning 0)) t tbl) 5033 (puthash file nil tbl)
5099 (ange-ftp-put-hash-entry file nil tbl)
5100 (if (string-match ";[0-9]+$" file) ; deal with extension 5034 (if (string-match ";[0-9]+$" file) ; deal with extension
5101 ;; sans extension 5035 ;; sans extension
5102 (ange-ftp-put-hash-entry 5036 (puthash (substring file 0 (match-beginning 0)) nil tbl)))
5103 (substring file 0 (match-beginning 0)) nil tbl)))
5104 (forward-line 1)) 5037 (forward-line 1))
5105 ;; Would like to look for a "Total" line, or a "Directory" line to 5038 ;; Would like to look for a "Total" line, or a "Directory" line to
5106 ;; make sure that the listing isn't complete garbage before putting 5039 ;; make sure that the listing isn't complete garbage before putting
5107 ;; in "." and "..", but we can't even count on all VAX's giving us 5040 ;; in "." and "..", but we can't even count on all VAX's giving us
5108 ;; either of these. 5041 ;; either of these.
5109 (ange-ftp-put-hash-entry "." t tbl) 5042 (puthash "." t tbl)
5110 (ange-ftp-put-hash-entry ".." t tbl)) 5043 (puthash ".." t tbl))
5111 tbl)) 5044 tbl))
5112 5045
5113(or (assq 'vms ange-ftp-parse-list-func-alist) 5046(or (assq 'vms ange-ftp-parse-list-func-alist)
@@ -5130,9 +5063,8 @@ Other orders of $ and _ seem to all work just fine.")
5130 ;; In VMS you can't delete a file without an explicit 5063 ;; In VMS you can't delete a file without an explicit
5131 ;; version number, or wild-card (e.g. FOO;*) 5064 ;; version number, or wild-card (e.g. FOO;*)
5132 ;; For now, we give up on wildcards. 5065 ;; For now, we give up on wildcards.
5133 (let ((files (ange-ftp-get-hash-entry 5066 (let ((files (gethash (file-name-directory name)
5134 (file-name-directory name) 5067 ange-ftp-files-hashtable)))
5135 ange-ftp-files-hashtable)))
5136 (if files 5068 (if files
5137 (let* ((root (substring file 0 5069 (let* ((root (substring file 0
5138 (match-beginning 0))) 5070 (match-beginning 0)))
@@ -5140,17 +5072,17 @@ Other orders of $ and _ seem to all work just fine.")
5140 (regexp-quote root) 5072 (regexp-quote root)
5141 ";[0-9]+$")) 5073 ";[0-9]+$"))
5142 versions) 5074 versions)
5143 (ange-ftp-del-hash-entry file files) 5075 (remhash file files)
5144 ;; Now we need to check if there are any 5076 ;; Now we need to check if there are any
5145 ;; versions left. If not, then delete the 5077 ;; versions left. If not, then delete the
5146 ;; root entry. 5078 ;; root entry.
5147 (mapatoms 5079 (maphash
5148 (lambda (sym) 5080 (lambda (key val)
5149 (and (string-match regexp (get sym 'key)) 5081 (and (string-match regexp key)
5150 (setq versions t))) 5082 (setq versions t)))
5151 files) 5083 files)
5152 (or versions 5084 (or versions
5153 (ange-ftp-del-hash-entry root files)))))))))) 5085 (remhash root files))))))))))
5154 5086
5155(or (assq 'vms ange-ftp-delete-file-entry-alist) 5087(or (assq 'vms ange-ftp-delete-file-entry-alist)
5156 (setq ange-ftp-delete-file-entry-alist 5088 (setq ange-ftp-delete-file-entry-alist
@@ -5160,38 +5092,34 @@ Other orders of $ and _ seem to all work just fine.")
5160(defun ange-ftp-vms-add-file-entry (name &optional dir-p) 5092(defun ange-ftp-vms-add-file-entry (name &optional dir-p)
5161 (if dir-p 5093 (if dir-p
5162 (ange-ftp-internal-add-file-entry name t) 5094 (ange-ftp-internal-add-file-entry name t)
5163 (let ((files (ange-ftp-get-hash-entry 5095 (let ((files (gethash (file-name-directory name)
5164 (file-name-directory name) 5096 ange-ftp-files-hashtable)))
5165 ange-ftp-files-hashtable)))
5166 (if files 5097 (if files
5167 (let ((file (ange-ftp-get-file-part name))) 5098 (let ((file (ange-ftp-get-file-part name)))
5168 (save-match-data 5099 (save-match-data
5169 (if (string-match ";[0-9]+$" file) 5100 (if (string-match ";[0-9]+$" file)
5170 (ange-ftp-put-hash-entry 5101 (puthash (substring file 0 (match-beginning 0)) nil files)
5171 (substring file 0 (match-beginning 0))
5172 nil files)
5173 ;; Need to figure out what version of the file 5102 ;; Need to figure out what version of the file
5174 ;; is being added. 5103 ;; is being added.
5175 (let ((regexp (concat "^" 5104 (let ((regexp (concat "^"
5176 (regexp-quote file) 5105 (regexp-quote file)
5177 ";\\([0-9]+\\)$")) 5106 ";\\([0-9]+\\)$"))
5178 (version 0)) 5107 (version 0))
5179 (mapatoms 5108 (maphash
5180 (lambda (sym) 5109 (lambda (name val)
5181 (let ((name (get sym 'key))) 5110 (and (string-match regexp name)
5182 (and (string-match regexp name) 5111 (setq version
5183 (setq version 5112 (max version
5184 (max version 5113 (string-to-int
5185 (string-to-int 5114 (substring name
5186 (substring name 5115 (match-beginning 1)
5187 (match-beginning 1) 5116 (match-end 1)))))))
5188 (match-end 1))))))))
5189 files) 5117 files)
5190 (setq version (1+ version)) 5118 (setq version (1+ version))
5191 (ange-ftp-put-hash-entry 5119 (puthash
5192 (concat file ";" (int-to-string version)) 5120 (concat file ";" (int-to-string version))
5193 nil files)))) 5121 nil files))))
5194 (ange-ftp-put-hash-entry file nil files)))))) 5122 (puthash file nil files))))))
5195 5123
5196(or (assq 'vms ange-ftp-add-file-entry-alist) 5124(or (assq 'vms ange-ftp-add-file-entry-alist)
5197 (setq ange-ftp-add-file-entry-alist 5125 (setq ange-ftp-add-file-entry-alist
@@ -5588,7 +5516,7 @@ Other orders of $ and _ seem to all work just fine.")
5588 5516
5589;; Parse the current buffer which is assumed to be in mts ftp dir format. 5517;; Parse the current buffer which is assumed to be in mts ftp dir format.
5590(defun ange-ftp-parse-mts-listing () 5518(defun ange-ftp-parse-mts-listing ()
5591 (let ((tbl (ange-ftp-make-hashtable))) 5519 (let ((tbl (make-hash-table :test 'equal)))
5592 (goto-char (point-min)) 5520 (goto-char (point-min))
5593 (save-match-data 5521 (save-match-data
5594 (while (re-search-forward ange-ftp-date-regexp nil t) 5522 (while (re-search-forward ange-ftp-date-regexp nil t)
@@ -5596,10 +5524,10 @@ Other orders of $ and _ seem to all work just fine.")
5596 (skip-chars-backward " ") 5524 (skip-chars-backward " ")
5597 (let ((end (point))) 5525 (let ((end (point)))
5598 (skip-chars-backward "-A-Z0-9_.!") 5526 (skip-chars-backward "-A-Z0-9_.!")
5599 (ange-ftp-put-hash-entry (buffer-substring (point) end) nil tbl)) 5527 (puthash (buffer-substring (point) end) nil tbl))
5600 (forward-line 1))) 5528 (forward-line 1)))
5601 ;; Don't need to bother with .. 5529 ;; Don't need to bother with ..
5602 (ange-ftp-put-hash-entry "." t tbl) 5530 (puthash "." t tbl)
5603 tbl)) 5531 tbl))
5604 5532
5605(or (assq 'mts ange-ftp-parse-list-func-alist) 5533(or (assq 'mts ange-ftp-parse-list-func-alist)
@@ -5815,19 +5743,19 @@ Other orders of $ and _ seem to all work just fine.")
5815; (minidisk (ange-ftp-get-file-part dir-file)) 5743; (minidisk (ange-ftp-get-file-part dir-file))
5816; (root-tbl (ange-ftp-get-hash-entry root ange-ftp-files-hashtable))) 5744; (root-tbl (ange-ftp-get-hash-entry root ange-ftp-files-hashtable)))
5817; (if root-tbl 5745; (if root-tbl
5818; (ange-ftp-put-hash-entry minidisk t root-tbl) 5746; (puthash minidisk t root-tbl)
5819; (setq root-tbl (ange-ftp-make-hashtable)) 5747; (setq root-tbl (ange-ftp-make-hashtable))
5820; (ange-ftp-put-hash-entry minidisk t root-tbl) 5748; (puthash minidisk t root-tbl)
5821; (ange-ftp-put-hash-entry "." t root-tbl) 5749; (puthash "." t root-tbl)
5822; (ange-ftp-set-files root root-tbl))) 5750; (ange-ftp-set-files root root-tbl)))
5823 ;; Now do the usual parsing 5751 ;; Now do the usual parsing
5824 (let ((tbl (ange-ftp-make-hashtable))) 5752 (let ((tbl (make-hash-table :test 'equal)))
5825 (goto-char (point-min)) 5753 (goto-char (point-min))
5826 (save-match-data 5754 (save-match-data
5827 (while 5755 (while
5828 (re-search-forward 5756 (re-search-forward
5829 "^\\([-A-Z0-9$_]+\\) +\\([-A-Z0-9$_]+\\) +[VF] +[0-9]+ " nil t) 5757 "^\\([-A-Z0-9$_]+\\) +\\([-A-Z0-9$_]+\\) +[VF] +[0-9]+ " nil t)
5830 (ange-ftp-put-hash-entry 5758 (puthash
5831 (concat (buffer-substring (match-beginning 1) 5759 (concat (buffer-substring (match-beginning 1)
5832 (match-end 1)) 5760 (match-end 1))
5833 "." 5761 "."
@@ -5835,7 +5763,7 @@ Other orders of $ and _ seem to all work just fine.")
5835 (match-end 2))) 5763 (match-end 2)))
5836 nil tbl) 5764 nil tbl)
5837 (forward-line 1)) 5765 (forward-line 1))
5838 (ange-ftp-put-hash-entry "." t tbl)) 5766 (puthash "." t tbl))
5839 tbl)) 5767 tbl))
5840 5768
5841(or (assq 'cms ange-ftp-parse-list-func-alist) 5769(or (assq 'cms ange-ftp-parse-list-func-alist)
@@ -5955,14 +5883,14 @@ Other orders of $ and _ seem to all work just fine.")
5955 "^\\(" ange-ftp-bs2000-filename-pubset-regexp "\\)?" 5883 "^\\(" ange-ftp-bs2000-filename-pubset-regexp "\\)?"
5956 "\\(" ange-ftp-bs2000-filename-username-regexp "\\)?" 5884 "\\(" ange-ftp-bs2000-filename-username-regexp "\\)?"
5957 "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") 5885 "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?")
5958"Regular expression used in ange-ftp-fix-name-for-bs2000.") 5886 "Regular expression used in ange-ftp-fix-name-for-bs2000.")
5959 5887
5960(defconst ange-ftp-bs2000-fix-name-regexp 5888(defconst ange-ftp-bs2000-fix-name-regexp
5961 (concat 5889 (concat
5962 "/?\\(" ange-ftp-bs2000-filename-pubset-regexp "/\\)?" 5890 "/?\\(" ange-ftp-bs2000-filename-pubset-regexp "/\\)?"
5963 "\\(\\$[A-Z0-9]*/\\)?" 5891 "\\(\\$[A-Z0-9]*/\\)?"
5964 "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?") 5892 "\\(" ange-ftp-bs2000-short-filename-regexp "\\)?")
5965"Regular expression used in ange-ftp-fix-name-for-bs2000.") 5893 "Regular expression used in ange-ftp-fix-name-for-bs2000.")
5966 5894
5967(defcustom ange-ftp-bs2000-special-prefix 5895(defcustom ange-ftp-bs2000-special-prefix
5968 "X" 5896 "X"
@@ -6123,7 +6051,7 @@ Other orders of $ and _ seem to all work just fine.")
6123;; Parse the current buffer which is assumed to be in (some) BS2000 FTP dir 6051;; Parse the current buffer which is assumed to be in (some) BS2000 FTP dir
6124;; format, and return a hashtable as the result. 6052;; format, and return a hashtable as the result.
6125(defun ange-ftp-parse-bs2000-listing () 6053(defun ange-ftp-parse-bs2000-listing ()
6126 (let ((tbl (ange-ftp-make-hashtable)) 6054 (let ((tbl (make-hash-table :test 'equal))
6127 pubset 6055 pubset
6128 file) 6056 file)
6129 ;; get current pubset 6057 ;; get current pubset
@@ -6134,14 +6062,13 @@ Other orders of $ and _ seem to all work just fine.")
6134 (goto-char (point-min)) 6062 (goto-char (point-min))
6135 (save-match-data 6063 (save-match-data
6136 (while (setq file (ange-ftp-parse-bs2000-filename)) 6064 (while (setq file (ange-ftp-parse-bs2000-filename))
6137 (ange-ftp-put-hash-entry file nil tbl))) 6065 (puthash file nil tbl)))
6138 ;; add . and .. 6066 ;; add . and ..
6139 (ange-ftp-put-hash-entry "." t tbl) 6067 (puthash "." t tbl)
6140 (ange-ftp-put-hash-entry ".." t tbl) 6068 (puthash ".." t tbl)
6141 ;; add all additional pubsets, if not listing one of them 6069 ;; add all additional pubsets, if not listing one of them
6142 (if (not (member pubset ange-ftp-bs2000-additional-pubsets)) 6070 (if (not (member pubset ange-ftp-bs2000-additional-pubsets))
6143 (mapcar (function (lambda (pubset) 6071 (mapcar (lambda (pubset) (puthash pubset t tbl))
6144 (ange-ftp-put-hash-entry pubset t tbl)))
6145 ange-ftp-bs2000-additional-pubsets)) 6072 ange-ftp-bs2000-additional-pubsets))
6146 tbl)) 6073 tbl))
6147 6074
@@ -6162,9 +6089,9 @@ be recognized automatically (they are all valid BS2000 hosts too)."
6162 (ange-ftp-cd host user "%POSIX") 6089 (ange-ftp-cd host user "%POSIX")
6163 ;; put new home directory in the expand-dir hashtable. 6090 ;; put new home directory in the expand-dir hashtable.
6164 ;; `host' and `user' are bound in ange-ftp-get-process. 6091 ;; `host' and `user' are bound in ange-ftp-get-process.
6165 (ange-ftp-put-hash-entry (concat host "/" user "/~") 6092 (puthash (concat host "/" user "/~")
6166 (car (ange-ftp-get-pwd host user)) 6093 (car (ange-ftp-get-pwd host user))
6167 ange-ftp-expand-dir-hashtable)))) 6094 ange-ftp-expand-dir-hashtable))))
6168 6095
6169;; Not available yet: 6096;; Not available yet:
6170;; ange-ftp-bs2000-delete-file-entry 6097;; ange-ftp-bs2000-delete-file-entry