#!/usr/bin/scsh -s !# (define targets-prereqs ; f : which file to scan ; i-dirs : the directories where to look for include files (lambda (f i-dirs) (let ; calling gcc-cmd returns ; all dependencies in one entire string ((raw-deps (lambda (file dirs) ; full command string (let ((gcc-cmd (lambda (my-file ds) ; build the include args for gcc e.g. ; ("-I." "-I.." "-I/usr/include") (let ((i-args (lambda (d) (let ((add-prefix (lambda (p s) (map string-append (circular-list p) s)))) (add-prefix "-I" d))))) (append (list "gcc" "-M") (i-args ds) (list my-file)))))) (run/string ,(gcc-cmd file dirs))))) ; cook-deps returns a list like ("target:" "filename" "otherfile" ...) (cook-deps (lambda (rdeps) (let ; merge all \ -separated lines ; into one entire line ((unbreak-lines (lambda (str) (regexp-substitute/global #f (rx (: (* white) #\\ #\newline (* white))) str 'pre " " 'post))) ; break a string into tokens ; "a space delimeted string" -> ; ("a" "space" "delimited" "string") (extract-f-l (lambda (s) (string-tokenize s char-set:graphic)))) (extract-f-l (unbreak-lines rdeps))))) ; splits a list of strings into a target and its prerequisites ; by searching for an element with a colon as the last character ; returns a pair list and needs the list of dependencies (t-p-pair (lambda (deps-l) (let ; deletes the last character colon... ((delete-colon (lambda (target) (regexp-substitute/global #f (rx (: #\: eos)) target 'pre 'post))) ; as list-index returns the element no ; starting at 0, last-target-element ; increases this index by 1 (last-target-element (lambda (str-l) ; tests if a target-candidate (tc) is a target ; a tc is a target if its last character is ; a colon... (let ((is-target? (lambda (tc) (regexp-search (rx (: any #\: eos)) tc)))) (+ 1 (list-index is-target? str-l)))))) (cond ((null? deps-l) #f) (else (cons ; this is a pair list -> the colon can be deleted (map delete-colon (take deps-l (last-target-element deps-l))) (list (drop deps-l (last-target-element deps-l)))))))))) (t-p-pair (cook-deps (raw-deps f i-dirs)))))) (define add-entry (lambda (k d a) (let ((tp (lambda (f i) (targets-prereqs f i)))) (alist-cons (car (tp k d)) (cdr (tp k d)) a)))) (define include-dirs (list "./" "/usr/include" "/usr/src/linux/include")) (define target-lookup-table (add-entry "./scanme.c" include-dirs '())) (define target-lookup-table (add-entry "./it.h" include-dirs target-lookup-table)) (display target-lookup-table) (newline)