-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathproject-packages-sbcl.lisp
100 lines (86 loc) · 3.16 KB
/
project-packages-sbcl.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
;; project-packages-sbcl.lisp -- Package mapping for SBCL
;;
;; DM/RAL 10/22
;; -----------------------------------------------------------
(defpackage #:com.ral.project-packages
(:use #:common-lisp)
(:export
#:defproject
#:map-name
#:show-mappings
))
(in-package #:com.ral.project-packages)
(defvar *mappings* (make-hash-table))
(defvar *map-lock* (sb-thread:make-mutex))
(defvar *bypass-mapping* nil)
(defun normalize (name)
(cond ((stringp name)
(intern (string-upcase name) :keyword))
((symbolp name)
(normalize (symbol-name name)))
(t
(error "What!? (~S)" name))
))
(defun do-defproject (pairs)
(sb-thread:with-recursive-lock (*map-lock*)
(dolist (pair pairs)
(destructuring-bind (from-name to-name) pair
(let ((from-name (normalize from-name)))
(setf (gethash from-name *mappings*) to-name)
)))
))
(defmacro defproject (&rest pairs)
`(do-defproject ',pairs))
(defun map-name (name &optional froms)
(cond ((or *bypass-mapping*
(packagep name))
name)
(t
(let ((norm-name (normalize name))
to-name)
(when (find norm-name froms :test #'string=)
(error "Cyclic mappong ~A" norm-name))
(sb-thread:with-recursive-lock (*map-lock*)
(if (and ;; (char= #\= (char norm-name 0))
(setf to-name (gethash norm-name *mappings*)))
(map-name to-name (cons norm-name froms))
name))))
))
(defun package-mapper (next-fn name)
(declare (optimize speed))
(funcall next-fn (map-name name)))
(defun in-quicklisp-p (filename)
(find "quicklisp" (pathname-directory filename)
:test #'string=))
(defun loader (next-fn filename &rest args)
(let ((*bypass-mapping* (in-quicklisp-p filename)))
(apply next-fn filename args)))
(sb-ext:with-unlocked-packages (:cl)
(cl-advice:make-advisable 'cl:find-package
:arguments '(name)
:force-use-arguments t)
(cl-advice:make-advisable 'cl:in-package
:arguments '(name)
:force-use-arguments t)
(cl-advice:make-advisable 'cl:load
:arguments '(name &rest args)
:force-use-arguments t)
(cl-advice:make-advisable 'cl:compile-file
:arguments '(name &rest args)
:force-use-arguments t)
(cl-advice:add-advice :around 'cl:find-package #'package-mapper)
(cl-advice:add-advice :around 'cl:in-package #'package-mapper)
(cl-advice:add-advice :around 'cl:load #'loader)
(cl-advice:add-advice :around 'cl:compile-file #'loader))
;; ------------------------------------------------------
(defun show-mappings ()
(let (lst)
(sb-thread:with-recursive-lock (*map-lock*)
(with-hash-table-iterator (gen *mappings*)
(loop
(multiple-value-bind (more? key value) (gen)
(unless more? (return))
(push `(,key ,value) lst)))))
(with-standard-io-syntax
(pprint (sort lst #'string< :key #'car)))
(values)))