2 # aside from this initial boilerplate, this is actually -*- scheme -*- code
3 main
='(module-ref (resolve-module '\''(scripts autofrisk)) '\'main
')'
4 exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@"
6 ;;; autofrisk
--- Generate module checks
for use with auto
* tools
8 ;; Copyright
(C
) 2002 Free Software Foundation
, Inc.
10 ;; This program is free software
; you can redistribute it and
/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation
; either version
2, or
13 ;; (at your option
) any later version.
15 ;; This program is distributed
in the hope that it will be useful
,
16 ;; but WITHOUT ANY WARRANTY
; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License
for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with this software
; see the
file COPYING. If not
, write to
22 ;; the Free Software Foundation
, Inc.
, 59 Temple Place
, Suite
330,
23 ;; Boston
, MA
02111-1307 USA
25 ;;; Author
: Thien-Thi Nguyen
<ttn@gnu.org
>
29 ;; Usage
: autofrisk
[file]
31 ;; This program looks
for the
file modules.af
in the current directory
32 ;; and writes out modules.af.
m4 containing autoconf definitions.
33 ;; If given
, look for FILE instead of modules.af and output to FILE.
m4.
35 ;; After running autofrisk
, you should add to configure.ac the lines
:
38 ;; Then run
"aclocal -I ." to update aclocal.
m4, and finally autoconf.
40 ;; The modules.af
file consists of a series of configuration forms
(Scheme
41 ;; lists
), which have one of the following formats
:
42 ;; (files-glob PATTERN ...
)
43 ;; (non-critical-external MODULE ...
)
44 ;; (non-critical-internal MODULE ...
)
45 ;; (programs
(MODULE PROG ...
) ...
)
46 ;; (pww-varname VARNAME
)
47 ;; PATTERN is a string that may contain
"*" and
"?" characters to be
48 ;; expanded into filenames. MODULE is a list of symbols naming a
49 ;; module
, such as
`(srfi srfi-1)'. VARNAME is a shell-safe name to use
50 ;; instead of "probably_wont_work", the default. This var is passed to
51 ;; `AC_SUBST
'. PROG is a string.
53 ;; Only the `files-glob' form is required.
55 ;; TODO
: Write better commentary.
56 ;; Make
"please see README" configurable.
60 (define-module
(scripts autofrisk
)
61 :autoload
(ice-9 popen
) (open-input-pipe
)
62 :use-module
(srfi srfi-1
)
63 :use-module
(srfi srfi-8
)
64 :use-module
(srfi srfi-13
)
65 :use-module
(srfi srfi-14
)
66 :use-module
(scripts read-scheme-source
)
67 :use-module
(scripts frisk
)
70 (define
*recognized-keys
* '(files-glob
76 (define (canonical-configuration forms)
77 (let ((chk (lambda (condition . x)
78 (or condition (apply error "syntax error:" x)))))
79 (chk (list? forms) "input not a list")
80 (chk (every list? forms) "non-list element")
81 (chk (every (lambda (form) (< 1 (length form))) forms) "list too short")
83 (chk (every (lambda (form)
84 (let ((key (car form)))
87 (memq key
*recognized-keys
*)
92 "unrecognized key:" un
))
93 (let ((bunched
(map
(lambda
(key
)
94 (fold (lambda
(form so-far
)
95 (or
(and
(eq?
(car form
) key
)
97 (append so-far
(cdr form
)))
103 (assq-ref bunched key
)))))
105 (define
(>>strong modules
)
106 (for-each
(lambda
(module
)
107 (format
#t "GUILE_MODULE_REQUIRED~A\n" module))
110 (define
(safe-name module
)
111 (let ((var
(object-
>string module
)))
112 (string-map
! (lambda
(c
)
113 (if (char-set-contains? char-set
:letter
+digit c
)
119 (define
*pww
* "probably_wont_work")
121 (define
(>>weak weak-edges
)
122 (for-each
(lambda
(edge
)
123 (let* ((up
(edge-up edge
))
124 (down
(edge-down edge
))
125 (var
(format
#f "have_guile_module~A" (safe-name up))))
126 (format
#t "GUILE_MODULE_AVAILABLE(~A, ~A)\n" var up)
127 (format
#t "test \"$~A\" = no &&\n ~A=\"~A $~A\"~A"
128 var
*pww
* down
*pww
* "\n\n")))
131 (define
(>>program module progs
)
132 (let ((vars
(map
(lambda
(prog
)
133 (format
#f "guile_module~Asupport_~A"
137 (for-each
(lambda
(var prog
)
138 (format
#t "AC_PATH_PROG(~A, ~A)\n" var prog))
140 (format
#t "test \\\n")
141 (for-each
(lambda
(var
)
142 (format
#t " \"$~A\" = \"\" -o \\\n" var))
144 (format
#t "~A &&\n~A=\"~A $~A\"\n\n"
145 (list-ref
(list
"war = peace"
147 "ignorance = strength")
149 *pww
* module
*pww
*)))
151 (define
(>>programs programs
)
152 (for-each
(lambda
(form
)
153 (>>program
(car form
) (cdr form
)))
156 (define
(unglob pattern
)
157 (let ((p
(open-input-pipe
(format
#f "echo '(' ~A ')'" pattern))))
158 (map symbol-
>string
(read p
))))
160 (define
(>>checks forms
)
161 (let* ((cfg
(canonical-configuration forms
))
162 (files
(apply append
(map unglob
(cfg
'files-glob))))
163 (ncx (cfg 'non-critical-external
))
164 (nci
(cfg
'non-critical-internal))
165 (prog (cfg 'non-critical
))
166 (report
((make-frisker
) files
))
167 (external
(report
'external)))
168 (let ((pww-varname (cfg 'pww-varname
)))
169 (or
(null? pww-varname
) (set! *pww
* (car pww-varname
))))
170 (receive
(weak strong
)
171 (partition
(lambda
(module
)
172 (or
(member module ncx
)
175 (map edge-down
(mod-down-ls module
)))))
177 (format
#t "AC_DEFUN([AUTOFRISK_CHECKS],[\n\n")
179 (format
#t "\n~A=~S\n\n" *pww* "")
180 (>>weak
(fold (lambda
(module so-far
)
181 (append so-far
(mod-down-ls module
)))
184 (>>programs
(cfg
'programs))
185 (format #t "AC_SUBST(~A)\n])\n\n" *pww*))))
191 AC_DEFUN
([AUTOFRISK_SUMMARY
],[
192 if test ! "$~A" = "" ; then
196 echo "$p The following modules probably won't work:"
198 echo "$p They can be installed anyway, and will work if their"
199 echo "$p dependencies are installed later. Please see README."
206 (define
(autofrisk . args
)
207 (let ((file (if (null? args
) "modules.af" (car args
))))
208 (or
(file-exists?
file)
209 (error
"could not find input file:" file))
210 (with-output-to-file
(format
#f "~A.m4" file)
212 (>>checks
(read-scheme-source-silently
file))
215 (define main autofrisk
)
218 ;; eval: (put
'receive 'scheme-indent-function
2)
221 ;;; autofrisk ends here