chiark / gitweb /
zone.lisp: New utility for hashing files.
[zone] / frontend.lisp
index 1ff3e2f0fab9a29e1e05bac432b4c4ccb6c95dae..0764c3f7cd43beea6ae526059cca40d75fbbb9e5 100644 (file)
@@ -22,8 +22,8 @@
 ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 (defpackage #:zone.frontend
-  (:use #:common-lisp #:optparse #:net #:zone
-       #+cmu #:mop
+  (:use #:common-lisp #:mdw.sys-base #:optparse #:net #:zone
+       #+(or cmu clisp) #:mop
        #+sbcl #:sb-mop)
   (:export #:main))
 (in-package #:zone.frontend)
@@ -32,10 +32,31 @@ (defvar opt-zones nil
   "Which zones to be emitted.")
 (defvar opt-format :bind
   "Which format to use on output.")
+(defvar opt-debug nil
+  "Whether to emit stack backtraces on error.")
+
+(defun directory-exists-p (name)
+
+  ;; Make a pathname for NAME which has the right form for a directory.
+  (let ((dirpath
+        (let ((path (pathname name)))
+          (if (null (pathname-name path))
+              path
+              (make-pathname :directory
+                             (append (or (pathname-directory path)
+                                         (list :relative))
+                                     (list (pathname-name path)))
+                             :name nil
+                             :type nil
+                             :defaults path)))))
+
+    ;; Now check that it exists.
+    #+clisp (and (ext:probe-directory dirpath) (truename dirpath))
+    #-clisp (probe-file dirpath)))
 
 (eval-when (:compile-toplevel :load-toplevel)
   (defopthandler dir (var arg) ()
-    (let ((path (probe-file arg)))
+    (let ((path (directory-exists-p arg)))
       (if (and path
               (not (pathname-name path)))
          (setf var path)
@@ -52,6 +73,8 @@ (define-program
                      (#\s "subnet" (:arg "NET")
                           (list zone:*preferred-subnets*)
                           "Designate NET as a preferred subnet.")
+                     (#\D "debug" (set opt-debug)
+                          "Produce stack backtrace on error.")
                      "Output options"
                      (#\d "directory" (:arg "DIRECTORY")
                           (dir *zone-output-path*)
@@ -60,8 +83,11 @@ (define-program
                           (keyword opt-format
                                    (delete-duplicates
                                     (loop for method in
-                                          (generic-function-methods
-                                           #'zone:zone-write)
+                                          (append
+                                           (generic-function-methods
+                                            #'zone:zone-write)
+                                           (generic-function-methods
+                                            #'zone:zone-write-header))
                                           for specs =
                                           (method-specializers method)
                                           if (typep (car specs)
@@ -74,20 +100,26 @@ (define-program
                           "Write information about zone NAME.")))
 
 (defun main ()
-  (with-unix-error-reporting ()
-    (let ((files nil))
-      (unless (option-parse-try
-               (do-options ()
-                 (nil (rest)
-                   (when (zerop (length rest))
-                     (option-parse-error "no files to read"))
-                   (setf files rest))))
-       (die-usage))
-      (dolist (f files)
-       (let ((*package* (make-package "ZONE.SCRATCH"
-                                      :use '(#:common-lisp #:net #:zone))))
-         (load f :verbose nil :print nil :if-does-not-exist :error)
-         (delete-package *package*)))
-      (zone-save opt-zones :format opt-format))))
+  (set-command-line-arguments)
+  (let ((files nil))
+    (flet ((run ()
+            (dolist (f files)
+              (let ((*package* (make-package "ZONE.SCRATCH"
+                                             :use '(#:common-lisp
+                                                    #:net #:zone))))
+                (load f :verbose nil :print nil :if-does-not-exist :error)
+                (delete-package *package*)))
+            (zone-save opt-zones :format opt-format)))
+      (with-unix-error-reporting ()
+       (unless (option-parse-try
+                 (do-options ()
+                   (nil (rest)
+                        (when (zerop (length rest))
+                          (option-parse-error "no files to read"))
+                        (setf files rest))))
+         (die-usage)))
+      (if opt-debug
+         (run)
+         (with-unix-error-reporting () (run))))))
 
 ;;;----- That's all, folks --------------------------------------------------