changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > core / annotate lisp/std/file.lisp

changeset 698: 96958d3eb5b0
parent: 5f81d888c31f
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
279
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 ;;; std/file.lisp --- Standard File Library
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 ;;
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 ;;; Code:
291
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
6
 (in-package :std/file)
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
7
 
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
8
 ;;; Sexp utils
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
9
 ;; (reexport-from :uiop :include '(read-file-form read-file-forms slurp-stream-forms))
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
10
 
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
11
 (defun tmpfile (size)
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
12
   "Create an anonymous temporary file of the given size. Returns a file descriptor."
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
13
   (let (done fd pathname)
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
14
     (unwind-protect
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
15
          (progn
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
16
            (setf (values fd pathname) (sb-posix:mkstemp "/dev/shm/tmp.XXXXXXXX"))
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
17
            (sb-posix:unlink pathname)
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
18
            (sb-posix:ftruncate fd size)
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
19
            (setf done t))
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
20
       (when (and fd (not done)) (sb-posix:close fd)))
a0dfde3cb3c4 begin :STD refactor
Richard Westhaver <ellis@rwest.io>
parents: 290
diff changeset
21
     fd))
279
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
22
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
23
 (declaim (inline octet-vector=/unsafe))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
24
 (defun octet-vector=/unsafe (v1 v2 start1 end1 start2 end2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
25
   (declare (optimize (speed 3)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
26
                      (safety 0)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
27
                      (debug 0)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
28
                      (compilation-speed 0))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
29
            (type octet-vector v1 v2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
30
            (type array-index start1 start2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
31
            (type array-length end1 end2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
32
   (and (= (- end1 start1)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
33
           (- end2 start2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
34
        (loop for i from start1 below end1
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
35
              for j from start2 below end2
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
36
              always (eql (aref v1 i) (aref v2 j)))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
37
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
38
 (defun octet-vector= (v1 v2 &key (start1 0) end1
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
39
                                  (start2 0) end2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
40
   "Like `string=' for octet vectors."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
41
   (declare (octet-vector v1 v2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
42
            (array-index start1 start2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
43
            ((or array-length null) end1 end2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
44
            (optimize speed))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
45
   (let* ((len1 (length v1))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
46
          (len2 (length v2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
47
          (end1 (or end1 len1))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
48
          (end2 (or end2 len2)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
49
     (assert (<= start1 end1 len1))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
50
     (assert (<= start2 end2 len2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
51
     (octet-vector=/unsafe v1 v2 start1 end1 start2 end2)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
52
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
53
 (defun file-size-in-octets (file)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
54
   (multiple-value-bind (path namestring)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
55
       (etypecase file
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
56
         (string (values (pathname file)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
57
                         file))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
58
         (pathname (values file
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
59
                           (sb-ext:native-namestring file))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
60
     (declare (ignorable path namestring))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
61
     (sb-posix:stat-size (sb-posix:stat path))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
62
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
63
 (define-constant si-prefixes
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
64
   '((-30 "quecto" "q")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
65
     (-27 "ronto"  "r")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
66
     (-24 "yocto"  "y")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
67
     (-21 "zepto"  "z")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
68
     (-18 "atto"   "a")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
69
     (-15 "femto"  "f")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
70
     (-12 "pico"   "p")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
71
     ( -9 "nano"   "n")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
72
     ( -6 "micro"  "μ")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
73
     ( -3 "milli"  "m")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
74
     ( -2 "centi"  "c")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
75
     ( -1 "deci"   "d")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
76
     (  0 ""       "" )
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
77
     (  1 "deca"   "da")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
78
     (  2 "hecto"  "h")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
79
     (  3 "kilo"   "k")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
80
     (  6 "mega"   "M")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
81
     (  9 "giga"   "G")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
82
     ( 12 "tera"   "T")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
83
     ( 15 "peta"   "P")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
84
     ( 18 "exa"    "E")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
85
     ( 21 "zetta"  "Z")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
86
     ( 24 "yotta"  "Y")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
87
     ( 27 "ronna"  "R")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
88
     ( 30 "quetta" "Q"))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
89
   :test #'equalp
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
90
   :documentation "List as SI prefixes: power of ten, long form, short form.")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
91
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
92
 (define-constant si-prefixes-base-1000
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
93
   (loop for (pow long short) in si-prefixes
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
94
         unless (and (not (zerop pow))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
95
                     (< (abs pow) 3))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
96
           collect (list (truncate pow 3) long short))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
97
   :test #'equalp
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
98
   :documentation "The SI prefixes as powers of 1000, with centi, deci, deca and hecto omitted.")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
99
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
100
 (define-constant iec-prefixes
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
101
   '(( 0 ""     "")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
102
     (10 "kibi" "Ki")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
103
     (20 "mebi" "Mi")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
104
     (30 "gibi" "Gi")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
105
     (40 "tebi" "Ti")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
106
     (50 "pebi" "Pi")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
107
     (60 "exbi" "Ei"))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
108
   :test #'equalp
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
109
   :documentation "The IEC binary prefixes, as powers of 2.")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
110
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
111
 (eval-always
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
112
   (defun single (seq)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
113
     "Is SEQ a sequence of one element?"
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
114
     (= (length seq) 1)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
115
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
116
 (defmacro si-prefix-rec (n base prefixes)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
117
   (cond ((null prefixes) (error "No prefixes!"))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
118
         ((single prefixes)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
119
          (destructuring-bind ((power long short)) prefixes
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
120
            `(values ,long ,short ,(expt base power))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
121
         (t
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
122
          ;; good enough
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
123
          (let* ((halfway (ceiling (length prefixes) 2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
124
                 (lo (subseq prefixes 0 halfway))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
125
                 (hi (subseq prefixes halfway))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
126
                 (split (* (expt base (caar hi)))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
127
              `(if (< ,n ,split)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
128
                   (si-prefix-rec ,n ,base ,lo)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
129
                   (si-prefix-rec ,n ,base ,hi))))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
130
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
131
 (defun si-prefix (n &key (base 1000))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
132
   "Given a number, return the prefix of the nearest SI unit.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
133
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
134
 Three values are returned: the long form, the short form, and the
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
135
 multiplying factor.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
136
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
137
     (si-prefix 1001) => \"kilo\", \"k\", 1000d0
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
138
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
139
 BASE can be 1000, 10, 1024, or 2. 1000 is the default, and prefixes
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
140
 start at kilo and milli. Base 10 is mostly the same, except the
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
141
 prefixes centi, deci, deca and hecto are also used. Base 1024 uses the
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
142
 same prefixes as 1000, but with 1024 as the base, as in vulgar file
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
143
 sizes. Base 2 uses the IEC binary prefixes."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
144
   (if (zerop n) (values "" "" 1d0)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
145
       (let ((n (abs (coerce n 'double-float))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
146
         (ecase base
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
147
           (2 (si-prefix-rec n 2d0 #.iec-prefixes))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
148
           (10 (si-prefix-rec n 10d0 #.si-prefixes))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
149
           (1000 (si-prefix-rec n 1000d0 #.si-prefixes-base-1000))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
150
           (1024 (si-prefix-rec n 1024d0 #.si-prefixes-base-1000))))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
151
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
152
 (defun human-size-formatter (size &key (flavor :si)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
153
                                        (space (eql flavor :si)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
154
   "Auxiliary function for formatting quantities human-readably.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
155
 Returns two values: a format control and a list of arguments.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
156
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
157
 This can be used to integrate the human-readable printing of
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
158
 quantities into larger format control strings using the recursive
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
159
 processing format directive (~?):
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
160
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
161
     (multiple-value-bind (control args)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
162
         (human-size-formatter size)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
163
       (format t \"~?\" control args))"
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
164
   (let ((size (coerce size 'double-float))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
165
         ;; Avoid printing exponent markers.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
166
         (*read-default-float-format* 'double-float)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
167
         (base (ecase flavor
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
168
                 (:file 1024)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
169
                 (:si   1000)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
170
                 (:iec  2))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
171
     (multiple-value-bind (long short factor)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
172
         (si-prefix size :base base)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
173
       (declare (ignore long))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
174
       (let* ((size (/ size factor))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
175
              (int (round size))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
176
              (size
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
177
                (if (> (abs (- size int))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
178
                       0.05d0)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
179
                    size
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
180
                    int)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
181
         (values (formatter "~:[~d~;~,1f~]~:[~; ~]~a")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
182
                 (list (floatp size) size space short))))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
183
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
184
 (defun format-human-size (stream size
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
185
                           &key (flavor :si)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
186
                                (space (eql flavor :si)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
187
   "Write SIZE to STREAM, in human-readable form.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
188
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
189
 STREAM is interpreted as by `format'.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
190
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
191
 If FLAVOR is `:si' (the default) the base is 1000 and SI prefixes are used.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
192
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
193
 If FLAVOR is `:file', the base is 1024 and SI prefixes are used.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
194
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
195
 If FLAVOR is `:iec', the base is 1024 bytes and IEC prefixes (Ki, Mi,
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
196
 etc.) are used.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
197
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
198
 If SPACE is non-nil, include a space between the number and the
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
199
 prefix. (Defaults to T if FLAVOR is `:si'.)"
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
200
   (if (zerop size)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
201
       (format stream "0")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
202
       (multiple-value-bind (formatter args)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
203
           (human-size-formatter size :flavor flavor :space space)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
204
         (format stream "~?" formatter args))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
205
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
206
 (defun format-file-size-human-readable (stream file-size
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
207
                                         &key flavor
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
208
                                              (space (eql flavor :si))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
209
                                              (suffix (if (eql flavor :iec) "B" "")))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
210
   "Write FILE-SIZE, a file size in bytes, to STREAM, in human-readable form.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
211
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
212
 STREAM is interpreted as by `format'.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
213
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
214
 If FLAVOR is nil, kilobytes are 1024 bytes and SI prefixes are used.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
215
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
216
 If FLAVOR is `:si', kilobytes are 1000 bytes and SI prefixes are used.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
217
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
218
 If FLAVOR is `:iec', kilobytes are 1024 bytes and IEC prefixes (Ki,
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
219
 Mi, etc.) are used.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
220
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
221
 If SPACE is non-nil, include a space between the number and the
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
222
 prefix. (Defaults to T if FLAVOR is `:si'.)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
223
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
224
 SUFFIX is the suffix to use; defaults to B if FLAVOR is `:iec',
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
225
 otherwise empty."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
226
   (check-type file-size (integer 0 *))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
227
   (if (zerop file-size)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
228
       (format stream "0")
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
229
       (let ((flavor (if (null flavor) :file flavor)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
230
         (multiple-value-bind (formatter args)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
231
             (human-size-formatter file-size :flavor flavor :space space)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
232
           (format stream "~?~a" formatter args suffix)))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
233
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
234
 (defun file-size-human-readable (file &key flavor space suffix stream)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
235
   "Format the size of FILE (in octets) using `format-file-size-human-readable'.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
236
 The size of file is found by `trivial-file-size:file-size-in-octets'.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
237
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
238
 Inspired by the function of the same name in Emacs."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
239
   (let ((file-size (file-size-in-octets file)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
240
     (format-file-size-human-readable
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
241
      stream
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
242
      file-size
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
243
      :flavor flavor
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
244
      :suffix suffix
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
245
      :space space)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
246
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
247
 (defmacro with-open-files ((&rest args) &body body)
393
6b87df03cdaf init cli/tools/cc.lisp for grovel experiments, add zstd tests
Richard Westhaver <ellis@rwest.io>
parents: 351
diff changeset
248
   "A simple macro to open one or more files providing the streams for the
6b87df03cdaf init cli/tools/cc.lisp for grovel experiments, add zstd tests
Richard Westhaver <ellis@rwest.io>
parents: 351
diff changeset
249
 BODY. The ARGS is a list of `(stream filespec options*)` as supplied to
6b87df03cdaf init cli/tools/cc.lisp for grovel experiments, add zstd tests
Richard Westhaver <ellis@rwest.io>
parents: 351
diff changeset
250
 WITH-OPEN-FILE."
279
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
251
   (case (length args)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
252
     ((0)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
253
      `(progn ,@body))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
254
     ((1)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
255
      `(with-open-file ,(first args) ,@body))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
256
     (t `(with-open-file ,(first args)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
257
           (with-open-files
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
258
               ,(rest args) ,@body)))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
259
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
260
 (defmacro with-open-file* ((stream filespec &key direction element-type
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
261
                                    if-exists if-does-not-exist external-format)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
262
                            &body body)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
263
   "Just like WITH-OPEN-FILE, but NIL values in the keyword arguments
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
264
 mean to use the default value specified for OPEN."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
265
   (once-only (direction element-type if-exists if-does-not-exist external-format)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
266
     `(with-open-stream
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
267
          (,stream (apply #'open ,filespec
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
268
                          (append
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
269
                           (when ,direction
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
270
                             (list :direction ,direction))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
271
                           (list :element-type (or ,element-type
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
272
                                                   +default-element-type+))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
273
                           (when ,if-exists
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
274
                             (list :if-exists ,if-exists))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
275
                           (when ,if-does-not-exist
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
276
                             (list :if-does-not-exist ,if-does-not-exist))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
277
                           (when ,external-format
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
278
                             (list :external-format ,external-format)))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
279
        ,@body)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
280
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
281
 (defmacro with-input-from-file ((stream-name file-name &rest args
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
282
                                              &key (direction nil direction-p)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
283
                                              &allow-other-keys)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
284
                                 &body body)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
285
   "Evaluate BODY with STREAM-NAME to an input stream on the file
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
286
 FILE-NAME. ARGS is sent as is to the call to OPEN except EXTERNAL-FORMAT,
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
287
 which is only sent to WITH-OPEN-FILE when it's not NIL."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
288
   (declare (ignore direction))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
289
   (when direction-p
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
290
     (error "Can't specify :DIRECTION for WITH-INPUT-FROM-FILE."))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
291
   `(with-open-file* (,stream-name ,file-name :direction :input ,@args)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
292
      ,@body))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
293
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
294
 (defmacro with-output-to-file ((stream-name file-name &rest args
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
295
                                             &key (direction nil direction-p)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
296
                                             &allow-other-keys)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
297
                                &body body)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
298
   "Evaluate BODY with STREAM-NAME to an output stream on the file
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
299
 FILE-NAME. ARGS is sent as is to the call to OPEN except EXTERNAL-FORMAT,
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
300
 which is only sent to WITH-OPEN-FILE when it's not NIL."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
301
   (declare (ignore direction))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
302
   (when direction-p
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
303
     (error "Can't specify :DIRECTION for WITH-OUTPUT-TO-FILE."))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
304
   `(with-open-file* (,stream-name ,file-name :direction :output ,@args)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
305
      ,@body))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
306
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
307
 (defun write-stream-into-file (stream pathname &key (if-exists :error) if-does-not-exist)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
308
   "Read STREAM and write the contents into PATHNAME.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
309
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
310
 STREAM will be closed afterwards, so wrap it with
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
311
 `make-concatenated-stream' if you want it left open."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
312
   (check-type pathname pathname)
549
32bd859533b3 fetch fixes
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
313
   (with-output-to-file (out pathname
32bd859533b3 fetch fixes
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
314
                             :element-type (stream-element-type stream)
32bd859533b3 fetch fixes
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
315
                             :if-exists if-exists
32bd859533b3 fetch fixes
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
316
                             :if-does-not-exist if-does-not-exist)
32bd859533b3 fetch fixes
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
317
     (copy-stream stream out))
32bd859533b3 fetch fixes
Richard Westhaver <ellis@rwest.io>
parents: 435
diff changeset
318
 pathname)
279
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
319
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
320
 (defun write-file-into-stream (pathname output &key (if-does-not-exist :error)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
321
                                                     (external-format :default))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
322
   "Write the contents of FILE into STREAM."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
323
   (check-type pathname pathname)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
324
   (with-input-from-file (input pathname
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
325
                                :element-type (stream-element-type output)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
326
                                :if-does-not-exist if-does-not-exist
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
327
                                :external-format external-format)
435
849bbe48e32d added dat/mime, removed sans-io
Richard Westhaver <ellis@rwest.io>
parents: 393
diff changeset
328
     (copy-stream input output :end (file-size-in-octets pathname))))
279
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
329
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
330
 (defun file= (file1 file2 &key (buffer-size 4096))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
331
   "Compare FILE1 and FILE2 octet by octet, \(possibly) using buffers
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
332
 of BUFFER-SIZE."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
333
   (declare (ignorable buffer-size))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
334
   (let ((file1 (truename file1))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
335
         (file2 (truename file2)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
336
     (or (equal file1 file2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
337
         (and (= (file-size-in-octets file1)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
338
                 (file-size-in-octets file2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
339
              #+ccl (file=/mmap file1 file2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
340
              #-ccl (file=/loop file1 file2 :buffer-size buffer-size)))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
341
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
342
 (defun file=/loop (file1 file2 &key (buffer-size 4096))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
343
   "Compare two files by looping over their contents using a buffer."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
344
   (declare
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
345
    (type pathname file1 file2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
346
    (type array-length buffer-size)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
347
    (optimize (safety 1) (debug 0) (compilation-speed 0)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
348
   (flet ((make-buffer ()
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
349
            (make-array buffer-size
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
350
                        :element-type 'octet
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
351
                        :initial-element 0)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
352
     (declare (inline make-buffer))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
353
     (with-open-files ((file1 file1 :element-type 'octet :direction :input)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
354
                       (file2 file2 :element-type 'octet :direction :input))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
355
       (and (= (file-length file1)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
356
               (file-length file2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
357
            (locally (declare (optimize speed))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
358
              (loop with buffer1 = (make-buffer)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
359
                    with buffer2 = (make-buffer)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
360
                    for end1 = (read-sequence buffer1 file1)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
361
                    for end2 = (read-sequence buffer2 file2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
362
                    until (or (zerop end1) (zerop end2))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
363
                    always (and (= end1 end2)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
364
                                (octet-vector= buffer1 buffer2
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
365
                                               :end1 end1
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
366
                                               :end2 end2))))))))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
367
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
368
 (defun file-size (file &key (element-type '(unsigned-byte 8)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
369
   "The size of FILE, in units of ELEMENT-TYPE (defaults to bytes).
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
370
 
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
371
 The size is computed by opening the file and getting the length of the
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
372
 resulting stream.
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
373
 
351
770f2d03efd8 homer push/pull
Richard Westhaver <ellis@rwest.io>
parents: 342
diff changeset
374
 If all you want is to read the file's size in octets from its metadata,
770f2d03efd8 homer push/pull
Richard Westhaver <ellis@rwest.io>
parents: 342
diff changeset
375
 consider FILE-SIZE-IN-OCTETS instead."
279
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
376
   (check-type file (or string pathname))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
377
   (with-input-from-file (in file :element-type element-type)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
378
     (file-length in)))
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
379
 
289
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
380
 (defun file-timestamp ()
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
381
   "Returns current timestamp as a string suitable as the name of a timestamped-file."
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
382
   (multiple-value-bind (sec min hr day mon yr)
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
383
                        (get-decoded-time)
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
384
     (format nil "~4d~2,'0d~2,'0d_~2,'0d~2,'0d~2,'0d" yr mon day hr min sec)))
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
385
 
279
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
386
 (defun file-date ()
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
387
   "Returns current date as a string suitable as the name of a timestamped-file."
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
388
   (multiple-value-bind (sec min hr day mon yr)
efc3e9ec02bf random tune-ups, added mpd and net/util.lisp
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
389
                        (get-decoded-time)
289
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
390
     (declare (ignore sec min hr))
c4682fedd73d added krypt lib, will probably add homer too
Richard Westhaver <ellis@rwest.io>
parents: 279
diff changeset
391
     (format nil "~4d~2,'0d~2,'0d" yr mon day)))
290
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
392
 
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
393
 ;; see https://www.n16f.net/blog/counting-lines-with-common-lisp/
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
394
 
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
395
 (defun directory-path-p (path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
396
   "Return T if PATH is a directory or NIL else."
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
397
   (declare (type (or pathname string) path))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
398
   (and (not (pathname-name path))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
399
        (not (pathname-type path))))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
400
 
342
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
401
 (defvar *hidden-paths* (list ".hg" ".git"))
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
402
 
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
403
 (defun hidden-path-p (path &optional strict)
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
404
   "Return T if PATH is strictly a hidden file or directory or NIL else."
290
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
405
   (declare (type pathname path))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
406
   (let ((name (if (directory-path-p path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
407
                   (car (last (pathname-directory path)))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
408
                   (file-namestring path))))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
409
     (and (plusp (length name))
342
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
410
          (if strict
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
411
              (eq (char name 0) #\.)
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
412
              (member name *hidden-paths* :test 'equal)))))
290
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
413
 
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
414
 (defun directory-path (path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
415
   "If PATH is a directory pathname, return it as it is. If it is a file
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
416
 pathname or a string, transform it into a directory pathname."
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
417
   (declare (type (or pathname string) path))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
418
   (if (directory-path-p path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
419
       path
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
420
       (make-pathname :directory (append (or (pathname-directory path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
421
                                             (list :relative))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
422
                                         (list (file-namestring path)))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
423
                      :name nil :type nil :defaults path)))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
424
 
342
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
425
 (defun find-files (path &optional (hide *hidden-paths*))
290
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
426
   "Return a list of all files contained in the directory at PATH or any of its
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
427
 subdirectories."
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
428
   (declare (type (or pathname string) path))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
429
   (flet ((list-directory (path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
430
            (directory
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
431
             (make-pathname :defaults (directory-path path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
432
                            :type :wild :name :wild))))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
433
     (let ((paths nil)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
434
           (children (list-directory (directory-path path))))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
435
       (dolist (child children paths)
342
254cca648492 homer fixups
Richard Westhaver <ellis@rwest.io>
parents: 291
diff changeset
436
         (unless (and hide (hidden-path-p child (eq t hide)))
290
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
437
           (if (directory-path-p child)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
438
               (setf paths (append paths (find-files child)))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
439
               (push child paths)))))))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
440
 
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
441
 (defun count-file-lines (path)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
442
   "Count the number of non-empty lines in the file at PATH. A line is empty if
693
5f81d888c31f sndfile ffi
Richard Westhaver <ellis@rwest.io>
parents: 549
diff changeset
443
 it only contains spaces or tab characters."
290
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
444
   (declare (type pathname path))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
445
   (with-open-file (stream path :element-type '(unsigned-byte 8))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
446
     (do ((nb-lines 0)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
447
          (blank-line t))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
448
         (nil)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
449
       (let ((octet (read-byte stream nil)))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
450
         (cond
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
451
           ((or (null octet) (eq octet #.(char-code #\Newline)))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
452
            (unless blank-line
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
453
              (incf nb-lines))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
454
            (when (null octet)
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
455
              (return-from count-file-lines nb-lines))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
456
            (setf blank-line t))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
457
           ((and (/= octet #.(char-code #\Space))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
458
                 (/= octet #.(char-code #\Tab)))
14b0ee8d09c1 threadworks
Richard Westhaver <ellis@rwest.io>
parents: 289
diff changeset
459
            (setf blank-line nil)))))))