debian update
[kmrcl.git] / impl.lisp
1 ;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          impl.lisp
6 ;;;; Purpose:       Implementation Dependent routines for kmrcl
7 ;;;; Programmer:    Kevin M. Rosenberg
8 ;;;; Date Started:  Sep 2003
9 ;;;;
10 ;;;; This file, part of KMRCL, is Copyright (c) 2002 by Kevin M. Rosenberg
11 ;;;;
12 ;;;; KMRCL users are granted the rights to distribute and use this software
13 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
14 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
15 ;;;; *************************************************************************
16
17 (in-package #:kmrcl)
18
19 (defun canonicalize-directory-name (filename)
20   (flet ((un-unspecific (value)
21            (if (eq value :unspecific) nil value)))
22     (let* ((path (pathname filename))
23            (name (un-unspecific (pathname-name path)))
24            (type (un-unspecific (pathname-type path)))
25            (new-dir
26             (cond ((and name type) (list (concatenate 'string name "." type)))
27                   (name (list name))
28                   (type (list type))
29                   (t nil))))
30       (if new-dir
31           (make-pathname
32            :directory (append (un-unspecific (pathname-directory path))
33                               new-dir)
34                     :name nil :type nil :version nil :defaults path)
35           path))))
36
37
38 (defun probe-directory (filename &key (error-if-does-not-exist nil))
39   (let* ((path (canonicalize-directory-name filename))
40          (probe
41           #+allegro (excl:probe-directory path)
42           #+clisp (values
43                    (ignore-errors
44                      (#+lisp=cl ext:probe-directory
45                                 #-lisp=cl lisp:probe-directory
46                                 path)))
47           #+(or cmu scl) (when (eq :directory
48                                    (unix:unix-file-kind (namestring path)))
49                            path)
50           #+lispworks (when (lw:file-directory-p path)
51                         path)
52           #+sbcl
53           (let ((file-kind-fun
54                  (or (find-symbol "NATIVE-FILE-KIND" :sb-impl)
55                      (find-symbol "UNIX-FILE-KIND" :sb-unix))))
56             (when (eq :directory (funcall file-kind-fun (namestring path)))
57               path))
58           #-(or allegro clisp cmu lispworks sbcl scl)
59           (probe-file path)))
60     (if probe
61         probe
62         (when error-if-does-not-exist
63           (error "Directory ~A does not exist." filename)))))
64
65 (defun cwd (&optional dir)
66   "Change directory and set default pathname"
67   (cond
68    ((not (null dir))
69     (when (and (typep dir 'logical-pathname)
70                (translate-logical-pathname dir))
71       (setq dir (translate-logical-pathname dir)))
72     (when (stringp dir)
73       (setq dir (parse-namestring dir)))
74     #+allegro (excl:chdir dir)
75     #+clisp (#+lisp=cl ext:cd #-lisp=cl lisp:cd dir)
76     #+(or cmu scl) (setf (ext:default-directory) dir)
77     #+cormanlisp (ccl:set-current-directory dir)
78     #+(and mcl (not openmcl)) (ccl:set-mac-default-directory dir)
79     #+openmcl (ccl:cwd dir)
80     #+gcl (si:chdir dir)
81     #+lispworks (hcl:change-directory dir)
82     (setq cl:*default-pathname-defaults* dir))
83    (t
84     (let ((dir
85            #+allegro (excl:current-directory)
86            #+clisp (#+lisp=cl ext:default-directory #-lisp=cl lisp:default-directory)
87            #+(or cmu scl) (ext:default-directory)
88            #+sbcl (sb-unix:posix-getcwd/)
89            #+cormanlisp (ccl:get-current-directory)
90            #+lispworks (hcl:get-working-directory)
91            #+mcl (ccl:mac-default-directory)
92            #-(or allegro clisp cmu scl cormanlisp mcl sbcl lispworks) (truename ".")))
93       (when (stringp dir)
94         (setq dir (parse-namestring dir)))
95       dir))))
96
97
98
99 (defun quit (&optional (code 0))
100   "Function to exit the Lisp implementation. Copied from CLOCC's QUIT function."
101     #+allegro (excl:exit code :quiet t)
102     #+clisp (#+lisp=cl ext:quit #-lisp=cl lisp:quit code)
103     #+(or cmu scl) (ext:quit code)
104     #+cormanlisp (win32:exitprocess code)
105     #+gcl (lisp:bye code)
106     #+lispworks (lw:quit :status code)
107     #+lucid (lcl:quit code)
108     #+sbcl (sb-ext:exit :code (typecase code (number code) (null 0) (t 1)))
109     #+mcl (ccl:quit code)
110     #-(or allegro clisp cmu scl cormanlisp gcl lispworks lucid sbcl mcl)
111     (error 'not-implemented :proc (list 'quit code)))
112
113
114 (defun command-line-arguments ()
115   #+allegro (system:command-line-arguments)
116   #+sbcl sb-ext:*posix-argv*
117   )
118
119 (defun copy-file (from to &key link overwrite preserve-symbolic-links
120                   (preserve-time t) remove-destination force verbose)
121   #+allegro (sys:copy-file from to :link link :overwrite overwrite
122                            :preserve-symbolic-links preserve-symbolic-links
123                            :preserve-time preserve-time
124                            :remove-destination remove-destination
125                            :force force :verbose verbose)
126   #-allegro
127   (declare (ignore verbose preserve-symbolic-links overwrite))
128   (cond
129     ((and (typep from 'stream) (typep to 'stream))
130      (copy-binary-stream from to))
131     ((not (probe-file from))
132      (error "File ~A does not exist." from))
133     ((eq link :hard)
134      (run-shell-command "ln -f ~A ~A" (namestring from) (namestring to)))
135     (link
136      (multiple-value-bind (stdout stderr status)
137          (command-output "ln -f ~A ~A" (namestring from) (namestring to))
138        (declare (ignore stdout stderr))
139        ;; try symbolic if command failed
140        (unless (zerop status)
141          (run-shell-command "ln -sf ~A ~A" (namestring from) (namestring to)))))
142     (t
143      (when (and (or force remove-destination) (probe-file to))
144        (delete-file to))
145      (let* ((options (if preserve-time
146                          "-p"
147                          ""))
148             (cmd (format nil "cp ~A ~A ~A" options (namestring from) (namestring to))))
149        (run-shell-command cmd)))))