diff --git a/adams.asd b/adams.asd
index 557350d..d6590f8 100644
--- a/adams.asd
+++ b/adams.asd
@@ -50,6 +50,7 @@
(:file "helpers")
(:file "host" :depends-on ("defs" "os" "resource-container"
"syntaxes"))
+ (:file "include")
(:file "operation" :depends-on ("defs" "host" "properties"))
(:file "os")
(:file "probe" :depends-on ("defs" "host" "properties"))
diff --git a/core/include.lisp b/core/include.lisp
new file mode 100644
index 0000000..0b1ae78
--- /dev/null
+++ b/core/include.lisp
@@ -0,0 +1,44 @@
+;;
+;; adams - system administrator written in Common Lisp
+;;
+;; Copyright 2020 Thomas de Grivel <thoxdg@gmail.com>
+;;
+;; Permission to use, copy, modify, and distribute this software for any
+;; purpose with or without fee is hereby granted, provided that the above
+;; copyright notice and this permission notice appear in all copies.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+;; WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+;; MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+;; ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+;; WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+;; ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+;; OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+;;
+
+(in-package :adams)
+
+(defun include/resolve-filename (spec)
+ (flet ((try (&rest parts)
+ (let ((path (str parts)))
+ (when (probe-file path)
+ (return-from include/resolve-filename path)))))
+ (try spec)
+ (try spec ".adams")))
+
+(defun include (&rest sources)
+ (let* ((head (cons 'list nil))
+ (tail head)
+ (eof (gensym "EOF")))
+ (dolist (source sources)
+ (let ((path (include/resolve-filename source)))
+ (with-open-file (in path
+ :element-type 'character
+ :external-format :utf-8)
+ (loop
+ (let ((form (read in nil eof)))
+ (when (eq form eof)
+ (return))
+ (setf (rest tail) (cons form nil)
+ tail (rest tail)))))))
+ head))
diff --git a/core/spec.lisp b/core/spec.lisp
index 4d063c4..891eef9 100644
--- a/core/spec.lisp
+++ b/core/spec.lisp
@@ -37,10 +37,12 @@
;; Parse specifications
(defmethod parse-next-specification ((res resource) spec)
- (let ((property (pop spec))
- (value (pop spec)))
- (setf (get-specified res property) value)
- spec))
+ (when (and (symbolp (first spec))
+ (consp (rest spec)))
+ (let ((property (pop spec))
+ (value (pop spec)))
+ (setf (get-specified res property) value)
+ spec)))
(defmethod parse-next-specification ((res resource-container) spec)
(cond ((typep (first spec) 'resource)
@@ -56,10 +58,14 @@
(loop
(when (endp spec)
(return))
- (let ((next-spec (parse-next-specification res spec)))
- (when (eq spec next-spec)
- (error "Invalid specification : ~S" spec))
- (setq spec next-spec)))
+ (if (consp (first spec))
+ (progn
+ (parse-specification res (first spec))
+ (setq spec (rest spec)))
+ (let ((next-spec (parse-next-specification res spec)))
+ (when (eq spec next-spec)
+ (error "Invalid specification : ~S" spec))
+ (setq spec next-spec))))
res)
#+nil
diff --git a/package.lisp b/package.lisp
index 05a307f..5c61e4a 100644
--- a/package.lisp
+++ b/package.lisp
@@ -151,6 +151,7 @@
;; OpenBSD
#:openbsd-pkg
;; helpers
+ #:include
#:read-file
))