2022-07-04 15:56:52 +02:00
|
|
|
;;; temp-file.lisp --- temporary file creation
|
|
|
|
|
|
|
|
;;; Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 by Walter C. Pelissero
|
|
|
|
;;; Copyright (C) 2022 The TVL Authors
|
|
|
|
|
|
|
|
;;; Author: Walter C. Pelissero <walter@pelissero.de>
|
|
|
|
;;; Project: mime4cl
|
|
|
|
;;;
|
|
|
|
;;; Code taken from SCLF
|
|
|
|
|
|
|
|
#+cmu (ext:file-comment "$Module: temp-file.lisp $")
|
|
|
|
|
|
|
|
;;; This library is free software; you can redistribute it and/or
|
|
|
|
;;; modify it under the terms of the GNU Lesser General Public License
|
|
|
|
;;; as published by the Free Software Foundation; either version 2.1
|
|
|
|
;;; of the License, or (at your option) any later version.
|
|
|
|
;;; This library is distributed in the hope that it will be useful,
|
|
|
|
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
;;; Lesser General Public License for more details.
|
|
|
|
;;; You should have received a copy of the GNU Lesser General Public
|
|
|
|
;;; License along with this library; if not, write to the Free
|
|
|
|
;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
|
;;; 02111-1307 USA
|
|
|
|
|
|
|
|
(in-package :mime4cl-tests)
|
|
|
|
|
|
|
|
(defvar *tmp-file-defaults* #P"/tmp/")
|
|
|
|
|
|
|
|
(defun temp-file-name (&optional (default *tmp-file-defaults*))
|
|
|
|
"Create a random pathname based on DEFAULT. No effort is made
|
|
|
|
to make sure that the returned pathname doesn't identify an
|
|
|
|
already existing file. If missing DEFAULT defaults to
|
|
|
|
*TMP-FILE-DEFAULTS*."
|
|
|
|
(make-pathname :defaults default
|
|
|
|
:name (format nil "~36R" (random #.(expt 36 10)))))
|
|
|
|
|
|
|
|
(defun open-temp-file (&optional default-pathname &rest open-args)
|
|
|
|
"Open a new temporary file and return a stream to it. This function
|
|
|
|
makes sure the pathname of the temporary file is unique. OPEN-ARGS
|
|
|
|
are arguments passed verbatim to OPEN. If OPEN-ARGS specify
|
|
|
|
the :DIRECTION it should be either :OUTPUT (default) or :IO;
|
|
|
|
any other value causes an error. If DEFAULT-PATHNAME is specified and
|
|
|
|
not NIL it's used as defaults to produce the pathname of the temporary
|
|
|
|
file, otherwise *TMP-FILE-DEFAULTS* is used."
|
|
|
|
(unless default-pathname
|
|
|
|
(setf default-pathname *tmp-file-defaults*))
|
|
|
|
;; if :DIRECTION is specified check that it's compatible with the
|
|
|
|
;; purpose of this function, otherwise make it default to :OUTPUT
|
|
|
|
(aif (getf open-args :direction)
|
|
|
|
(unless (member it '(:output :io))
|
|
|
|
(error "Can't create temporary file with open direction ~A." it))
|
|
|
|
(setf open-args (append '(:direction :output)
|
|
|
|
open-args)))
|
|
|
|
(do* ((name #1=(temp-file-name default-pathname) #1#)
|
|
|
|
(stream #2=(apply #'open name
|
|
|
|
:if-exists nil
|
|
|
|
:if-does-not-exist :create
|
|
|
|
open-args) #2#))
|
|
|
|
(stream stream)))
|
|
|
|
|
|
|
|
(defmacro with-temp-file ((stream &rest open-temp-args) &body body)
|
|
|
|
"Execute BODY within a dynamic extent where STREAM is bound to
|
|
|
|
a STREAM open on a unique temporary file name. OPEN-TEMP-ARGS are
|
|
|
|
passed verbatim to OPEN-TEMP-FILE."
|
2023-05-18 00:14:11 +02:00
|
|
|
`(let ((,stream (open-temp-file ,@open-temp-args)))
|
2022-07-04 15:56:52 +02:00
|
|
|
(unwind-protect
|
|
|
|
(progn ,@body)
|
|
|
|
(close ,stream)
|
|
|
|
;; body may decide to rename the file so we must ignore the errors
|
|
|
|
(ignore-errors
|
|
|
|
(delete-file (pathname ,stream))))))
|