-;; #### The following two should probably use `replace-in-string'.
-
-(defun auto-save-unslashify-name (s)
- ;; "Quote any slashes in string S by replacing them with the two
- ;;characters `\\!'.
- ;;Also, replace any backslash by double backslash, to make it one-to-one."
- (let ((limit 0))
- (while (string-match "[/\\]" s limit)
- (setq s (concat (substring s 0 (match-beginning 0))
- (if (string= (substring s
- (match-beginning 0)
- (match-end 0))
- "/")
- "\\!"
- "\\\\")
- (substring s (match-end 0))))
- (setq limit (1+ (match-end 0)))))
- s)
-
-(defun auto-save-slashify-name (s)
- ;;"Reverse of `auto-save-unslashify-name'."
- (let (pos)
- (while (setq pos (string-match "\\\\[\\!]" s pos))
- (setq s (concat (substring s 0 pos)
- (if (eq ?! (aref s (1+ pos))) "/" "\\")
- (substring s (+ pos 2)))
- pos (1+ pos))))
- s)
+(defconst auto-save-reserved-chars
+ '(
+ ?\0 ?\1 ?\2 ?\3 ?\4 ?\5 ?\6 ?\7 ?\10 ?\11 ?\12 ?\13 ?\14 ?\15 ?\16
+ ?\17 ?\20 ?\21 ?\22 ?\23 ?\24 ?\25 ?\26 ?\27 ?\30 ?\31 ?\32 ?\33
+ ?\34 ?\35 ?\36 ?\37 ?\40 ?? ?* ?: ?< ?> ?| ?/ ?\\ ?& ?^ ?% ?= ?\")
+ "List of characters disallowed (or potentially disallowed) in filenames.
+Includes everything that can get us into trouble under MS Windows or Unix.")
+
+;; This code based on code in Bill Perry's url.el.
+
+(defun auto-save-escape-name (str)
+ "Escape any evil nasty characters in a potential filename.
+Uses quoted-printable-style escaping -- e.g. the dreaded =3D.
+Does not use URL escaping (with %) because filenames beginning with #% are
+a special signal for non-file buffers."
+ (mapconcat
+ (function
+ (lambda (char)
+ (if (memq char auto-save-reserved-chars)
+ (if (< char 16)
+ (upcase (format "=0%x" char))
+ (upcase (format "=%x" char)))
+ (char-to-string char))))
+ str ""))
+
+(defun auto-save-unhex (x)
+ (if (> x ?9)
+ (if (>= x ?a)
+ (+ 10 (- x ?a))
+ (+ 10 (- x ?A)))
+ (- x ?0)))
+
+(defun auto-save-unescape-name (str)
+ "Undo any escaping of evil nasty characters in a file name.
+See `auto-save-escape-name'."
+ (setq str (or str ""))
+ (let ((tmp "")
+ (case-fold-search t))
+ (while (string-match "=[0-9a-f][0-9a-f]" str)
+ (let* ((start (match-beginning 0))
+ (ch1 (auto-save-unhex (elt str (+ start 1))))
+ (code (+ (* 16 ch1)
+ (auto-save-unhex (elt str (+ start 2))))))
+ (setq tmp (concat tmp (substring str 0 start)
+ (char-to-string code))
+ str (substring str (match-end 0)))))
+ (setq tmp (concat tmp str))
+ tmp))
+
+;; The old versions are below.
+
+;(defun auto-save-escape-name (s)
+; ;; "Quote any slashes in string S by replacing them with the two
+; ;;characters `\\!'.
+; ;;Also, replace any backslash by double backslash, to make it one-to-one."
+; (let ((limit 0))
+; (while (string-match "[/\\]" s limit)
+; (setq s (concat (substring s 0 (match-beginning 0))
+; (if (string= (substring s
+; (match-beginning 0)
+; (match-end 0))
+; "/")
+; "\\!"
+; "\\\\")
+; (substring s (match-end 0))))
+; (setq limit (1+ (match-end 0)))))
+; s)
+
+;(defun auto-save-unescape-name (s)
+; ;;"Reverse of `auto-save-escape-name'."
+; (let (pos)
+; (while (setq pos (string-match "\\\\[\\!]" s pos))
+; (setq s (concat (substring s 0 pos)
+; (if (eq ?! (aref s (1+ pos))) "/" "\\")
+; (substring s (+ pos 2)))
+; pos (1+ pos))))
+; s)