diff --git a/lang/ninja/src/ninja.sld b/lang/ninja/src/ninja.sld index 8164fe7..4ccb6de 100644 --- a/lang/ninja/src/ninja.sld +++ b/lang/ninja/src/ninja.sld @@ -217,7 +217,7 @@ (try-resolve (build-rule-restat rule) #f) (try-resolve (build-rule-rspfile rule) #f) (try-resolve (build-rule-rspfile-content rule) #f))) - + (define (bytevector-prefix? bv in-bv index) (define bv-len (bytevector-length bv)) (define (inner-loop j) @@ -229,9 +229,9 @@ (if (> (+ index bv-len) (bytevector-length in-bv)) #f (inner-loop 0))) - + ;; Reads a full Ninja file, returning a record. - (define (read-ninja-file strval) + (define (read-ninja-file-inner strval into read-other-file) (define i 0) (define (eat-whitespace) (cond @@ -295,10 +295,11 @@ (define (read-token) (define start-i i) - (define post-space (or (bytestring-index strval (lambda (ch) (not (= ch #x20))) i) i)) + (define post-space-index (bytestring-index strval (lambda (ch) (not (= ch #x20))) i)) + (define post-space (or post-space-index i)) (define token (cond - ((>= i (bytevector-length strval)) + ((>= post-space (bytevector-length strval)) 'eof) ((bytevector-prefix? #u8(#x23) strval post-space) (let ((end-of-comment (or (bytestring-index strval (lambda (ch) (= ch #x0A)) post-space) (bytevector-length strval)))) @@ -339,7 +340,9 @@ ((string=? token "include") 'include) ((string=? token "subninja") 'subninja) (else token)))) - (else #f))) + ((and (not post-space-index) (= (bytevector-u8-ref strval i) #x20)) + 'eof) + (else (fprintf (current-error-port) "found token ~S here\n" (number->string (bytevector-u8-ref strval i) 16)) #f))) (unless (member token '(newline eof #f)) (eat-whitespace)) token) (define (expect-token expected) @@ -445,17 +448,22 @@ (let ((edge (read-build-edge file))) (set-build-file-build-edges! file (cons edge (build-file-build-edges file)))) (read-toplevel file)) ((default) - (do () ((expect-token 'newline)) (set-build-file-default-targets! file (cons (resolve-evalstring (read-eval-string-text #t) file #f #f #f) (build-file-default-targets file))))) - ((subninja include) (error "todo: includes")) + (do () ((expect-token 'newline)) (set-build-file-default-targets! file (cons (resolve-evalstring (read-eval-string-text #t) file #f #f #f) (build-file-default-targets file)))) + (read-toplevel file)) + ((include) (read-ninja-file-inner (read-other-file (resolve-evalstring (read-eval-string-text #t) file #f #f #f)) file read-other-file) + (read-toplevel file)) + ((subninja) (error "todo: subninja")) ((pool) (read-pool) (read-toplevel file)) ((newline) (read-toplevel file)) (else - (unless (string? token) (error "unexpected" (list token i))) + (unless (string? token) (error "unexpected" (list token i (bytevector-length strval)))) (unless (expect-token 'equals) (error "expected =, found" (read-token))) (let* ((value (read-eval-string-text #f)) (resolved (resolve-evalstring value file #f #f #f))) (set-build-file-global-variables! file (mapping-set! (build-file-global-variables file) token resolved))) (read-toplevel file))) file) - (define out-file (read-toplevel (make-build-file (mapping (make-default-comparator)) '() (mapping (make-default-comparator)) '() (mapping (make-default-comparator))))) + (read-toplevel into)) + (define (read-ninja-file strval read-other-file) + (define out-file (read-ninja-file-inner strval (make-build-file (mapping (make-default-comparator)) '() (mapping (make-default-comparator)) '() (mapping (make-default-comparator))) read-other-file)) (for-each (lambda (f) (unless (string=? (build-edge-rule f) "phony") (set-build-edge-resolved! f (build-rule-resolve (mapping-ref (build-file-rules out-file) (build-edge-rule f)) f out-file)))) (build-file-build-edges out-file)) out-file))) diff --git a/lang/ninja/src/nixpkgs.sld b/lang/ninja/src/nixpkgs.sld index c8b29d0..f0ce4e6 100644 --- a/lang/ninja/src/nixpkgs.sld +++ b/lang/ninja/src/nixpkgs.sld @@ -101,10 +101,13 @@ (set-ninja-build-config-root-dir! conf configured-vfs) + (define (read-file-at-path path) + (set! path (string-append "build/" path)) + (define last-slash (string-contains-right path "/")) + (call-with-port (store-path-open (vfs-file-ref configured-vfs (string-copy path 0 last-slash) (string-copy path (+ 1 last-slash)))) + (lambda (p) (read-bytevector (* 20 1024 1024) p)))) (define ninja-file - (read-ninja-file - (call-with-port (store-path-open (vfs-file-ref configured-vfs "build" "build.ninja")) - (lambda (p) (read-bytevector (* 20 1024 1024) p))))) + (read-ninja-file (read-file-at-path "build.ninja") read-file-at-path)) ; Process the build.ninja file. (define-values (edge-ref defaults) (process-ninja-file ninja-file conf "build"))