+(defun desktop-list* (&rest args)
+ (if (null (cdr args))
+ (car args)
+ (setq args (nreverse args))
+ (let ((value (cons (nth 1 args) (car args))))
+ (setq args (cdr (cdr args)))
+ (while args
+ (setq value (cons (car args) value))
+ (setq args (cdr args)))
+ value)))
+
+(defun desktop-internal-v2s (val)
+ "Convert VALUE to a pair (QUOTE . TXT); (eval (read TXT)) gives VALUE.
+TXT is a string that when read and evaluated yields value.
+QUOTE may be `may' (value may be quoted),
+`must' (values must be quoted), or nil (value may not be quoted)."
+ (cond
+ ((or (numberp val) (null val) (eq t val))
+ (cons 'may (prin1-to-string val)))
+ ((stringp val)
+ (let ((copy (copy-sequence val)))
+ (set-text-properties 0 (length copy) nil copy)
+ ;; Get rid of text properties because we cannot read them
+ (cons 'may (prin1-to-string copy))))
+ ((symbolp val)
+ (cons 'must (prin1-to-string val)))
+ ((vectorp val)
+ (let* ((special nil)
+ (pass1 (mapcar
+ (lambda (el)
+ (let ((res (desktop-internal-v2s el)))
+ (if (null (car res))
+ (setq special t))
+ res))
+ val)))
+ (if special
+ (cons nil (concat "(vector "
+ (mapconcat (lambda (el)
+ (if (eq (car el) 'must)
+ (concat "'" (cdr el))
+ (cdr el)))
+ pass1
+ " ")
+ ")"))
+ (cons 'may (concat "[" (mapconcat 'cdr pass1 " ") "]")))))
+ ((consp val)
+ (let ((p val)
+ newlist
+ use-list*
+ anynil)
+ (while (consp p)
+ (let ((q.txt (desktop-internal-v2s (car p))))
+ (or anynil (setq anynil (null (car q.txt))))
+ (setq newlist (cons q.txt newlist)))
+ (setq p (cdr p)))
+ (if p
+ (let ((last (desktop-internal-v2s p))
+ (el (car newlist)))
+ (or anynil (setq anynil (null (car last))))
+ (or anynil
+ (setq newlist (cons '(must . ".") newlist)))
+ (setq use-list* t)
+ (setq newlist (cons last newlist))))
+ (setq newlist (nreverse newlist))
+ (if anynil
+ (cons nil
+ (concat (if use-list* "(desktop-list* " "(list ")
+ (mapconcat (lambda (el)
+ (if (eq (car el) 'must)
+ (concat "'" (cdr el))
+ (cdr el)))
+ newlist
+ " ")
+ ")"))
+ (cons 'must
+ (concat "(" (mapconcat 'cdr newlist " ") ")")))))
+ ((subrp val)
+ (cons nil (concat "(symbol-function '"
+ (substring (prin1-to-string val) 7 -1)
+ ")")))
+ ((markerp val)
+ (let ((pos (prin1-to-string (marker-position val)))
+ (buf (prin1-to-string (buffer-name (marker-buffer val)))))
+ (cons nil (concat "(let ((mk (make-marker)))"
+ " (add-hook 'desktop-delay-hook"
+ " (list 'lambda '() (list 'set-marker mk "
+ pos " (get-buffer " buf ")))) mk)"))))
+ (t ; save as text
+ (cons 'may "\"Unprintable entity\""))))
+
+(defun desktop-value-to-string (val)
+ "Convert VALUE to a string that when read evaluates to the same value.
+Not all types of values are supported."
+ (let* ((print-escape-newlines t)
+ (float-output-format nil)
+ (quote.txt (desktop-internal-v2s val))
+ (quote (car quote.txt))
+ (txt (cdr quote.txt)))
+ (if (eq quote 'must)
+ (concat "'" txt)
+ txt)))