X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=incore.lsp;h=2847b54fb101dae94412b1c0504cbf18c54cd204;hb=c6d3a0b36a69445ab93993b92ec73b090ed8c156;hp=6ba256198cc8158007440ddc5490bb8eec7ea971;hpb=3dcbdf45070be29c4dec5217bcb141d8ee96ac47;p=rrq%2Fnewlisp%2Fpacknl.git diff --git a/incore.lsp b/incore.lsp index 6ba2561..2847b54 100644 --- a/incore.lsp +++ b/incore.lsp @@ -8,39 +8,65 @@ ;; ;; archives:archives is a hashmap for loadable files ;; core:core is the running binary file -;; archive:main is the name of the first on-core member -;; archive:incore is the byte position into core for the archive +;; +;; The "archive" context holds utility code. +;; archive:main is the name of the first in-core member. +;; archive:incore is the byte position into core for the archive. +;; +;; Use (archives member pathname) to register that the file "member" +;; should be looked up in the ar style archive of the given pathname. +;; +;; Use (archive pathname) to register all members of the nominated ar +;; style archive. +;; This is a hashmap of loaded files (new Tree 'archives) -(define core:core (read-file (main-args 0))) +;; A copy of the executable +(define core:core (read-file "/proc/self/exe")) (context 'archive) (setf main nil) -(constant 'AR "/usr/bin/ar") +(constant 'AR "/usr/bin/ar" 'TAR "/bin/tar" 'FILE "/usr/bin/file") + +(define (tar-able PATH) + (when (file? FILE) + (if (exec (format "%s -Z %s" FILE PATH)) + (find " tar archive" ($it 0))))) +;; Install indexes for all members of the given archive file (define (archive:archive PATH) ;;(write-line 2 (string (list 'archive PATH))) (map (fn (F) (archives F PATH) F) - (exec (format "%s t %s" AR PATH)))) + (if (directory? PATH) (directory PATH "^[^.]") + (ends-with PATH ".a") (exec (format "%s t %s" AR PATH)) + (tar-able PATH) (exec (format "%s tf %s" TAR PATH)) + '() + ))) -(define (get-ar PATH MEMBER) - ;;(write-line 2 (string (list 'get-ar PATH MEMBER))) +;; Read a member of an external archive +(define (get-stdout CMD) (let ((I (pipe)) (O (pipe)) (DATA "") (ALL "") (SUB (fn (I O) - (close (I 1)) (close (O 0)) (close 0) - (process (format "%s p %s %s" AR PATH MEMBER) (I 0) (O 1))))) + (map close (list (I 1) (O 0) 0)) + (process CMD (I 0) (O 1))))) (fork (SUB I O)) (close (O 1)) (close (I 0)) (close (I 1)) (while (> (or (read (O 0) DATA 1000000) 0)) (extend ALL DATA)) (close (I 0)) ALL)) +;; Read an archive member. The given PATH is either a string path for +;; an external archive file or the (position length) list for an +;; incore packaged member. (define (get PATH MEMBER) (if (list? PATH) ((PATH 0) (PATH 1) core) - (ends-with PATH ".a") (get-ar PATH MEMBER))) + (directory? PATH) (read-file (format "%s/%s" PATH MEMBER)) + (ends-with PATH ".a") (get-stdout (format "%s p %s %s" AR PATH MEMBER)) + (tar-able PATH) (get-stdout (format "%s xOf %s %s" TAR PATH MEMBER)) + )) ;; Discover and load an in-core archive by means of a marker row of 40 ;; "x", and then a series of pathname\nsize\nbytes[size] members. @@ -59,17 +85,17 @@ (constant 'load - (letex (LOAD load) + (letex ((LOAD load) (CTX '(if (1 (args)) (args 1)) MAIN)) (fn () (if (archives (args 0)) - (eval-string (archive:get $it (args 0)) MAIN) - (LOAD (args 0))))) + (eval-string (archive:get $it (args 0)) CTX) + (LOAD (args 0) CTX)))) 'read-file - (letex (READ-FILE read-file) + (letex ((READ-FILE read-file) (CTX '(if (1 (args)) (args 1)) MAIN)) (fn () - (if (archives (args 0)) (archive:get $it (args 0)) - (READ-FILE (args 0))))) + (if (archives (args 0)) (archive:get $it (args 0) CTX) + (READ-FILE (args 0))))) 'file? - (letex (FILE? file?) + (letex ((FILE? file?)) (fn () (if (archives (args 0)) true (FILE? (args 0))))) )