Re: [PATCH] Proposal: implement feature-dependent-op
Richard M Kreuter <[email protected]>
| Newsgroups | gmane.lisp.cclan.general |
|---|---|
| Message-ID | <[email protected]> |
Christophe Rhodes <[email protected]> writes: > Richard M Kreuter <[email protected]> writes: > >> * the feature testing done by :in-order-to ((... (feature ...))) >> doesn't support the composite feature expressions that read-time >> conditionals do. Is this omission intended? > > I'm not sure. I think I would support the inclusion of composite > expression support. The attached patch contains an implementation of a featurep, and uses it in traverse. >> * the in-order-to notation looks like it applies only to direct >> instances of the operation classes named in the defsystem form, and >> not to instances of subclasses (example below [*]). This seems like >> a bug; is it intended? > > That definitely looks wrong. A fix for this is also in the attached patch. >> * is there any other way to specify that the component-pathname of a >> module is the same as that of its parent other than the defsystem >> syntax :pathname "."? Does :pathname "." work the same way >> everywhere? > > For what it's worth, I believe the pedantically correct way of > indicating this is > :pathname #.(make-pathname :directory '(:relative)) > but I appreciate that this is a bit of a mouthful. Hrm. Would it objectionable to add a bit of syntax to defsystem for this case, e.g., ":pathname :parent"? (Not in the patch; just a suggestion.) As an additonal unimplemented suggestion, what would people think about making compile-op, load-source-op, and load-op all subclasses of a common class that denoted that the operation processes components as programs, rather than as mere files? For Lisp files, for example, this means that the operation might read, compile, load, or run the contents of the files; but merely copying, archiving, or updating the files from a VC system probably shouldn't be process-program-ops. This way, given inheritance of the in-order-to relation, the sorts of components that need feature conditionalization can be written like this: (:file "sbcl" :in-order-to ((process-program--op (feature :sbcl)))) rather than like this (:file "sbcl" :in-order-to ((compile-op (feature :sbcl)) (load-op (feature :sbcl)) (load-source-op (feature :sbcl)))) More importantly, third-party operations could be written as subclasses of process-program-op and so automagically be contingent on the same features as compile-op, load-op, and load-source-op. (At least one published third-party operation could take advantage of this, lint-op in Nikodemus Siivola's asdf-packaging-tools, which reads in source files with READ in order to check them.) Thanks, RmK ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ cclan-list mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/cclan-list
asdf.diff
(text/x-patch, 1.8 KB)
Index: asdf.lisp
===================================================================
RCS file: /cvsroot/cclan/asdf/asdf.lisp,v
retrieving revision 1.102
diff -u -r1.102 asdf.lisp
--- asdf.lisp 7 Nov 2006 10:27:13 -0000 1.102
+++ asdf.lisp 22 Jan 2007 23:37:32 -0000
@@ -560,8 +560,7 @@
(defgeneric component-depends-on (operation component))
(defmethod component-depends-on ((o operation) (c component))
- (cdr (assoc (class-name (class-of o))
- (slot-value c 'in-order-to))))
+ (cdr (assoc o (slot-value c 'in-order-to) :test #'typep)))
(defgeneric component-self-dependencies (operation component))
@@ -622,6 +621,22 @@
(> (apply #'min (mapcar #'file-write-date out-files))
(apply #'max (mapcar #'fwd-or-return-t in-files)))))))))
+(defun featurep (feature-expression)
+ (when feature-expression
+ (etypecase feature-expression
+ (symbol
+ (member feature-expression *features*))
+ (cons
+ (let ((bool (car feature-expression)))
+ (ecase bool
+ (:and
+ (every #'featurep (rest feature-expression)))
+ (:or
+ (some #'featurep (rest feature-expression)))
+ (:not
+ (not (featurep (cadr feature-expression))))))))))
+
+
;;; So you look at this code and think "why isn't it a bunch of
;;; methods". And the answer is, because standard method combination
;;; runs :before methods most->least-specific, which is back to front
@@ -645,9 +660,9 @@
(traverse op dep-c)))
(do-dep (op dep)
(cond ((eq op 'feature)
- (or (member (car dep) *features*)
+ (or (featurep dep)
(error 'missing-dependency :required-by c
- :requires (car dep) :version nil)))
+ :requires dep :version nil)))
(t
(dolist (d dep)
(cond ((consp d)