|
1 | 1 | #lang racket/base
|
2 | 2 | (require racket/contract/base
|
3 |
| - racket/list |
4 |
| - racket/path |
5 |
| - "modread.rkt") |
| 3 | + "private/modcode-noctc.rkt") |
6 | 4 |
|
7 |
| -(provide moddep-current-open-input-file |
8 |
| - exn:get-module-code |
9 |
| - exn:get-module-code? |
10 |
| - exn:get-module-code-path |
11 |
| - make-exn:get-module-code) |
| 5 | +(provide (except-out (all-from-out "private/modcode-noctc.rkt") |
| 6 | + get-module-code |
| 7 | + get-module-path |
| 8 | + get-metadata-path)) |
12 | 9 |
|
13 | 10 | (provide/contract
|
14 | 11 | [get-module-code
|
|
40 | 37 | (#:roots (listof (or/c path-string? 'same)))
|
41 | 38 | #:rest (listof (or/c path-string? 'same))
|
42 | 39 | path?)])
|
43 |
| - |
44 |
| -(define moddep-current-open-input-file |
45 |
| - (make-parameter open-input-file)) |
46 |
| - |
47 |
| -(define (resolve s) |
48 |
| - (if (complete-path? s) |
49 |
| - s |
50 |
| - (let ([d (current-load-relative-directory)]) |
51 |
| - (if d (path->complete-path s d) s)))) |
52 |
| - |
53 |
| -(define (date>=? a bm) |
54 |
| - (and a |
55 |
| - (let ([am (with-handlers ([exn:fail:filesystem? (lambda (x) #f)]) |
56 |
| - (file-or-directory-modify-seconds a))]) |
57 |
| - (and am (if bm (>= am bm) #t))))) |
58 |
| - |
59 |
| -(define (read-one orig-path path src? read-src-syntax) |
60 |
| - (define p ((moddep-current-open-input-file) path)) |
61 |
| - (when src? (port-count-lines! p)) |
62 |
| - (define (reader) |
63 |
| - (define-values (base name dir?) (split-path orig-path)) |
64 |
| - (define unchecked-v |
65 |
| - (with-module-reading-parameterization |
66 |
| - (lambda () |
67 |
| - ;; In case we're reading a .zo, we need to set |
68 |
| - ;; the load-relative directory for unmarshaling |
69 |
| - ;; path literals. |
70 |
| - (parameterize ([current-load-relative-directory |
71 |
| - (if (path? base) base (current-directory))]) |
72 |
| - (read-src-syntax path p))))) |
73 |
| - (when (eof-object? unchecked-v) |
74 |
| - (error 'read-one "empty file; expected a module declaration in: ~a" path)) |
75 |
| - (define sym |
76 |
| - (string->symbol |
77 |
| - (bytes->string/utf-8 (path->bytes (path-replace-extension name #"")) #\?))) |
78 |
| - (define checked-v (check-module-form unchecked-v sym path)) |
79 |
| - (unless (eof-object? (read p)) |
80 |
| - (error 'read-one |
81 |
| - "file has more than one expression; expected a module declaration only in: ~a" |
82 |
| - path)) |
83 |
| - (if (and (syntax? checked-v) (compiled-expression? (syntax-e checked-v))) |
84 |
| - (syntax-e checked-v) |
85 |
| - checked-v)) |
86 |
| - (define (closer) (close-input-port p)) |
87 |
| - (dynamic-wind void reader closer)) |
88 |
| - |
89 |
| -(define-struct (exn:get-module-code exn:fail) (path)) |
90 |
| - |
91 |
| -(define (reroot-path* base root) |
92 |
| - (cond |
93 |
| - [(eq? root 'same) base] |
94 |
| - [(relative-path? root) (build-path base root)] |
95 |
| - [else (reroot-path base root)])) |
96 |
| - |
97 |
| -;; : (or/c path-string? 'same) -> (or/c path? 'same) |
98 |
| -(define (path-string->path ps) |
99 |
| - (if (string? ps) (string->path ps) ps)) |
100 |
| - |
101 |
| -;; : (listof (or/c path-string? 'same)) -> (listof (or/c path? 'same)) |
102 |
| -(define (root-strs->roots root-strs) |
103 |
| - (map path-string->path root-strs)) |
104 |
| - |
105 |
| -(define (get-metadata-path |
106 |
| - #:roots [root-strs (current-compiled-file-roots)] |
107 |
| - base-str . arg-strs) |
108 |
| - (define base (path-string->path base-str)) |
109 |
| - (define roots (root-strs->roots root-strs)) |
110 |
| - (define args (root-strs->roots arg-strs)) |
111 |
| - (cond |
112 |
| - [(or (equal? roots '(same)) (null? roots)) |
113 |
| - (apply build-path base args)] |
114 |
| - [else |
115 |
| - (or (for/or ([root (in-list (if (null? (cdr roots)) null roots))]) |
116 |
| - (define p (apply build-path (reroot-path* base root) args)) |
117 |
| - (and (file-exists? p) p)) |
118 |
| - (apply build-path (reroot-path* base (car roots)) args))])) |
119 |
| - |
120 |
| -(define (default-compiled-sub-path) |
121 |
| - (let ([l (use-compiled-file-paths)]) |
122 |
| - (if (pair? l) |
123 |
| - (car l) |
124 |
| - "compiled"))) |
125 |
| - |
126 |
| -(define (get-module-path |
127 |
| - path0-str |
128 |
| - #:roots [root-strs (current-compiled-file-roots)] |
129 |
| - #:submodule? [submodule? #f] |
130 |
| - #:sub-path [sub-path/kw (default-compiled-sub-path)] |
131 |
| - [sub-path sub-path/kw] |
132 |
| - #:choose [choose (lambda (src zo so) #f)] |
133 |
| - #:rkt-try-ss? [rkt-try-ss? #t]) |
134 |
| - (define path0 (path-string->path path0-str)) |
135 |
| - (define roots (root-strs->roots root-strs)) |
136 |
| - (define resolved-path (resolve path0)) |
137 |
| - (define-values (path0-rel path0-file path0-dir?) (split-path path0)) |
138 |
| - (define-values (main-src-file alt-src-file) |
139 |
| - (if rkt-try-ss? |
140 |
| - (let* ([b (path->bytes path0-file)] |
141 |
| - [len (bytes-length b)]) |
142 |
| - (cond |
143 |
| - [(and (len . >= . 4) (bytes=? #".rkt" (subbytes b (- len 4)))) |
144 |
| - ;; .rkt => try .rkt then .ss |
145 |
| - (values path0-file |
146 |
| - (bytes->path (bytes-append (subbytes b 0 (- len 4)) |
147 |
| - #".ss")))] |
148 |
| - [else |
149 |
| - ;; No search path |
150 |
| - (values path0-file #f)])) |
151 |
| - (values path0-file #f))) |
152 |
| - (define main-src-path |
153 |
| - (if (eq? main-src-file path0-file) |
154 |
| - resolved-path |
155 |
| - (build-path path0-rel main-src-file))) |
156 |
| - (define alt-src-path |
157 |
| - (and alt-src-file |
158 |
| - (if (eq? alt-src-file path0-file) |
159 |
| - resolved-path |
160 |
| - (build-path path0-rel alt-src-file)))) |
161 |
| - (define path0-base (if (eq? path0-rel 'relative) 'same path0-rel)) |
162 |
| - (define main-src-date |
163 |
| - (file-or-directory-modify-seconds main-src-path #f (lambda () #f))) |
164 |
| - (define alt-src-date |
165 |
| - (and alt-src-path |
166 |
| - (not main-src-date) |
167 |
| - (file-or-directory-modify-seconds alt-src-path #f (lambda () #f)))) |
168 |
| - (define src-date (or main-src-date alt-src-date)) |
169 |
| - (define src-file (if alt-src-date alt-src-file main-src-file)) |
170 |
| - (define src-path (if alt-src-date alt-src-path main-src-path)) |
171 |
| - (define try-alt? (and alt-src-file (not alt-src-date) (not main-src-date))) |
172 |
| - (define (get-so file) |
173 |
| - (get-metadata-path #:roots roots |
174 |
| - path0-base |
175 |
| - sub-path |
176 |
| - "native" |
177 |
| - (system-library-subpath) |
178 |
| - (path-add-extension file (system-type 'so-suffix)))) |
179 |
| - (define zo |
180 |
| - (get-metadata-path #:roots roots |
181 |
| - path0-base |
182 |
| - sub-path |
183 |
| - (path-add-extension src-file #".zo"))) |
184 |
| - (define alt-zo |
185 |
| - (and try-alt? |
186 |
| - (get-metadata-path #:roots roots |
187 |
| - path0-base |
188 |
| - sub-path |
189 |
| - (path-add-extension alt-src-file #".zo")))) |
190 |
| - (define so (get-so src-file)) |
191 |
| - (define alt-so (and try-alt? (get-so alt-src-file))) |
192 |
| - (define prefer (choose src-path zo so)) |
193 |
| - (cond |
194 |
| - ;; Use .zo, if it's new enough |
195 |
| - [(or (eq? prefer 'zo) |
196 |
| - (and (not prefer) |
197 |
| - (pair? roots) |
198 |
| - (or (date>=? zo src-date) |
199 |
| - (and try-alt? |
200 |
| - (date>=? alt-zo src-date))))) |
201 |
| - (let ([zo (if (date>=? zo src-date) |
202 |
| - zo |
203 |
| - (if (and try-alt? (date>=? alt-zo src-date)) |
204 |
| - alt-zo |
205 |
| - zo))]) |
206 |
| - (values (simple-form-path zo) 'zo))] |
207 |
| - ;; Maybe there's an .so? Use it only if we don't prefer source |
208 |
| - ;; and only if there's no submodule path. |
209 |
| - [(and (not submodule?) |
210 |
| - (or (eq? prefer 'so) |
211 |
| - (and (not prefer) |
212 |
| - (pair? roots) |
213 |
| - (or (date>=? so src-date) |
214 |
| - (and try-alt? |
215 |
| - (date>=? alt-so src-date)))))) |
216 |
| - (let ([so (if (date>=? so src-date) |
217 |
| - so |
218 |
| - (if (and try-alt? (date>=? alt-so src-date)) |
219 |
| - alt-so |
220 |
| - so))]) |
221 |
| - (values (simple-form-path so) 'so))] |
222 |
| - ;; Use source if it exists |
223 |
| - [(or (eq? prefer 'src) src-date) |
224 |
| - (values (simple-form-path src-path) 'src)] |
225 |
| - ;; Report a not-there error |
226 |
| - [else (raise (make-exn:get-module-code |
227 |
| - (format "get-module-code: no such file: ~e" resolved-path) |
228 |
| - (current-continuation-marks) |
229 |
| - #f))])) |
230 |
| - |
231 |
| -(define (get-module-code |
232 |
| - path0-str |
233 |
| - #:roots [root-strs (current-compiled-file-roots)] |
234 |
| - #:submodule-path [submodule-path '()] |
235 |
| - #:sub-path [sub-path/kw (default-compiled-sub-path)] |
236 |
| - [sub-path sub-path/kw] |
237 |
| - #:compile [compile/kw compile] |
238 |
| - [compiler compile/kw] |
239 |
| - #:extension-handler [ext-handler/kw #f] |
240 |
| - [ext-handler ext-handler/kw] |
241 |
| - #:choose [choose (lambda (src zo so) #f)] |
242 |
| - #:notify [notify void] |
243 |
| - #:source-reader [read-src-syntax read-syntax] |
244 |
| - #:rkt-try-ss? [rkt-try-ss? #t]) |
245 |
| - (define path0 (path-string->path path0-str)) |
246 |
| - (define roots (root-strs->roots root-strs)) |
247 |
| - (define-values (path type) |
248 |
| - (get-module-path |
249 |
| - path0 |
250 |
| - #:roots roots |
251 |
| - #:submodule? (pair? submodule-path) |
252 |
| - #:sub-path sub-path |
253 |
| - #:choose choose |
254 |
| - #:rkt-try-ss? rkt-try-ss?)) |
255 |
| - (define (extract-submodule m [sm-path submodule-path]) |
256 |
| - (cond |
257 |
| - [(null? sm-path) m] |
258 |
| - [else |
259 |
| - (extract-submodule |
260 |
| - (or (for/or ([c (in-list (append (module-compiled-submodules m #t) |
261 |
| - (module-compiled-submodules m #f)))]) |
262 |
| - (and (eq? (last (module-compiled-name c)) (car sm-path)) |
263 |
| - c)) |
264 |
| - (raise |
265 |
| - (make-exn:get-module-code |
266 |
| - (format "get-module-code: cannot find submodule: ~e" sm-path) |
267 |
| - (current-continuation-marks) |
268 |
| - #f))) |
269 |
| - (cdr sm-path))])) |
270 |
| - (case type |
271 |
| - [(zo) |
272 |
| - (notify path) |
273 |
| - (extract-submodule (read-one path0 path #f read-syntax))] |
274 |
| - [(so) |
275 |
| - (if ext-handler |
276 |
| - (begin |
277 |
| - (notify path) |
278 |
| - (ext-handler path #f)) |
279 |
| - (raise (make-exn:get-module-code |
280 |
| - (format "get-module-code: cannot use extension file; ~e" path) |
281 |
| - (current-continuation-marks) |
282 |
| - path)))] |
283 |
| - [(src) |
284 |
| - (notify path) |
285 |
| - (define (compile-one) |
286 |
| - (define-values (path0-base path0-name path0-dir?) (split-path path0)) |
287 |
| - (parameterize ([current-load-relative-directory |
288 |
| - (if (path? path0-base) path0-base (current-directory))]) |
289 |
| - (compiler (read-one path0 path #t read-src-syntax)))) |
290 |
| - (if (null? submodule-path) |
291 |
| - ;; allow any result: |
292 |
| - (compile-one) |
293 |
| - ;; expect a compiled-module result: |
294 |
| - (extract-submodule (compile-one)))])) |
0 commit comments