examples: a small c program to be build through makefile-c.scm
to-rule-set: rule-candidates -> dfs -> '(#{:rule} ...) -> rule-set dfs: depth first topological sort with automatic leaf insertion out-of-date: replaced by templates.scm rule-trans-set: replaced by to-rule-set
This commit is contained in:
parent
5b462916b1
commit
a8dd2ab60b
|
@ -0,0 +1,59 @@
|
|||
MAKEFILE:
|
||||
=========
|
||||
|
||||
<makefile> ::= '(' + "makefile" + <makerule-clause>* + ')'
|
||||
|
||||
<makerule-clause> ::= <rule-clause>
|
||||
| <md5-clause>
|
||||
| <always-clause>
|
||||
| <once-clause>
|
||||
|
||||
<rule-clause> ::= '(' + <rule-clause-identifier>
|
||||
+ <target-spec>
|
||||
+ <prereq-spec>
|
||||
+ <action-spec> + ')'
|
||||
|
||||
<md5-clause> ::= '(' + <md5-clause-identifier>
|
||||
+ <target-spec>
|
||||
+ <prereq-spec>
|
||||
+ <action-spec> + ')'
|
||||
|
||||
<always-clause> ::= '(' + <always-clause-identifier>
|
||||
+ <target-spec>
|
||||
+ <prereq-spec>
|
||||
+ <action-spec> + ')'
|
||||
|
||||
<once-clause> ::= '(' + <once-clause-identifier>
|
||||
+ <target-spec>
|
||||
+ <prereq-spec>
|
||||
+ <action-spec> + ')'
|
||||
|
||||
<rule-clause-identifier> ::= "rule"
|
||||
| "makefile-rule"
|
||||
| "is-out-of-date?"
|
||||
|
||||
<md5-clause-identifier> ::= "md5"
|
||||
| "rule-md5"
|
||||
| "fp-changed?"
|
||||
|
||||
<always-clause-identifier> ::= "always"
|
||||
| "rule-always"
|
||||
| "phony"
|
||||
| "is-out-of-date!"
|
||||
|
||||
<once-clause-identifier> ::= "once"
|
||||
| "rule-once"
|
||||
|
||||
<target-spec> ::= <target> | <target-list>
|
||||
<target> ::= <filename>
|
||||
<target-list> ::= '(' + <filename>+ + ')'
|
||||
|
||||
<prereq-spec> ::= <prereq> | <prereq-list>
|
||||
<prereq> ::= <filename>
|
||||
<prereq-list> ::= '(' + <filename>* + ')'
|
||||
|
||||
<action-spec> ::= <action> | <action-list>
|
||||
<action> ::= '(' + <thunk>* + ')'
|
||||
<action-list> ::= '(' + <action>+ + ')'
|
||||
|
||||
<filename> ::= '"' + {<dir-separator> + { 'a'-'z''A'-'Z''0'-'9' ... }+ }+ + '"'
|
230
dfs.scm
230
dfs.scm
|
@ -1,100 +1,172 @@
|
|||
(define time 0)
|
||||
|
||||
(define-enumerated-type color :color
|
||||
is-color?
|
||||
the-color
|
||||
the-colors
|
||||
color-name
|
||||
color-index
|
||||
(white grey black))
|
||||
|
||||
;;;
|
||||
;;; DFS:
|
||||
;;; ====
|
||||
;;;
|
||||
;;; (make-dfs node-name adjacencies ignored-data) ---> #{:dfs}
|
||||
;;;
|
||||
;;; node-name : "this is a node name"
|
||||
;;; adjacencies : (list "another node name" "no node name")
|
||||
;;; ignored-data : "anything you need in each node, eg. a long list..."
|
||||
;;;
|
||||
;;; (dfs->list node) ---> '(node-name adjacencies ignored-data)
|
||||
;;;
|
||||
;;; node : #{:dfs}
|
||||
;;;
|
||||
;;; (dfs-name node) ---> node-name
|
||||
;;; (dfs-adjacencies node) ---> adjacencies
|
||||
;;; (dfs-color node) ---> #{:color}
|
||||
;;; (dfs-ftime node) ---> finishing-time
|
||||
;;; (dfs-ignored node) ---> ignored-data
|
||||
;;;
|
||||
(define-record-type :dfs
|
||||
(really-make-dfs node adjacencies color predec dtime ftime ignored-data)
|
||||
(really-make-dfs name adjacencies color ftime ignored)
|
||||
is-dfs?
|
||||
(node dfs-node)
|
||||
(name dfs-name)
|
||||
(adjacencies dfs-adjacencies)
|
||||
;; color (white by default)
|
||||
(color dfs-color)
|
||||
;; predecessor (is #f by default)
|
||||
(predec dfs-predec)
|
||||
;; discovery-time
|
||||
(dtime dfs-dtime)
|
||||
;; finishing-time
|
||||
(ftime dfs-ftime)
|
||||
;; thie is for all node specific information
|
||||
;; and is ignore by the dfs algorithm
|
||||
;; put in there what you like
|
||||
(ignored-data dfs-ignored-data))
|
||||
(ignored dfs-ignored))
|
||||
|
||||
(define (make-dfs node adjacencies ignored-data)
|
||||
(really-make-dfs node adjacencies (color white) 0 0 #f ignored-data))
|
||||
(define (make-dfs node-name adjacencies ignored-data)
|
||||
(really-make-dfs node-name adjacencies (color white) 0 ignored-data))
|
||||
|
||||
(define (dfs->list dfs)
|
||||
(list (dfs-node dfs) (dfs-adjacencies dfs) (dfs-ignored-data dfs)))
|
||||
(define (dfs->list dfs-node)
|
||||
(list (dfs-name dfs-node) (dfs-adjacencies dfs-node) (dfs-ignored dfs-node)))
|
||||
|
||||
(define (dfs-timer ch)
|
||||
(spawn
|
||||
(lambda ()
|
||||
(let timer-loop ((current-time 0))
|
||||
(cml-sync-ch/receive ch)
|
||||
(cml-sync-ch/send ch current-time)
|
||||
(timer-loop (+ current-time 1))))))
|
||||
(define (dfs-lookup-node node-name dag)
|
||||
(find (lambda (candidate)
|
||||
(string=? (dfs-name candidate) node-name))
|
||||
dag))
|
||||
|
||||
(define (dfs-time ch)
|
||||
(cml-sync-ch/send ch 'get-time)
|
||||
(cml-sync-ch/receive ch))
|
||||
;;;
|
||||
;;; DEPTH FIRST SEARCH:
|
||||
;;; ===================
|
||||
;;;
|
||||
;;; (dfs dag) ---> sorted-dag
|
||||
;;; (dfs dag auto-leafs?) ---> sorted-dag
|
||||
;;;
|
||||
;;; where
|
||||
;;;
|
||||
;;; dag : '(#{:dfs} ...)
|
||||
;;; auto-leafs? : #t (by default) or #f
|
||||
;;; sorted-dag : the sorted dag
|
||||
;;;
|
||||
;;; auto-leafs?:
|
||||
;;;
|
||||
;;; if auto-leafs? is enabled then every adjacency which is unresolveable
|
||||
;;; in the set of all node-names is assumed to point to a leaf.
|
||||
;;; this leaf is then created automatically: it consists of the node-name
|
||||
;;; which was given by the initiating adjencency, the empty adjacencies
|
||||
;;; list, and the ignored-data-field set to #f.
|
||||
;;; if auto-leafs? is set to #f then it is an error that an adjacency is
|
||||
;;; unresolveable in the list of all node-names.
|
||||
;;;
|
||||
(define (dfs dag . maybe-arg)
|
||||
(let-optionals maybe-arg ((auto-leafs? #t))
|
||||
(set! time 0)
|
||||
(let ((node-names (map dfs-name dag)))
|
||||
(if (not (null? node-names))
|
||||
;; (sort pred todo-list done-list)
|
||||
(sort (lambda (current position)
|
||||
(< (dfs-ftime current) (dfs-ftime position)))
|
||||
;;
|
||||
;; the result of this should be the dag with the ftimes
|
||||
;;
|
||||
(let for-all-nodes ((node-name (car node-names))
|
||||
(nodes-to-do (cdr node-names))
|
||||
(current-dag dag))
|
||||
(let ((current-node (dfs-lookup-node node-name current-dag)))
|
||||
(cond
|
||||
((eq? (dfs-color current-node) (color white))
|
||||
(let ((new-dag (dfs-visit current-dag
|
||||
current-node auto-leafs?)))
|
||||
(if (not (null? nodes-to-do))
|
||||
(for-all-nodes (car nodes-to-do)
|
||||
(cdr nodes-to-do)
|
||||
new-dag)
|
||||
new-dag)))
|
||||
(else (if (not (null? nodes-to-do))
|
||||
(for-all-nodes (car nodes-to-do)
|
||||
(cdr nodes-to-do)
|
||||
current-dag)
|
||||
current-dag)))))
|
||||
'())
|
||||
node-names))))
|
||||
|
||||
(define (dfs-lookup-adjs dag adj)
|
||||
(let ((maybe-rc ))
|
||||
(if maybe-rc maybe-rc
|
||||
(define (dfs-visit dag node auto-leafs?)
|
||||
;; (dfs-dag-show dag node)
|
||||
(let ((name (dfs-name node))
|
||||
(adjs (dfs-adjacencies node))
|
||||
(ignored (dfs-ignored node)))
|
||||
(let* ((current-node (really-make-dfs name adjs (color grey)
|
||||
(dfs-ftime node) ignored))
|
||||
(current-dag (cons current-node (delete node dag))))
|
||||
(if (not (null? adjs))
|
||||
(let for-all-adjs ((current-adj (car adjs))
|
||||
(todo-adjs (cdr adjs)))
|
||||
(let ((maybe-node (dfs-lookup-node current-adj current-dag)))
|
||||
(if maybe-node
|
||||
(begin
|
||||
(if (eq? (dfs-color maybe-node) (color white))
|
||||
(let ((next-dag (dfs-visit current-dag
|
||||
maybe-node auto-leafs?)))
|
||||
(set! current-dag next-dag))
|
||||
(if (eq? (dfs-color maybe-node) (color grey))
|
||||
(error "dfs-visit: cycle detected; node-name: "
|
||||
(dfs-name node)))))
|
||||
(if auto-leafs?
|
||||
(let ((leaf (really-make-dfs current-adj '()
|
||||
(color white) 0 #f)))
|
||||
(set! current-dag (dfs-visit (cons leaf current-dag)
|
||||
leaf auto-leafs?)))
|
||||
(error "dfs-visit: incomplete dag!"))))
|
||||
(if (not (null? todo-adjs))
|
||||
(for-all-adjs (car todo-adjs) (cdr todo-adjs)))))
|
||||
(set! time (+ time 1))
|
||||
(cons (really-make-dfs name adjs (color black) time ignored)
|
||||
(delete current-node current-dag)))))
|
||||
|
||||
(define (dfs-visit dag node time-ch)
|
||||
(set! (dfs-color node) (color grey))
|
||||
(set! (dfs-dtime node) (dfs-time time-ch))
|
||||
(for-each (lambda (adj)
|
||||
(cond
|
||||
((eq? (dfs-color adj) (color white))
|
||||
(begin
|
||||
(set! (dfs-predecessor adj) node)
|
||||
(dfs-visit adj time-ch)))
|
||||
;;
|
||||
;; ((eq? (dfs-color adj) (color black))
|
||||
;; "already been here")
|
||||
;;
|
||||
((eq? (dfs-color adj) (color grey))
|
||||
(error "dfs-visit: cycle detected!"))))
|
||||
;; this should be the list of all adjacency-nodes
|
||||
;; this is done by map over all adjacencies
|
||||
;; lookup each adj in dag, check if its node-name is adj
|
||||
(map (lambda (adj)
|
||||
(find (lambda (candidate)
|
||||
(eq? (dfs-node candidate) adj))
|
||||
dag))
|
||||
(dfs-adjs node)))
|
||||
(set! (dfs-color node) (color black))
|
||||
(set! (dfs-ftime node) (dfs-time time-ch)))
|
||||
|
||||
;;; this is the depth first search algorithm
|
||||
;;; dag is a list of nodes of record-type dfs
|
||||
(define (dfs dag)
|
||||
(let* ((time-ch (cml-sync-ch/make-channel))
|
||||
(start-timer (dfs-timer time-ch)))
|
||||
(define (dfs-dag-show dag node)
|
||||
(newline) (newline) (newline) (newline)
|
||||
(display "************************************************************\n")
|
||||
(display (dfs-name node)) (newline)
|
||||
(display "************************************************************\n")
|
||||
(let ((dfs-node-show (lambda (node)
|
||||
(newline)
|
||||
(display "~dfs-name: ")
|
||||
(display (dfs-name node))
|
||||
(newline)
|
||||
(display "~dfs-adjacencies: ")
|
||||
(display (dfs-adjacencies node))
|
||||
(newline)
|
||||
(display "~dfs-color: ")
|
||||
(display (dfs-color node))
|
||||
(newline)
|
||||
(display "~dfs-ftime: ")
|
||||
(display (dfs-ftime node))
|
||||
(newline)
|
||||
(display "~dfs-ignored: ")
|
||||
(display (dfs-ignored node))
|
||||
(newline))))
|
||||
(if (not (null? dag))
|
||||
(begin
|
||||
(let visit-each-node ((current-node (car dag))
|
||||
(nodes-to-do (cdr dag)))
|
||||
(if (eq? (dfs-color current-node) (color white))
|
||||
(dfs-visit dag current-node time-ch))
|
||||
(if (not (null? nodes-to-do))
|
||||
(visit-each-node (car nodes-to-do) (cdr nodes-to-do))))
|
||||
;; now sort field (dfs-ftime node) in descendent order
|
||||
...
|
||||
))))
|
||||
|
||||
(define (dfs-sort-insert pred item queue)
|
||||
(cond
|
||||
((null? queue) (cons item))
|
||||
((not (pred item (car queue))) (cons item queue))
|
||||
(else (dfs-sort-insert item (cdr queue)))))
|
||||
|
||||
(define (dfs-sort pred todo done)
|
||||
(if (null? todo)
|
||||
done
|
||||
(dfs-sort pred (cdr todo) (dfs-sort-insert pred (car todo) done))))
|
||||
(let visit-each-node ((current-node (car dag))
|
||||
(nodes-to-do (cdr dag)))
|
||||
(dfs-node-show current-node)
|
||||
(if (not (null? nodes-to-do))
|
||||
(visit-each-node (car nodes-to-do) (cdr nodes-to-do))
|
||||
(begin
|
||||
(display "************************************************************\n")
|
||||
(display "************************************************************\n")
|
||||
(newline) (newline) (newline) (newline)))))))
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
Starting make:
|
||||
==============
|
||||
|
||||
In XEmacs open a new buffer to edit this makefile-c.scm. Make sure you
|
||||
had no active scheme-buffer. This will have the effect that your
|
||||
current working directory is the one with makefile-c.scm in it. Now
|
||||
open a new scheme-buffer with 'M-x run-scheme'. You should have passed
|
||||
(at least) the following arguments to scsh:
|
||||
|
||||
'scsh -lel cml/load.scm -lel concurrency/load.scm'
|
||||
|
||||
Now load the packages.scm file into package config:
|
||||
|
||||
> ,config ,load ../packages.scm
|
||||
|
||||
Open the structures macros and make in package user:
|
||||
|
||||
> ,open macros make
|
||||
|
||||
Load makefile-c.scm:
|
||||
|
||||
> ,load makefile-c.scm
|
||||
|
||||
Start make:
|
||||
|
||||
> (make rule-set (list "test"))
|
||||
|
||||
This should start a build all, install, and test installation process.
|
||||
By default, the installation directory will be ../../image.
|
||||
|
||||
Have fun.
|
|
@ -0,0 +1,3 @@
|
|||
71537751982895759163390057694999171418 config.h
|
||||
14291919577004468625754235508931697268 mymath.c
|
||||
277010555671960749526965727376092322885 manual.tex
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef MY_DELTA_MAX
|
||||
#define MY_DELTA_MAX 0.00000000000001
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
#include "wildio.h"
|
||||
#include "mymath.h"
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
double magic_number = 0.0;
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
void *libwildio;
|
||||
int (*show_a_double_call)(double);
|
||||
double (*checkargs_call)(int,char**);
|
||||
|
||||
void *libmymath;
|
||||
double (*sqrt_call)(double), result;
|
||||
|
||||
dlerror();
|
||||
|
||||
if (libwildio=dlopen("libwildio.so.1",RTLD_LAZY))
|
||||
{
|
||||
checkargs_call = dlsym(libwildio,"checkargs");
|
||||
show_a_double_call = dlsym(libwildio,"show_a_double");
|
||||
|
||||
/* magic_number will be set by checkargs */
|
||||
magic_number = (*checkargs_call)(argc,argv);
|
||||
|
||||
if (libmymath=dlopen("libmymath.so.1",RTLD_LAZY)) {
|
||||
sqrt_call = dlsym(libmymath,"sqrt");
|
||||
magic_number = (*sqrt_call)(magic_number);
|
||||
|
||||
result = (*show_a_double_call)(magic_number);
|
||||
|
||||
dlclose(libmymath);
|
||||
dlclose(libwildio);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* last exit */
|
||||
exit(1);
|
||||
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
(define image-dir "../../image")
|
||||
(define prefix (string-append image-dir "/" "usr"))
|
||||
(define my-lib-dir (string-append prefix "/" "lib"))
|
||||
(define my-bin-dir (string-append prefix "/" "bin"))
|
||||
(define my-share-dir (string-append prefix "/" "share"))
|
||||
(define my-doc-dir (string-append my-share-dir "/" "doc"))
|
||||
(define my-install-doc-dir (string-append my-doc-dir "/" "show-sqrt-1.0"))
|
||||
|
||||
(define clean-files
|
||||
(list "wildio.o" "mymath.o"
|
||||
"libwildio.so.1.0" "libmymath.so.1.0"
|
||||
"libwildio.so.1" "libmymath.so.1"
|
||||
"libwildio.so" "libmymath.so"
|
||||
"show-sqrt"
|
||||
"manual.dvi" "manual.pdf" "manual.log" "manual.aux"))
|
||||
|
||||
(define rule-set
|
||||
(makefile
|
||||
;;
|
||||
;; build libmymath.*
|
||||
;;
|
||||
(md5 "mymath.o"
|
||||
("config.h" "mymath.c")
|
||||
(lambda ()
|
||||
(run (gcc -fPIC -c ,"mymath.c"))))
|
||||
(rule "libmymath.so.1.0"
|
||||
("mymath.o")
|
||||
(lambda ()
|
||||
(run (gcc -shared ,"-Wl,-soname,libmymath.so.1"
|
||||
-o ,"libmymath.so.1.0" ,"mymath.o"))))
|
||||
;;
|
||||
;; build wildio.*
|
||||
;;
|
||||
(rule "wildio.o"
|
||||
("wildio.c")
|
||||
(lambda ()
|
||||
(run (gcc -fPIC -c ,"wildio.c"))))
|
||||
(rule "libwildio.so.1.0"
|
||||
("wildio.o")
|
||||
(lambda ()
|
||||
(run (gcc -shared "-Wl,-soname,libwildio.so.1"
|
||||
-o ,"libwildio.so.1.0" ,"wildio.o"))))
|
||||
;;
|
||||
;; build the program
|
||||
;;
|
||||
(rule "show-sqrt"
|
||||
("libmymath.so.1" "libwildio.so.1" "main.c" "wildio.h" "mymath.h")
|
||||
(lambda ()
|
||||
(run (gcc -L ,"." -L ,my-lib-dir -rdynamic
|
||||
-o ,(expand-file-name "show-sqrt" (cwd))
|
||||
,(expand-file-name "main.c" (cwd))
|
||||
,(expand-file-name "libwildio.so.1" (cwd))
|
||||
,(expand-file-name "libmymath.so.1" (cwd)) -ldl))))
|
||||
;;
|
||||
;; install libs
|
||||
;;
|
||||
(rule "libmymath.so.1"
|
||||
("libmymath.so.1.0")
|
||||
(lambda ()
|
||||
(create-symlink "libmymath.so.1.0" "libmymath.so.1")))
|
||||
(rule "libmymath.so"
|
||||
("libmymath.so.1")
|
||||
(lambda ()
|
||||
(create-symlink "libmymath.so.1" "libmymath.so")))
|
||||
(rule "libwildio.so.1"
|
||||
("libwildio.so.1.0")
|
||||
(lambda ()
|
||||
(create-symlink "libwildio.so.1.0" "libwildio.so.1")))
|
||||
(rule "libwildio.so"
|
||||
("libwildio.so.1")
|
||||
(lambda ()
|
||||
(create-symlink "libwildio.so.1" "libwildio.so")))
|
||||
(rule (string-append my-lib-dir "/" "libmymath.so.1")
|
||||
((string-append my-lib-dir "/" "libmymath.so.1.0"))
|
||||
(lambda ()
|
||||
(with-cwd my-lib-dir
|
||||
(create-symlink "libmymath.so.1.0" "libmymath.so.1"))))
|
||||
(rule (string-append my-lib-dir "/" "libmymath.so")
|
||||
((string-append my-lib-dir "/" "libmymath.so.1"))
|
||||
(lambda ()
|
||||
(with-cwd my-lib-dir
|
||||
(create-symlink "libmymath.so.1" "libmymath.so"))))
|
||||
(rule (string-append my-lib-dir "/" "libwildio.so.1")
|
||||
((string-append my-lib-dir "/" "libwildio.so.1.0"))
|
||||
(lambda ()
|
||||
(with-cwd my-lib-dir
|
||||
(create-symlink "libwildio.so.1.0" "libwildio.so.1"))))
|
||||
(rule (string-append my-lib-dir "/" "libwildio.so")
|
||||
((string-append my-lib-dir "/" "libwildio.so.1"))
|
||||
(lambda ()
|
||||
(with-cwd my-lib-dir
|
||||
(create-symlink "libwildio.so.1" "libwildio.so"))))
|
||||
(rule (string-append my-lib-dir "/" "libwildio.so.1.0")
|
||||
(my-lib-dir "libwildio.so.1.0")
|
||||
(lambda ()
|
||||
(run (cp ,"libwildio.so.1.0"
|
||||
,(string-append my-lib-dir "/" "libwildio.so.1.0")))))
|
||||
(rule (string-append my-lib-dir "/" "libmymath.so.1.0")
|
||||
(my-lib-dir "libmymath.so.1.0")
|
||||
(lambda ()
|
||||
(run (cp ,"libmymath.so.1.0"
|
||||
,(string-append my-lib-dir "/" "libmymath.so.1.0")))))
|
||||
;;
|
||||
;; install the program
|
||||
;;
|
||||
(rule (string-append my-bin-dir "/" "show-sqrt")
|
||||
(my-bin-dir "show-sqrt")
|
||||
(lambda ()
|
||||
(run (cp ,"show-sqrt"
|
||||
,(string-append my-bin-dir "/" "show-sqrt")))))
|
||||
;;
|
||||
;; build the manual
|
||||
;;
|
||||
(md5 "manual.dvi"
|
||||
("manual.tex")
|
||||
(lambda ()
|
||||
(run (latex ,"manual.tex"))))
|
||||
(rule "manual.pdf"
|
||||
("manual.dvi")
|
||||
(lambda ()
|
||||
(run (dvipdfm -o ,"manual.pdf" ,"manual.dvi"))))
|
||||
;;
|
||||
;; install the manual
|
||||
;;
|
||||
(rule (string-append my-install-doc-dir "/" "manual.pdf")
|
||||
(my-install-doc-dir "manual.pdf")
|
||||
(lambda ()
|
||||
(run (cp "manual.pdf"
|
||||
,(string-append my-install-doc-dir "/" "manual.pdf")))))
|
||||
;;
|
||||
;; install all
|
||||
;;
|
||||
(rule "install"
|
||||
((string-append my-lib-dir "/" "libmymath.so.1.0")
|
||||
(string-append my-lib-dir "/" "libwildio.so.1.0")
|
||||
(string-append my-lib-dir "/" "libmymath.so.1")
|
||||
(string-append my-lib-dir "/" "libwildio.so.1")
|
||||
(string-append my-lib-dir "/" "libmymath.so")
|
||||
(string-append my-lib-dir "/" "libwildio.so")
|
||||
(string-append my-bin-dir "/" "show-sqrt")
|
||||
(string-append my-install-doc-dir "/" "manual.pdf"))
|
||||
(lambda ()
|
||||
(display "install done.\n")))
|
||||
;;
|
||||
;; create checksums.md5
|
||||
;;
|
||||
(once "checksums.md5"
|
||||
("manual.tex" "main.c" "mymath.c"
|
||||
"mymath.h" "wildio.c" "wildio.h" "config.h")
|
||||
(lambda ()
|
||||
(let ((outport (open-output-file (expand-file-name "checksums.md5"
|
||||
(cwd)))))
|
||||
(with-current-output-port outport (display ""))
|
||||
(close-output-port outport))))
|
||||
(rule "config.h"
|
||||
()
|
||||
(lambda ()
|
||||
(let ((outport (open-output-file
|
||||
(expand-file-name "config.h" (cwd)))))
|
||||
(with-current-output-port
|
||||
outport
|
||||
(display "#ifndef MY_DELTA_MAX\n")
|
||||
(display "#define MY_DELTA_MAX 0.000000001\n")
|
||||
(display "#endif\n")
|
||||
(close-output-port outport)))))
|
||||
;;
|
||||
;; clean rules
|
||||
;;
|
||||
(always "clean"
|
||||
()
|
||||
(lambda ()
|
||||
(for-each (lambda (f)
|
||||
(delete-filesys-object (expand-file-name f (cwd))))
|
||||
clean-files)))
|
||||
;;
|
||||
;; clean rules
|
||||
;;
|
||||
(always "mrproper"
|
||||
("clean")
|
||||
(lambda ()
|
||||
(for-each (lambda (f)
|
||||
(delete-filesys-object (expand-file-name f (cwd))))
|
||||
(list "checksums.md5"))))
|
||||
;;
|
||||
;; uninstall all
|
||||
;;
|
||||
(always "uninstall"
|
||||
()
|
||||
(lambda ()
|
||||
(display "uninstall: \n")
|
||||
(for-each (lambda (f)
|
||||
(delete-filesys-object f))
|
||||
(list (string-append my-lib-dir "/" "libmymath.so.1.0")
|
||||
(string-append my-lib-dir "/" "libwildio.so.1.0")
|
||||
(string-append my-lib-dir "/" "libmymath.so.1")
|
||||
(string-append my-lib-dir "/" "libwildio.so.1")
|
||||
(string-append my-lib-dir "/" "libmymath.so")
|
||||
(string-append my-lib-dir "/" "libwildio.so")
|
||||
(string-append my-bin-dir "/" "show-sqrt")
|
||||
(string-append my-install-doc-dir "/" "manual.pdf")
|
||||
my-install-doc-dir
|
||||
my-doc-dir
|
||||
my-share-dir
|
||||
my-lib-dir
|
||||
my-bin-dir
|
||||
prefix
|
||||
image-dir))
|
||||
(display "uninstall done.\n")))
|
||||
;;
|
||||
;; install dirs
|
||||
;;
|
||||
(once image-dir
|
||||
()
|
||||
(lambda ()
|
||||
(create-directory image-dir)))
|
||||
(once prefix
|
||||
(image-dir)
|
||||
(lambda ()
|
||||
(create-directory prefix)))
|
||||
(once my-lib-dir
|
||||
(prefix)
|
||||
(lambda ()
|
||||
(create-directory my-lib-dir)))
|
||||
(once my-bin-dir
|
||||
(prefix)
|
||||
(lambda ()
|
||||
(create-directory my-bin-dir)))
|
||||
(once my-share-dir
|
||||
(prefix)
|
||||
(lambda ()
|
||||
(create-directory my-share-dir)))
|
||||
(once my-doc-dir
|
||||
(my-share-dir)
|
||||
(lambda ()
|
||||
(create-directory my-doc-dir)))
|
||||
(once my-install-doc-dir
|
||||
(my-doc-dir)
|
||||
(lambda ()
|
||||
(create-directory my-install-doc-dir)))
|
||||
;;
|
||||
;; a small test
|
||||
;;
|
||||
(always "test"
|
||||
("install")
|
||||
(lambda ()
|
||||
(let ((proggy (expand-file-name "show-sqrt" my-bin-dir)))
|
||||
(display "testing ") (display proggy) (newline)
|
||||
(setenv "LD_LIBRARY_PATH" my-lib-dir)
|
||||
(display "# sqrt 2.0:\n")
|
||||
(run (,proggy ,"2.0"))
|
||||
(display "# sqrt 5.0:\n")
|
||||
(run (,proggy ,"5.0"))
|
||||
(display "ok.\n"))))))
|
|
@ -0,0 +1,19 @@
|
|||
\documentclass[a4paper]{report}
|
||||
\usepackage[dvipdfm,hyperindex,hypertex,
|
||||
pdftitle={show-sqrt manual, release 1.0},
|
||||
pdfauthor={Johannes Brügmann}
|
||||
colorlinks=true,linkcolor=blue,pagecolor=blue,urlcolor=blue,
|
||||
pdfstartview=FitW,pdfview=FitW]{hyperref}
|
||||
\usepackage{charter}
|
||||
\author{Real A. Name}
|
||||
\title{show-sqrt rel. 1.0 manual}
|
||||
\begin{document}
|
||||
\maketitle
|
||||
This is the show-sqrt release 1.0 manual.
|
||||
|
||||
show-sqrt comes with a single feature: It calculates the square root
|
||||
of a passed as an argument given positive double value and prints the
|
||||
result on screen (stdout).
|
||||
|
||||
Have fun.
|
||||
\end{document}
|
|
@ -0,0 +1,28 @@
|
|||
#include "config.h"
|
||||
|
||||
double positive (double x) {
|
||||
|
||||
if (x > 0.0)
|
||||
return x;
|
||||
else
|
||||
return 0.0 - x;
|
||||
|
||||
}
|
||||
|
||||
double sqrt (double a) {
|
||||
|
||||
double x_old = 1.0, x_new = 0.5;
|
||||
|
||||
if (a > 0.0) {
|
||||
do {
|
||||
|
||||
x_old = x_new;
|
||||
x_new = ((a / x_old) + x_old) / 2.0;
|
||||
|
||||
} while (positive(x_old - x_new) > MY_DELTA_MAX);
|
||||
|
||||
return x_new;
|
||||
|
||||
} else exit(1);
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
double sqrt (double a);
|
|
@ -0,0 +1,28 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
int show_a_double (double x) {
|
||||
|
||||
printf(">> double: %09.15f\n", x);
|
||||
|
||||
}
|
||||
|
||||
int usage(char *progname) {
|
||||
|
||||
char *str;
|
||||
|
||||
printf("usage: %s <double-value>\n", progname);
|
||||
exit(ENOTSUP);
|
||||
|
||||
}
|
||||
|
||||
int checkargs(int argc, char *argv[]) {
|
||||
|
||||
double darg = 0.0;
|
||||
|
||||
if (argc != 2) usage((char *const) argv[0]);
|
||||
else darg = atof(argv[1]);
|
||||
|
||||
return darg;
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
int show_a_double (double x);
|
||||
int checkargs(int argc, char *argv[]);
|
243
macros.scm
243
macros.scm
|
@ -1,132 +1,157 @@
|
|||
;;; TODO:
|
||||
;;;
|
||||
;;; macros -> functions, eg.
|
||||
;;;
|
||||
;;; (define make-is-out-of-date!
|
||||
;;; (lambda (t . p)
|
||||
;;; (lambda args (cons #t (last args)))))
|
||||
|
||||
(define-syntax make
|
||||
(syntax-rules ()
|
||||
((make ?rule-trans-set (?target-fname0 ...) ?init-state)
|
||||
;;
|
||||
;; ?rule-trans-set or ?target-fname0 could be an expr: eval only once
|
||||
;;
|
||||
(let ((rule-trans-set (known-rules-update ?rule-trans-set)))
|
||||
(let* ((target-fname0 ?target-fname0)
|
||||
(target-rule (known-rules-get rule-trans-set target-fname0)))
|
||||
(if (not (null? (rule-trans-set-rule-candidates rule-trans-set)))
|
||||
(display "rule-candidates not empty.\n"))
|
||||
(if target-rule
|
||||
(rule-make target-rule
|
||||
?init-state
|
||||
(rule-trans-set-rule-set rule-trans-set))
|
||||
(error "target-rule not found in rule-set.")))
|
||||
...))
|
||||
((_ )
|
||||
(error "usage: (make '#{:rule-trans-set} (target0 ...) init-state)\n"))))
|
||||
;;; MAKEFILE:
|
||||
;;; =========
|
||||
|
||||
;;; (define-syntax makefile
|
||||
;;; (syntax-rules ()
|
||||
;;; ((makefile ?rule0 ...)
|
||||
;;; (let ((rule-trans-set (make-empty-rule-trans-set)))
|
||||
;;; (let* ((rule-trans-set (?rule0 rule-trans-set))
|
||||
;;; (let ((rule-candidates '()))
|
||||
;;; (let* ((rule-candidates (?rule0 rule-candidates))
|
||||
;;; ...)
|
||||
;;; rule-trans-set)))))
|
||||
;;; rule-candidates)))))
|
||||
|
||||
;;;
|
||||
;;; <makefile> ::= '(' + "makefile" + <makerule-clause>* + ')'
|
||||
;;; <makerule-clause> ::= <rule-clause>
|
||||
;;; | <md5-clause>
|
||||
;;; | <always-clause>
|
||||
;;; | <once-clause>
|
||||
;;;
|
||||
;;;
|
||||
(define-syntax makefile
|
||||
(syntax-rules ()
|
||||
((makefile) (make-empty-rule-trans-set))
|
||||
((makefile ?rule0 ?rule1 ...)
|
||||
(?rule0 (makefile ?rule1 ...)))))
|
||||
((makefile) (list))
|
||||
((makefile ?rule0 ?rule1 ...) (?rule0 (makefile ?rule1 ...)))))
|
||||
|
||||
;;;
|
||||
;;; <rule-clause>
|
||||
;;;
|
||||
;;; to achieve consistency only rule will use the rule-tmpvars
|
||||
;;; macro directly and all other macros use this clause
|
||||
;;;
|
||||
(define-syntax makefile-rule
|
||||
(syntax-rules ()
|
||||
((makefile-rule ?target (?prereq0 ...) ?thunk)
|
||||
(makefile-rule-tmpvars () ?target (?prereq0 ...) ?thunk))))
|
||||
((makefile-rule ?target ?prereqs ?thunk) (rule ?target ?prereqs ?thunk))))
|
||||
|
||||
(define-syntax makefile-rule-tmpvars
|
||||
(define-syntax is-out-of-date?
|
||||
(syntax-rules ()
|
||||
((makefile-rule-tmpvars (tmp1 ...) ?target () ?thunk)
|
||||
;;
|
||||
;; ?target could be an expr: eval only once
|
||||
;;
|
||||
(let ((target ?target))
|
||||
(lambda (rule-trans-set)
|
||||
(rule-trans-set-add rule-trans-set
|
||||
target
|
||||
(list tmp1 ...)
|
||||
(make-is-out-of-date? target tmp1 ...)
|
||||
(lambda ?args (?thunk))))))
|
||||
;;
|
||||
;; recursively construct temporary, hygienic variables
|
||||
;;
|
||||
((makefile-rule-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?thunk)
|
||||
((is-out-of-date? ?target ?prereqs ?thunk) (rule ?target ?prereqs ?thunk))))
|
||||
|
||||
(define-syntax rule
|
||||
(syntax-rules ()
|
||||
((rule ?target (?prereq0 ...) ?thunk)
|
||||
(rule-tmpvars () ?target (?prereq0 ...) ?thunk))))
|
||||
|
||||
(define-syntax rule-tmpvars
|
||||
(syntax-rules ()
|
||||
((rule-tmpvars (tmp1 ...) ?target () ?thunk)
|
||||
(let ((target ?target)
|
||||
(prereqs (list tmp1 ...)))
|
||||
(lambda (rule-candidates)
|
||||
(cons (list target
|
||||
prereqs
|
||||
(make-is-out-of-date? target tmp1 ...)
|
||||
(make-rule-build-func target prereqs ?thunk))
|
||||
rule-candidates))))
|
||||
((rule-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?thunk)
|
||||
(let ((tmp2 ?prereq0))
|
||||
(makefile-rule-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?thunk)))))
|
||||
(rule-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?thunk)))))
|
||||
|
||||
(define-syntax makefile-rule-md5
|
||||
;;;
|
||||
;;; <md5-clause>
|
||||
;;;
|
||||
;;; to achieve consistency only rule-md5 will use the rule-md5-tmpvars
|
||||
;;; macro directly and all other macros use this clause
|
||||
;;;
|
||||
(define-syntax md5
|
||||
(syntax-rules ()
|
||||
((makefile-rule-md5 ?fingerprint ?target (?prereq0 ...) ?thunk)
|
||||
(makefile-rule-md5-tmpvars () ?fingerprint ?target (?prereq0 ...) ?thunk))))
|
||||
((md5 ?target ?prereqs ?thunk) (rule-md5 ?target ?prereqs ?thunk))))
|
||||
|
||||
(define-syntax makefile-rule-md5-tmpvars
|
||||
(define-syntax rule-md5
|
||||
(syntax-rules ()
|
||||
((makefile-rule-md5-tmpvars (tmp1 ...) ?fingerprint ?target () ?thunk)
|
||||
;;
|
||||
;; ?target could be an expr: eval only once
|
||||
;;
|
||||
(let ((target ?target))
|
||||
(lambda (rule-trans-set)
|
||||
(rule-trans-set-add rule-trans-set
|
||||
target
|
||||
(list tmp1 ...)
|
||||
(make-has-md5-digest=? ?fingerprint
|
||||
target
|
||||
tmp1 ...)
|
||||
(lambda ?args (?thunk))))))
|
||||
;;
|
||||
;; recursively construct temporary, hygienic variables
|
||||
;;
|
||||
((makefile-rule-md5-tmpvars (tmp1 ...) ?fingerprint ?target
|
||||
(?prereq0 ?prereq1 ...) ?thunk)
|
||||
((rule-md5 ?target (?prereq0 ...) ?thunk)
|
||||
(rule-md5-tmpvars () ?target (?prereq0 ...) ?thunk))))
|
||||
|
||||
(define-syntax rule-md5-tmpvars
|
||||
(syntax-rules ()
|
||||
((rule-md5-tmpvars (tmp1 ...) ?target () ?thunk)
|
||||
(let ((target ?target)
|
||||
(prereqs (list tmp1 ...)))
|
||||
(lambda (rule-candidates)
|
||||
(cons (list target
|
||||
prereqs
|
||||
(make-md5-sum-changed? target tmp1 ...)
|
||||
(make-md5-build-func target prereqs ?thunk))
|
||||
rule-candidates))))
|
||||
((rule-md5-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?thunk)
|
||||
(let ((tmp2 ?prereq0))
|
||||
(makefile-rule-md5-tmpvars (tmp1 ... tmp2) ?fingerprint
|
||||
?target (?prereq1 ...) ?thunk)))))
|
||||
(rule-md5-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?thunk)))))
|
||||
|
||||
(define-syntax make-is-out-of-date?
|
||||
(syntax-rules ()
|
||||
((make-is-out-of-date? ?target)
|
||||
(lambda ?args
|
||||
(cons (file-not-exists? ?target) ?args)))
|
||||
((make-is-out-of-date? ?target ?prereq0 ...)
|
||||
(lambda ?args
|
||||
(cons (and (file-exists? ?prereq0) ...
|
||||
(or (file-not-exists? ?target)
|
||||
(> (file-last-mod ?prereq0)
|
||||
(file-last-mod ?target)))
|
||||
...)
|
||||
(last ?args))))))
|
||||
;;;
|
||||
;;; <always-clause>
|
||||
;;;
|
||||
;;; to achieve consistency only rule-always will use the rule-always-tmpvars
|
||||
;;; macro directly and all other macros use this clause
|
||||
;;;
|
||||
(define-syntax phony
|
||||
(syntax-rules ()
|
||||
((phony ?target ?prereqs ?thunk) (rule-always ?target ?prereqs ?thunk))))
|
||||
|
||||
(define-syntax make-is-out-of-date!
|
||||
(syntax-rules ()
|
||||
((make-is-out-of-date? ?target ?prereq0 ...)
|
||||
(lambda ?args
|
||||
(cons #t (last ?args))))))
|
||||
(define-syntax always
|
||||
(syntax-rules ()
|
||||
((always ?target ?prereqs ?thunk) (rule-always ?target ?prereqs ?thunk))))
|
||||
|
||||
(define-syntax make-has-md5-digest=?
|
||||
(syntax-rules ()
|
||||
((make-has-md5-digest=? ?fingerprint ?target)
|
||||
(lambda ?args
|
||||
(cons (or (file-not-exists? ?target)
|
||||
(=? (md5-digest-for-port (open-input-file ?target))
|
||||
?fingerprint))
|
||||
?args)))
|
||||
((make-has-md5-digest=? ?fingerprint ?target ?prereq0 ...)
|
||||
(lambda ?args
|
||||
(cons (or (file-not-exists? ?target)
|
||||
(=? (md5-digest->number (md5-digest-for-port
|
||||
(open-input-file ?target)))
|
||||
(md5-digest->number ?fingerprint)))
|
||||
(last ?args))))))
|
||||
(define-syntax is-out-of-date!
|
||||
(syntax-rules ()
|
||||
((is-out-of-date! ?target ?prereqs ?thunk)
|
||||
(rule-always ?target ?prereqs ?thunk))))
|
||||
|
||||
(define-syntax rule-always
|
||||
(syntax-rules ()
|
||||
((rule-always ?target (?prereq0 ...) ?thunk)
|
||||
(rule-always-tmpvars () ?target (?prereq0 ...) ?thunk))))
|
||||
|
||||
(define-syntax rule-always-tmpvars
|
||||
(syntax-rules ()
|
||||
((rule-always-tmpvars (tmp1 ...) ?target () ?thunk)
|
||||
(let ((target ?target)
|
||||
(prereqs (list tmp1 ...)))
|
||||
(lambda (rule-candidates)
|
||||
(cons (list target
|
||||
prereqs
|
||||
(make-is-out-of-date! target tmp1 ...)
|
||||
(make-always-build-func target prereqs ?thunk))
|
||||
rule-candidates))))
|
||||
((rule-always-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?thunk)
|
||||
(let ((tmp2 ?prereq0))
|
||||
(rule-always-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?thunk)))))
|
||||
|
||||
;;;
|
||||
;;; <once-clause>
|
||||
;;;
|
||||
;;; to achieve consistency only rule-once will use the rule-once-tmpvars
|
||||
;;; macro directly and all other macros use this clause
|
||||
;;;
|
||||
(define-syntax once
|
||||
(syntax-rules ()
|
||||
((once ?target ?prereqs ?thunk)
|
||||
(rule-once ?target ?prereqs ?thunk))))
|
||||
|
||||
(define-syntax rule-once
|
||||
(syntax-rules ()
|
||||
((rule-once ?target (?prereq0 ...) ?thunk)
|
||||
(rule-once-tmpvars () ?target (?prereq0 ...) ?thunk))))
|
||||
|
||||
(define-syntax rule-once-tmpvars
|
||||
(syntax-rules ()
|
||||
((rule-once-tmpvars (tmp1 ...) ?target () ?thunk)
|
||||
(let ((target ?target)
|
||||
(prereqs (list tmp1 ...)))
|
||||
(lambda (rule-candidates)
|
||||
(cons (list target
|
||||
prereqs
|
||||
(make-once target tmp1 ...)
|
||||
(make-once-build-func target prereqs ?thunk))
|
||||
rule-candidates))))
|
||||
((rule-once-tmpvars (tmp1 ...) ?target (?prereq0 ?prereq1 ...) ?thunk)
|
||||
(let ((tmp2 ?prereq0))
|
||||
(rule-once-tmpvars (tmp1 ... tmp2) ?target (?prereq1 ...) ?thunk)))))
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
(define-record-type :rule-set
|
||||
(make-rule-set rules)
|
||||
is-rule-set?
|
||||
(rules rule-set-rules))
|
||||
(rules rule-set-rules))
|
||||
|
||||
(define (make-empty-rule-set)
|
||||
(make-rule-set '()))
|
||||
|
@ -40,10 +40,12 @@
|
|||
(error "make-rule: rule already exists."))))
|
||||
|
||||
(define (rule-set-get-listen-ch rule rule-set)
|
||||
(let ((?thing (assq rule (rule-set-rules rule-set))))
|
||||
(if (and ?thing (pair? ?thing) (is-collect&reply-channel? (cdr ?thing)))
|
||||
(cdr ?thing)
|
||||
(error "Rule not found in rule-set."))))
|
||||
(let ((maybe-rule (assoc rule (rule-set-rules rule-set))))
|
||||
(if (and maybe-rule
|
||||
(pair? maybe-rule)
|
||||
(is-collect&reply-channel? (cdr maybe-rule)))
|
||||
(cdr maybe-rule)
|
||||
(error "rule not found in rule-set."))))
|
||||
|
||||
;;;
|
||||
;;; RULE-RESULT
|
||||
|
@ -54,7 +56,7 @@
|
|||
;;; (rule-result-build-func rule-result) --->
|
||||
;;; (build-func-result . end-state) oder #f
|
||||
;;;
|
||||
;;; (rule-make rule init-state rule-set) ---> rule-result
|
||||
;;; (rule-make rule init-state rule-set) ---> rule-result
|
||||
;;;
|
||||
(define-record-type :rule-result
|
||||
(make-rule-result wants-build?-result build-func-result)
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
(define (make rcs targets . maybe-arg)
|
||||
(let-optionals maybe-arg ((init-state (list)))
|
||||
(let* ((rules (rcs->rules rcs))
|
||||
(rule-set (rules->rule-set rules))
|
||||
(target-rules (map (lambda (t) (lookup-rule t rules))
|
||||
targets)))
|
||||
(map rule-make
|
||||
target-rules (circular-list init-state)
|
||||
(circular-list rule-set)))))
|
|
@ -0,0 +1,9 @@
|
|||
(define (insert pred item ls)
|
||||
(if (or (null? ls) (pred item (car ls)))
|
||||
(cons item ls)
|
||||
(cons (car ls) (insert pred item (cdr ls)))))
|
||||
|
||||
(define (sort pred todo done)
|
||||
(if (null? todo)
|
||||
done
|
||||
(sort pred (cdr todo) (insert pred (car todo) done))))
|
110
packages.scm
110
packages.scm
|
@ -136,6 +136,8 @@
|
|||
is-rule-set?
|
||||
make-rule-result
|
||||
is-rule-result?
|
||||
rule-result-wants-build?
|
||||
rule-result-build-func
|
||||
rule-make))
|
||||
|
||||
(define-structure make-rule make-rule-interface
|
||||
|
@ -159,6 +161,8 @@
|
|||
is-rule-set?
|
||||
make-rule-result
|
||||
is-rule-result?
|
||||
rule-result-wants-build?
|
||||
rule-result-build-func
|
||||
rule-make))
|
||||
|
||||
(define-structure make-rule-no-cml make-rule-no-cml-interface
|
||||
|
@ -169,35 +173,91 @@
|
|||
srfi-9)
|
||||
(files make-rule-no-cml))
|
||||
|
||||
(define-interface rule-trans-set-interface
|
||||
(export make-rule-trans-set
|
||||
is-rule-trans-set?
|
||||
make-empty-rule-trans-set
|
||||
make-rule-trans-set
|
||||
rule-trans-set-rule-candidates
|
||||
rule-trans-set-known-rules
|
||||
rule-trans-set-rule-set
|
||||
rule-trans-set-add
|
||||
rule-candidate-get
|
||||
known-rules-get))
|
||||
|
||||
(define-structure rule-trans-set rule-trans-set-interface
|
||||
(open scheme-with-scsh
|
||||
srfi-1
|
||||
srfi-9
|
||||
make-rule)
|
||||
(files rule-trans-set))
|
||||
|
||||
(define-interface macros-interface
|
||||
(export (make :syntax)
|
||||
(makefile :syntax)
|
||||
(export (makefile :syntax)
|
||||
(rule :syntax)
|
||||
(makefile-rule :syntax)
|
||||
(make-is-out-of-date? :syntax)))
|
||||
|
||||
(is-out-of-date? :syntax)
|
||||
(md5 :syntax)
|
||||
(rule-md5 :syntax)
|
||||
(phony :syntax)
|
||||
(always :syntax)
|
||||
(is-out-of-date! :syntax)
|
||||
(once :syntax)
|
||||
(rule-once :syntax)))
|
||||
|
||||
(define-structure macros macros-interface
|
||||
(open scheme-with-scsh
|
||||
srfi-1
|
||||
make-rule
|
||||
rule-trans-set)
|
||||
to-rule-set
|
||||
dfs
|
||||
templates
|
||||
make-rule)
|
||||
(files macros))
|
||||
|
||||
(define-interface to-rule-set-interface
|
||||
(export lookup-rc
|
||||
lookup-fname
|
||||
lookup-rule
|
||||
rcs->dag
|
||||
dag->rcs
|
||||
rcs->rules
|
||||
rules->rule-set))
|
||||
|
||||
(define-structure to-rule-set to-rule-set-interface
|
||||
(open scheme-with-scsh
|
||||
srfi-1
|
||||
templates
|
||||
make-rule
|
||||
dfs)
|
||||
(files to-rule-set))
|
||||
|
||||
(define-interface dfs-interface
|
||||
(export make-dfs
|
||||
dfs->list
|
||||
dfs-dag-show
|
||||
dfs))
|
||||
|
||||
(define-structure dfs dfs-interface
|
||||
(open scheme-with-scsh
|
||||
finite-types
|
||||
threads
|
||||
srfi-1
|
||||
srfi-9
|
||||
misc
|
||||
let-opt
|
||||
(with-prefix rendezvous-channels cml-sync-ch/))
|
||||
(files dfs))
|
||||
|
||||
(define-interface misc-interface
|
||||
(export sort
|
||||
insert))
|
||||
|
||||
(define-structure misc misc-interface
|
||||
(open scheme-with-scsh)
|
||||
(files misc))
|
||||
|
||||
(define-interface templates-interface
|
||||
(export make-rule-build-func
|
||||
make-md5-build-func
|
||||
make-always-build-func
|
||||
make-once-build-func
|
||||
make-is-out-of-date!
|
||||
make-once
|
||||
make-is-out-of-date?
|
||||
make-md5-sum-changed?))
|
||||
|
||||
(define-structure templates templates-interface
|
||||
(open scheme-with-scsh
|
||||
srfi-1
|
||||
srfi-13)
|
||||
(files templates))
|
||||
|
||||
(define-structure make (export make)
|
||||
(open scheme-with-scsh
|
||||
srfi-1
|
||||
macros
|
||||
let-opt
|
||||
to-rule-set
|
||||
make-rule)
|
||||
(files make))
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
;;; TODO:
|
||||
;;;
|
||||
;;; change to topological sort
|
||||
|
||||
;;;
|
||||
;;; RULE-TRANS-SET
|
||||
;;;
|
||||
;;; (make-empty-rule-trans-set) ---> rule-trans-set
|
||||
;;;
|
||||
;;; (make-rule-trans-set rule-candidates known-rules rule-set)
|
||||
;;;
|
||||
;;; (rule-trans-set-rule-candidates rts) ---> (rule-candidate0 ...)
|
||||
;;; (rule-trans-set-known-rules rts) ---> (known-rule0 ...)
|
||||
;;; (rule-trans-set-rule-set rts) ---> rule-set
|
||||
;;;
|
||||
;;; (rule-trans-set-add! rule-trans-set target prereqs wants-build? build-func)
|
||||
;;; ---> rule-trans-set
|
||||
;;;
|
||||
(define-record-type :rule-trans-set
|
||||
(make-rule-trans-set rule-candidates known-rules rule-set)
|
||||
is-rule-trans-set?
|
||||
(rule-candidates rule-trans-set-rule-candidates)
|
||||
(known-rules rule-trans-set-known-rules)
|
||||
(rule-set rule-trans-set-rule-set))
|
||||
|
||||
(define (make-empty-rule-trans-set)
|
||||
(let ((rule-candidates '())
|
||||
(known-rules (alist-cons '() '() '()))
|
||||
(rule-set (make-empty-rule-set)))
|
||||
(make-rule-trans-set rule-candidates known-rules rule-set)))
|
||||
|
||||
;;; o every incoming rule is considered as a rule-candidate
|
||||
;;; o add the new rule-candidate to rule-candidates
|
||||
;;; o run known-rules-update afterwards
|
||||
(define rule-trans-set-add
|
||||
(lambda (rule-trans-set target prereqs wants-build? build-func)
|
||||
(rule-candidate-add rule-trans-set target prereqs wants-build? build-func)))
|
||||
|
||||
(define rule-candidate-add
|
||||
(lambda (rule-trans-set target prereqs wants-build? build-func)
|
||||
(let ((rule-candidates (rule-trans-set-rule-candidates rule-trans-set))
|
||||
(known-rules (rule-trans-set-known-rules rule-trans-set))
|
||||
(rule-set (rule-trans-set-rule-set rule-trans-set))
|
||||
(rule-args (list prereqs wants-build? build-func)))
|
||||
(make-rule-trans-set (alist-cons target rule-args rule-candidates)
|
||||
known-rules
|
||||
rule-set))))
|
||||
|
||||
(define (rule-candidate-del rule-trans-set target)
|
||||
(let ((rule-candidates (rule-trans-set-rule-candidates rule-trans-set))
|
||||
(known-rules (rule-trans-set-known-rules rule-trans-set))
|
||||
(rule-set (rule-trans-set-rule-set rule-trans-set)))
|
||||
(make-rule-trans-set (alist-delete! target rule-candidates)
|
||||
known-rules
|
||||
rule-set)))
|
||||
|
||||
(define (rule-candidate-get rule-trans-set target)
|
||||
(let* ((rule-candidates (rule-trans-set-rule-candidates rule-trans-set))
|
||||
(maybe-rule-candidate (assq target rule-candidates)))
|
||||
(if maybe-rule-candidate
|
||||
(cons target (cdr (assq target rule-candidates)))
|
||||
maybe-rule-candidate)))
|
||||
|
||||
;;; o if a target's prereqs are all in known-rules then the rule-candidate
|
||||
;;; can be added to the known-rules as a freshly created rule
|
||||
;;; o any rule-candidate with () as prereqs can be added to the known-rules
|
||||
;;; as well, so this will be the first element of the known-rules
|
||||
(define known-rules-add
|
||||
(lambda (rule-trans-set target prereqs wants-build? build-func)
|
||||
(let ((rule (make-rule (map (lambda (prereq)
|
||||
(known-rules-get rule-trans-set prereq))
|
||||
prereqs)
|
||||
wants-build?
|
||||
build-func))
|
||||
(rule-candidates (rule-trans-set-rule-candidates rule-trans-set))
|
||||
(known-rules (rule-trans-set-known-rules rule-trans-set))
|
||||
(rule-set (rule-trans-set-rule-set rule-trans-set)))
|
||||
(make-rule-trans-set rule-candidates
|
||||
(alist-cons target rule known-rules)
|
||||
(rule-set-add rule rule-set)))))
|
||||
|
||||
(define (known-rules-get rule-trans-set target)
|
||||
(let* ((known-rules (rule-trans-set-known-rules rule-trans-set))
|
||||
(maybe-rule (assoc target known-rules)))
|
||||
(if maybe-rule (cdr maybe-rule) maybe-rule)))
|
||||
|
||||
(define (known-rules-update rts)
|
||||
(let until-no-change ((last-rcs (length (rule-trans-set-rule-candidates rts)))
|
||||
(rule-trans-set rts))
|
||||
(let* ((rule-candidates (rule-trans-set-rule-candidates rule-trans-set))
|
||||
(candidate-descs (map cons (map car rule-candidates)
|
||||
(map cdr rule-candidates))))
|
||||
(let for-candidates ((current-candidate-desc (car candidate-descs))
|
||||
(to-do-candidate-desc (cdr candidate-descs))
|
||||
(current-rts rule-trans-set))
|
||||
(let ((target (list-ref current-candidate-desc 0))
|
||||
(prereqs (list-ref current-candidate-desc 1))
|
||||
(wants-build? (list-ref current-candidate-desc 2))
|
||||
(build-func (list-ref current-candidate-desc 3)))
|
||||
(let* ((known-rules (rule-trans-set-known-rules current-rts))
|
||||
;;
|
||||
;; if all prereqs of a target are in known-rules
|
||||
;; then the rule-candidate can be added to the known-rules
|
||||
;; after its deletion of the rule-candidates
|
||||
;;
|
||||
(new-rts (if (not (memq #f
|
||||
(map (lambda (prereq)
|
||||
(assoc prereq known-rules))
|
||||
prereqs)))
|
||||
(known-rules-add (rule-candidate-del
|
||||
current-rts
|
||||
target)
|
||||
target prereqs
|
||||
wants-build? build-func)
|
||||
current-rts)))
|
||||
(if (not (null? to-do-candidate-desc))
|
||||
(for-candidates (car to-do-candidate-desc)
|
||||
(cdr to-do-candidate-desc)
|
||||
new-rts)
|
||||
(let ((current-rcs (length (rule-trans-set-rule-candidates
|
||||
new-rts))))
|
||||
(if (or (= current-rcs last-rcs) (= current-rcs 0))
|
||||
new-rts
|
||||
(until-no-change current-rcs new-rts))))))))))
|
|
@ -0,0 +1,209 @@
|
|||
;;; TODO:
|
||||
;;;
|
||||
;;; (update-md-sum ...) is (due to history) not very lucky
|
||||
;;;
|
||||
(define digest-files (list "checksums.md5"
|
||||
"fingerprints.md5"
|
||||
"digests.md5"))
|
||||
|
||||
(define digest-extensions (list ".md5" ".fp" ".digest"))
|
||||
|
||||
(define (make-rule-build-func target prereqs thunk)
|
||||
(lambda args
|
||||
(cons (begin
|
||||
(display ";;; rule : ")
|
||||
(display target)
|
||||
(newline)
|
||||
(thunk))
|
||||
(last args))))
|
||||
|
||||
(define (make-md5-build-func target prereqs thunk)
|
||||
(lambda args
|
||||
(cons (begin
|
||||
(display ";;; md5 : ")
|
||||
(display target)
|
||||
(newline)
|
||||
(thunk))
|
||||
(last args))))
|
||||
|
||||
(define (make-always-build-func target prereqs thunk)
|
||||
(lambda args
|
||||
(cons (begin
|
||||
(display ";;; always : ")
|
||||
(display target)
|
||||
(newline)
|
||||
(thunk))
|
||||
(last args))))
|
||||
|
||||
(define (make-once-build-func target prereqs thunk)
|
||||
(lambda args
|
||||
(cons (begin
|
||||
(display ";;; once : ")
|
||||
(display target)
|
||||
(newline)
|
||||
(thunk))
|
||||
(last args))))
|
||||
|
||||
(define (make-is-out-of-date! target . prereqs)
|
||||
;; init-state is the last arg
|
||||
;; pass it untouched to the result
|
||||
(lambda args (cons #t (last args))))
|
||||
|
||||
(define (make-once target . prereqs)
|
||||
;; init-state is the last arg
|
||||
;; pass it untouched to the result
|
||||
(lambda args (cons (file-not-exists? target) (last args))))
|
||||
|
||||
(define (make-is-out-of-date? target . prereqs)
|
||||
(lambda args
|
||||
(let ((init-state (last args)))
|
||||
(cons (or (file-not-exists? target)
|
||||
(and (not (null? prereqs))
|
||||
(let for-each-prereq ((prereq (car prereqs))
|
||||
(todo (cdr prereqs)))
|
||||
(and (file-exists? prereq)
|
||||
(> (file-last-mod prereq)
|
||||
(file-last-mod target))
|
||||
(or (null? todo)
|
||||
(for-each-prereq (car todo) (cdr todo)))))))
|
||||
init-state))))
|
||||
|
||||
(define (make-md5-sum-changed? target . prereqs)
|
||||
(lambda args
|
||||
(let ((init-state (last args))
|
||||
(tfname (expand-file-name target (cwd))))
|
||||
(cons (or (file-not-exists? tfname)
|
||||
(or (null? prereqs)
|
||||
(let for-each-prereq ((prereq (car prereqs))
|
||||
(todo (cdr prereqs)))
|
||||
(let ((pname (expand-file-name prereq (cwd))))
|
||||
(or (and (file-exists? pname)
|
||||
(> (file-last-mod pname)
|
||||
(file-last-mod tfname))
|
||||
(checksum-changed? pname)
|
||||
(or (md5-sum-update pname) #t))
|
||||
(and (not (null? todo))
|
||||
(for-each-prereq (car todo) (cdr todo))))))))
|
||||
init-state))))
|
||||
|
||||
(define (check-files-target+extensions target checksum)
|
||||
(map (lambda (digest-file)
|
||||
(lambda ()
|
||||
(let ((dfile (expand-file-name digest-file (cwd))))
|
||||
(or (file-not-exists? dfile)
|
||||
(let ((strls (port->string-list (open-input-file dfile))))
|
||||
(= checksum
|
||||
(string->number (if (null? strls) "" (car strls)))))))))
|
||||
(map (lambda (ext)
|
||||
(string-append target ext))
|
||||
digest-extensions)))
|
||||
|
||||
(define (update-files-target+extensions target checksum)
|
||||
(map (lambda (digest-file)
|
||||
(lambda ()
|
||||
(let ((dfile (expand-file-name digest-file (cwd))))
|
||||
(and (file-exists? dfile)
|
||||
(let ((outport (open-output-file dfile)))
|
||||
(display ";;; update : ") (display target) (newline)
|
||||
(with-current-output-port
|
||||
outport
|
||||
(lambda ()
|
||||
(display (number->string checksum)) (newline)))
|
||||
(close outport)
|
||||
#t)))))
|
||||
(map (lambda (ext)
|
||||
(string-append target ext))
|
||||
digest-extensions)))
|
||||
|
||||
(define (digest-file->string-list digest-fname)
|
||||
(let* ((inport (open-input-file (expand-file-name digest-fname (cwd))))
|
||||
(strls (map (lambda (str)
|
||||
(let ((ls (string-tokenize str)))
|
||||
(if (not (null? ls))
|
||||
(let ((fp (car ls))
|
||||
(name (cadr ls)))
|
||||
(cons name fp))
|
||||
'())))
|
||||
(port->string-list inport))))
|
||||
(close inport)
|
||||
strls))
|
||||
|
||||
(define (check-digest-files target checksum)
|
||||
(map (lambda (digest-file)
|
||||
(lambda ()
|
||||
(let ((dfile (expand-file-name digest-file (cwd)))
|
||||
(tname (file-name-nondirectory target)))
|
||||
(or (file-not-exists? dfile)
|
||||
(let* ((*fname-md5* (digest-file->string-list dfile))
|
||||
(maybe-md5 (if (or (null? *fname-md5*)
|
||||
(null? (car *fname-md5*)))
|
||||
#f
|
||||
(assoc tname *fname-md5*))))
|
||||
(or (not maybe-md5)
|
||||
(= checksum
|
||||
(string->number (cdr maybe-md5)))))))))
|
||||
digest-files))
|
||||
|
||||
(define (string-list->digest-file dfname strls)
|
||||
(let ((outport (open-output-file (expand-file-name dfname (cwd))))
|
||||
(names (if (or (null? strls) (null? (car strls))) '() (map car strls)))
|
||||
(sums (if (or (null? strls) (null? (car strls))) '() (map cdr strls))))
|
||||
(display ";;; update : ") (display dfname) (newline)
|
||||
(for-each (lambda (name fp)
|
||||
(with-current-output-port outport
|
||||
(for-each display (list fp " " name))
|
||||
(newline)))
|
||||
names sums)
|
||||
(close outport)
|
||||
#t))
|
||||
|
||||
(define (update-digest-files target checksum)
|
||||
(map (lambda (digest-file)
|
||||
(lambda ()
|
||||
(let ((dfile (expand-file-name digest-file (cwd)))
|
||||
(tname (file-name-nondirectory target)))
|
||||
(and (file-exists? dfile)
|
||||
(let* ((*fname-md5* (digest-file->string-list dfile))
|
||||
(cleaned-table (if (or (null? *fname-md5*)
|
||||
(null? (car *fname-md5*)))
|
||||
(list)
|
||||
(alist-delete tname *fname-md5*))))
|
||||
(string-list->digest-file
|
||||
dfile
|
||||
(alist-cons tname checksum cleaned-table)))))))
|
||||
digest-files))
|
||||
|
||||
(define (checksum-changed? target)
|
||||
(let* ((inport (open-input-file target))
|
||||
(checksum (md5-digest->number (md5-digest-for-port inport)))
|
||||
(result-funcs (append (check-files-target+extensions target checksum)
|
||||
(check-digest-files target checksum))))
|
||||
(close inport)
|
||||
(not (let each-result-and ((current (car result-funcs))
|
||||
(todo (cdr result-funcs)))
|
||||
(let ((res (current)))
|
||||
(and res
|
||||
(or (null? todo)
|
||||
(each-result-and (car todo) (cdr todo)))))))))
|
||||
|
||||
(define (md5-sum-update target)
|
||||
(let* ((tname (expand-file-name target (cwd)))
|
||||
(inport (open-input-file tname))
|
||||
(checksum (md5-digest->number (md5-digest-for-port inport)))
|
||||
(update-funcs (append (update-files-target+extensions target checksum)
|
||||
(update-digest-files target checksum))))
|
||||
(close inport)
|
||||
(let ((update-ok? (lambda ()
|
||||
(let each-update-and ((current (car update-funcs))
|
||||
(todo (cdr update-funcs)))
|
||||
(or (current)
|
||||
(and (not (null? todo))
|
||||
(each-update-and (car todo) (cdr todo))))))))
|
||||
;; the default is to use the filename with .md5 extension
|
||||
(if (not (update-ok?))
|
||||
(let ((outport (open-output-file (string-append tname ".md5"))))
|
||||
(with-current-output-port outport
|
||||
(begin
|
||||
(display checksum)
|
||||
(newline)))
|
||||
(close outport))))))
|
135
to-rule-set.scm
135
to-rule-set.scm
|
@ -1,45 +1,122 @@
|
|||
(define (rcs->dag rcs)
|
||||
(map (lambda (rc)
|
||||
(make-dfs (car rc) (cadr rc) (caddr rc) (cadddr rc)))
|
||||
(let ((target (list-ref rc 0))
|
||||
(prereqs (list-ref rc 1))
|
||||
(wants-build? (list-ref rc 2))
|
||||
(build-func (list-ref rc 3)))
|
||||
(make-dfs target prereqs (list wants-build? build-func))))
|
||||
rcs))
|
||||
|
||||
;;;
|
||||
;;; if dfs inserted leafs they have the ignored-data set to #f
|
||||
;;; the build-func will then be set to produce an error
|
||||
;;; in case of the file doesn't exist
|
||||
;;;
|
||||
(define (dag->rcs dag)
|
||||
(map (lambda (node)
|
||||
(let* ((ls (dfs->list node))
|
||||
(target (car ls))
|
||||
(prereqs (cadr ls))
|
||||
(wants-build? (caddr ls))
|
||||
(build-func (cdddr ls)))
|
||||
(list target prereqs wants-build? build-func)))
|
||||
(target (list-ref ls 0))
|
||||
(prereqs (list-ref ls 1))
|
||||
(ignored (list-ref ls 2)))
|
||||
(if ignored
|
||||
(let ((wants-build? (car ignored))
|
||||
(build-func (cadr ignored)))
|
||||
(list target prereqs wants-build? build-func))
|
||||
(let* ((tfname (expand-file-name target (cwd)))
|
||||
(wants-build? (lambda args
|
||||
(cons (file-not-exists? tfname)
|
||||
(last args))))
|
||||
(build-func (lambda args
|
||||
(error "file (assumed leaf) does not exist:"
|
||||
tfname))))
|
||||
(list target prereqs wants-build? build-func)))))
|
||||
dag))
|
||||
|
||||
(define (lookup-rc rcs rc)
|
||||
(define (lookup-rc rc rcs)
|
||||
(let ((maybe-rc (find (lambda (current)
|
||||
(eq? (car rc) (car current)))
|
||||
rcs)))
|
||||
(if maybe-rc maybe-rc (error "lookup-rc: rc not found."))))
|
||||
|
||||
(define (rcs->rules rcs)
|
||||
(let ((sorted-rcs (dag->rcs (dfs (rcs->dag rcs)))))
|
||||
(map (lambda (rc)
|
||||
(let* ((target (car rc))
|
||||
(prereqs (cadr rc))
|
||||
(wants-build? (caddr rc))
|
||||
(build-func (cdddr rc))
|
||||
(prereq-rcs (map (lambda (p)
|
||||
(lookup-rc sorted-rcs p))
|
||||
prereqs))
|
||||
(rule (make-rule prereq-rcs wants-build? build-func)))
|
||||
(cons target rule)))
|
||||
rcs)))
|
||||
(define (lookup-fname fname rcs)
|
||||
(let ((maybe-fname (find (lambda (current)
|
||||
(eq? fname (car current)))
|
||||
rcs)))
|
||||
(if maybe-fname maybe-fname (error "lookup-fname: fname not found."))))
|
||||
|
||||
(define (rules->rule-set rules)
|
||||
(let for-each-rule ((current-rule (if (null? rules) '() (car rules)))
|
||||
(rules-to-do (if (null? rules) '() (cdr rules)))
|
||||
(rule-set (make-empty-rule-set)))
|
||||
(if (not (null? rules-to-do))
|
||||
(for-each-rule (car rules-to-do)
|
||||
(cdr rules-to-do)
|
||||
(rule-set-add current-rule rule-set)))
|
||||
rule-set))
|
||||
(define (lookup-rule fname rules)
|
||||
(let ((maybe-rule (assoc fname rules)))
|
||||
(if maybe-rule
|
||||
(cdr maybe-rule)
|
||||
(error "lookup-rule: fname not found in rules."))))
|
||||
|
||||
(define (rcs->rules rule-candidates)
|
||||
(let* ((sorted-dag (dfs (rcs->dag rule-candidates)))
|
||||
(sorted-rcs (dag->rcs sorted-dag)))
|
||||
;; (dfs-dag-show sorted-dag (car sorted-dag))
|
||||
;; (rcs-show sorted-rcs)
|
||||
(if (not (null? sorted-rcs))
|
||||
(let for-all-rcs ((rc (car sorted-rcs))
|
||||
(todo (cdr sorted-rcs))
|
||||
(last-done '()))
|
||||
(let* ((target (list-ref rc 0))
|
||||
(prereqs (list-ref rc 1))
|
||||
(wants-build? (list-ref rc 2))
|
||||
(build-func (list-ref rc 3))
|
||||
(done (cons (cons target
|
||||
(make-rule (map (lambda (p)
|
||||
(lookup-rule p last-done))
|
||||
prereqs)
|
||||
wants-build?
|
||||
build-func))
|
||||
last-done)))
|
||||
(if (not (null? todo))
|
||||
(for-all-rcs (car todo) (cdr todo) done)
|
||||
done))))))
|
||||
|
||||
(define (rules->rule-set rule-alist)
|
||||
(if (not (null? rule-alist))
|
||||
(let ((rules (map cdr rule-alist)))
|
||||
(let for-each-rule ((current-rule (car rules))
|
||||
(rules-to-do (cdr rules))
|
||||
(rule-set (make-empty-rule-set)))
|
||||
(let ((next-rule-set (rule-set-add current-rule rule-set)))
|
||||
(if (not (null? rules-to-do))
|
||||
(for-each-rule (car rules-to-do)
|
||||
(cdr rules-to-do)
|
||||
next-rule-set)
|
||||
next-rule-set))))))
|
||||
|
||||
(define (rcs-show rcs)
|
||||
(newline) (newline) (newline) (newline)
|
||||
(display ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n")
|
||||
(display ";;; rcs-show ;;;\n")
|
||||
(display ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n")
|
||||
(let ((rc-show (lambda (rc)
|
||||
(let ((target (list-ref rc 0))
|
||||
(prereqs (list-ref rc 1))
|
||||
(wants-build? (list-ref rc 2))
|
||||
(build-func (list-ref rc 3)))
|
||||
(newline)
|
||||
(display "; target: ")
|
||||
(display target)
|
||||
(newline)
|
||||
(display "; prereqs: ")
|
||||
(display prereqs)
|
||||
(newline)
|
||||
(display "; wants-build?: ")
|
||||
(display wants-build?)
|
||||
(newline)
|
||||
(display "; build-func: ")
|
||||
(display build-func)
|
||||
(newline)))))
|
||||
(if (not (null? rcs))
|
||||
(let visit-each-rc ((current-rc (car rcs))
|
||||
(todo-rcs (cdr rcs)))
|
||||
(rc-show current-rc)
|
||||
(if (not (null? todo-rcs))
|
||||
(visit-each-rc (car todo-rcs) (cdr todo-rcs))
|
||||
(begin
|
||||
(display ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n")
|
||||
(display ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n")
|
||||
(newline) (newline) (newline) (newline)))))))
|
||||
|
|
Loading…
Reference in New Issue