On Tue, 2 Jun 2009, Robert Dodier wrote:
< Well, actually I was thinking that the plotting code or any other
< code which writes a temporary file would call mkstemp or
< its equivalent to get a new file name. All such files would
< go in the same directory (the one named by maxima_tempdir).
< I was intending to hide the temp name stuff from the user.
Robert,
I came up with the following lisp code to imitate mktemp. I modified plot-temp-file from
src/plot.lisp so that it now returns a name not already belonging to
an existing file.
Leo
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
-------------- next part --------------
(defvar *admissible-characters* (vector #\a #\b #\c #\d #\e #\f #\g #\h #\i #\j #\k #\l #\m #\n #\o #\p #\q #\r #\s #\t #\u #\v #\w #\x #\y #\z #\A #\B #\C #\D #\E #\F #\G #\H #\I #\J #\K #\L #\M #\N #\O #\P #\Q #\R #\S #\T #\U #\V #\W #\X #\Y #\Z #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))
(defvar *num-admissible-characters* (length *admissible-characters*))
(defvar *default-suffix-length* 6)
(defvar *default-tempfile-root* "maxima-temp-")
(defvar *default-special-char* #\X)
(defun randomise-template (template &key (special-char *default-special-char*) (seed *random-state*))
(declare (type 'string template) (type 'string-char special-char))
(map 'string #'(lambda (u)
(if (char= u special-char)
(make-random-char :seed seed) u)) template))
(defun make-random-char (&key (seed *random-state*))
(let* ((c (random *num-admissible-characters* seed)) (rand-char (aref *admissible-characters* c)))
rand-char))
(defun make-template (&key (root *default-tempfile-root*) (suffix-length *default-suffix-length*) (special-char *default-special-char*))
(declare (type 'string root) (type 'fixnum suffix-length))
(let ((suf ""))
(if (> suffix-length 0)
(progn
(setf suf (make-string suffix-length :initial-element special-char))
(concatenate 'string root suf))
(make-template :root root :special-char special-char)))))
(defun make-tempfilename (&key (template *default-tempfile-root*) (special-char *default-special-char*) (seed *random-state*))
"Function: make-tempfilename (&key (template *default-tempfile-root*) (special-char *default-special-char*) (seed *random-state*))
>(make-tempfilename) --> \"maxima-temp-FcUwTn\"
>(make-tempfilename :template \"maxout-XXXXXX.gnuplot\") --> \"maxout-dlEDpX.gnuplot\"
>(make-tempfilename :template \"tmp-YYYYYY\" :seed #$2134 :special-char #\Y) --> \"tmp-UGBt7S\"
The seed is overwritten, so to re-use, you must save seed externally or pass a constant.
Implements mkstemp.c in C-L (http://www.opensource.apple.com/source/shell_cmds/shell_cmds-118/mktemp/mktemp.c)
Due to portability issues (see http://www.faqs.org/faqs/lisp-faq/part2/section-19.html) we do not attempt to open/create files or directories."
(declare (type 'string template))
(when (string= template *default-tempfile-root*)
(setf template (make-template :root template)))
(if (stringp template)
(setf template (randomise-template template :special-char special-char :seed seed))
(make-tempfilename :special-char special-char :seed seed))
template)
;; Altered from src/plot.lisp
;; This adds 6 random chars at the end of
;; a file name, and returns this filename
;; if a file of that name does not exist.
(defun plot-temp-file (file &key (depth 0))
(let (tmp-file (max-depth most-positive-fixnum)) ;; 36^5 < most-positive-fixnum < 36^6
(if *maxima-tempdir*
(setf tmp-file (format nil "~a/~a" *maxima-tempdir* file))
(setf tmp-file file))
(setf tmp-file (make-tempfilename :template (make-template :root tmp-file)))
(when (and (probe-file tmp-file) (< depth max-depth))
(plot-temp-file file :depth (+ depth 1)))
tmp-file))