~peter-pearse/ubuntu/natty/guile-1.8/prop001

« back to all changes in this revision

Viewing changes to scripts/snarf-check-and-output-texi

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Schepler
  • Date: 2006-11-09 03:11:16 UTC
  • Revision ID: james.westby@ubuntu.com-20061109031116-hu0q1jxqg12y6yeg
Tags: upstream-1.8.1+1
ImportĀ upstreamĀ versionĀ 1.8.1+1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/sh
 
2
# aside from this initial boilerplate, this is actually -*- scheme -*- code
 
3
main="(module-ref (resolve-module '(scripts snarf-check-and-output-texi)) 'main)"
 
4
exec ${GUILE-guile} -l $0 -c "(apply $main (cdr (command-line)))" "$@"
 
5
!#
 
6
;;; snarf-check-and-output-texi --- called by the doc snarfer.
 
7
 
 
8
;;      Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
 
9
;;
 
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.
 
14
;;
 
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.
 
19
;;
 
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., 51 Franklin Street, Fifth Floor,
 
23
;; Boston, MA 02110-1301 USA
 
24
 
 
25
;;; Author: Michael Livshin
 
26
 
 
27
;;; Code:
 
28
 
 
29
(define-module (scripts snarf-check-and-output-texi)
 
30
    :use-module (ice-9 streams)
 
31
    :use-module (ice-9 match)
 
32
    :export (snarf-check-and-output-texi))
 
33
 
 
34
;;; why aren't these in some module?
 
35
 
 
36
(define-macro (when cond . body)
 
37
  `(if ,cond (begin ,@body)))
 
38
 
 
39
(define-macro (unless cond . body)
 
40
  `(if (not ,cond) (begin ,@body)))
 
41
 
 
42
(define *manual-flag* #f)
 
43
 
 
44
(define (snarf-check-and-output-texi . flags)
 
45
  (if (member "--manual" flags)
 
46
      (set! *manual-flag* #t))
 
47
  (process-stream (current-input-port)))
 
48
 
 
49
(define (process-stream port)
 
50
  (let loop ((input (stream-map (match-lambda
 
51
                                 (('id . s)
 
52
                                  (cons 'id (string->symbol s)))
 
53
                                 (('int_dec . s)
 
54
                                  (cons 'int (string->number s)))
 
55
                                 (('int_oct . s)
 
56
                                  (cons 'int (string->number s 8)))
 
57
                                 (('int_hex . s)
 
58
                                  (cons 'int (string->number s 16)))
 
59
                                 ((and x (? symbol?))
 
60
                                  (cons x x))
 
61
                                 ((and x (? string?))
 
62
                                  (cons 'string x))
 
63
                                 (x x))
 
64
                                (make-stream (lambda (s)
 
65
                                               (let loop ((s s))
 
66
                                                 (cond
 
67
                                                   ((stream-null? s) #t)
 
68
                                                   ((eq? 'eol (stream-car s))
 
69
                                                    (loop (stream-cdr s)))
 
70
                                                   (else (cons (stream-car s) (stream-cdr s))))))
 
71
                                             (port->stream port read)))))
 
72
 
 
73
    (unless (stream-null? input)
 
74
      (let ((token (stream-car input)))
 
75
        (if (eq? (car token) 'snarf_cookie)
 
76
          (dispatch-top-cookie (stream-cdr input)
 
77
                               loop)
 
78
          (loop (stream-cdr input)))))))
 
79
 
 
80
(define (dispatch-top-cookie input cont)
 
81
 
 
82
  (when (stream-null? input)
 
83
    (error 'syntax "premature end of file"))
 
84
 
 
85
  (let ((token (stream-car input)))
 
86
    (cond
 
87
      ((eq? (car token) 'brace_open)
 
88
       (consume-multiline (stream-cdr input)
 
89
                          cont))
 
90
      (else
 
91
       (consume-upto-cookie process-singleline
 
92
                            input
 
93
                            cont)))))
 
94
 
 
95
(define (consume-upto-cookie process input cont)
 
96
  (let loop ((acc '()) (input input))
 
97
 
 
98
    (when (stream-null? input)
 
99
      (error 'syntax "premature end of file in directive context"))
 
100
 
 
101
    (let ((token (stream-car input)))
 
102
      (cond
 
103
        ((eq? (car token) 'snarf_cookie)
 
104
         (process (reverse! acc))
 
105
         (cont (stream-cdr input)))
 
106
 
 
107
        (else (loop (cons token acc) (stream-cdr input)))))))
 
108
 
 
109
(define (consume-multiline input cont)
 
110
  (begin-multiline)
 
111
 
 
112
  (let loop ((input input))
 
113
 
 
114
    (when (stream-null? input)
 
115
      (error 'syntax "premature end of file in multiline context"))
 
116
 
 
117
    (let ((token (stream-car input)))
 
118
      (cond
 
119
        ((eq? (car token) 'brace_close)
 
120
         (end-multiline)
 
121
         (cont (stream-cdr input)))
 
122
 
 
123
        (else (consume-upto-cookie process-multiline-directive
 
124
                                   input
 
125
                                   loop))))))
 
126
 
 
127
(define *file* #f)
 
128
(define *line* #f)
 
129
(define *c-function-name* #f)
 
130
(define *function-name* #f)
 
131
(define *snarf-type* #f)
 
132
(define *args* #f)
 
133
(define *sig* #f)
 
134
(define *docstring* #f)
 
135
 
 
136
(define (begin-multiline)
 
137
  (set! *file* #f)
 
138
  (set! *line* #f)
 
139
  (set! *c-function-name* #f)
 
140
  (set! *function-name* #f)
 
141
  (set! *snarf-type* #f)
 
142
  (set! *args* #f)
 
143
  (set! *sig* #f)
 
144
  (set! *docstring* #f))
 
145
 
 
146
(define *primitive-deffnx-signature* "@deffnx {Scheme Procedure} ")
 
147
(define *primitive-deffnx-sig-length* (string-length *primitive-deffnx-signature*))
 
148
 
 
149
(define (end-multiline)
 
150
  (let* ((req (car *sig*))
 
151
         (opt (cadr *sig*))
 
152
         (var (caddr *sig*))
 
153
         (all (+ req opt var)))
 
154
    (if (and (not (eqv? *snarf-type* 'register))
 
155
             (not (= (length *args*) all)))
 
156
      (error (format #f "~A:~A: ~A's C implementation takes ~A args (should take ~A)"
 
157
             *file* *line* *function-name* (length *args*) all)))
 
158
    (let ((nice-sig
 
159
            (if (eq? *snarf-type* 'register)
 
160
              *function-name*
 
161
              (with-output-to-string
 
162
                (lambda ()
 
163
                  (format #t "~A" *function-name*)
 
164
                  (let loop-req ((args *args*) (r 0))
 
165
                    (if (< r req)
 
166
                      (begin
 
167
                       (format #t " ~A" (car args))
 
168
                       (loop-req (cdr args) (+ 1 r)))
 
169
                      (let loop-opt ((o 0) (args args) (tail '()))
 
170
                       (if (< o opt)
 
171
                         (begin
 
172
                          (format #t " [~A" (car args))
 
173
                          (loop-opt (+ 1 o) (cdr args) (cons #\] tail)))
 
174
                         (begin
 
175
                          (if (> var 0)
 
176
                            (format #t " . ~A"
 
177
                                    (car args)))
 
178
                          (let loop-tail ((tail tail))
 
179
                               (if (not (null? tail))
 
180
                                 (begin
 
181
                                  (format #t "~A" (car tail))
 
182
                                  (loop-tail (cdr tail))))))))))))))
 
183
          (scm-deffnx
 
184
            (if (and *manual-flag* (eq? *snarf-type* 'primitive))
 
185
                (with-output-to-string
 
186
                  (lambda ()
 
187
                    (format #t "@deffnx {C Function} ~A (" *c-function-name*)
 
188
                    (unless (null? *args*)
 
189
                      (format #t "~A" (car *args*))
 
190
                      (let loop ((args (cdr *args*)))
 
191
                        (unless (null? args)
 
192
                          (format #t ", ~A" (car args))
 
193
                          (loop (cdr args)))))
 
194
                    (format #t ")\n")))
 
195
                #f)))
 
196
      (format #t "\n ~A\n" *function-name*)
 
197
      (format #t "@c snarfed from ~A:~A\n" *file* *line*)
 
198
      (format #t "@deffn {Scheme Procedure} ~A\n" nice-sig)
 
199
      (let loop ((strings *docstring*) (scm-deffnx scm-deffnx))
 
200
        (cond ((null? strings))
 
201
              ((or (not scm-deffnx)
 
202
                   (and (>= (string-length (car strings))
 
203
                            *primitive-deffnx-sig-length*)
 
204
                        (string=? (substring (car strings)
 
205
                                             0 *primitive-deffnx-sig-length*)
 
206
                                  *primitive-deffnx-signature*)))
 
207
               (display (car strings))
 
208
               (loop (cdr strings) scm-deffnx))
 
209
              (else (display scm-deffnx)
 
210
                    (loop strings #f))))
 
211
      (display "\n")
 
212
      (display "@end deffn\n"))))
 
213
 
 
214
(define (texi-quote s)
 
215
  (let rec ((i 0))
 
216
    (if (= i (string-length s))
 
217
      ""
 
218
      (string-append (let ((ss (substring s i (+ i 1))))
 
219
                       (if (string=? ss "@")
 
220
                         "@@"
 
221
                         ss))
 
222
                     (rec (+ i 1))))))
 
223
 
 
224
(define (process-multiline-directive l)
 
225
 
 
226
  (define do-args
 
227
    (match-lambda
 
228
 
 
229
     (('(paren_close . paren_close))
 
230
      '())
 
231
 
 
232
     (('(comma . comma) rest ...)
 
233
      (do-args rest))
 
234
 
 
235
     (('(id . SCM) ('id . name) rest ...)
 
236
      (cons name (do-args rest)))
 
237
 
 
238
     (x (error (format #f "invalid argument syntax: ~A" (map cdr x))))))
 
239
 
 
240
  (define do-arglist
 
241
    (match-lambda
 
242
 
 
243
     (('(paren_open . paren_open) '(id . void) '(paren_close . paren_close))
 
244
      '())
 
245
 
 
246
     (('(paren_open . paren_open) rest ...)
 
247
      (do-args rest))
 
248
 
 
249
     (x (error (format #f "invalid arglist syntax: ~A" (map cdr x))))))
 
250
 
 
251
  (define do-command
 
252
    (match-lambda
 
253
 
 
254
     (('cname ('id . name))
 
255
      (set! *c-function-name* (texi-quote (symbol->string name))))
 
256
 
 
257
     (('fname ('string . name) ...)
 
258
      (set! *function-name* (texi-quote (apply string-append name))))
 
259
 
 
260
     (('type ('id . type))
 
261
      (set! *snarf-type* type))
 
262
 
 
263
     (('type ('int . num))
 
264
      (set! *snarf-type* num))
 
265
 
 
266
     (('location ('string . file) ('int . line))
 
267
      (set! *file* file)
 
268
      (set! *line* line))
 
269
 
 
270
     (('arglist rest ...)
 
271
      (set! *args* (do-arglist rest)))
 
272
 
 
273
     (('argsig ('int . req) ('int . opt) ('int . var))
 
274
      (set! *sig* (list req opt var)))
 
275
 
 
276
     (x (error (format #f "unknown doc attribute: ~A" x)))))
 
277
 
 
278
  (define do-directive
 
279
    (match-lambda
 
280
 
 
281
     ((('id . command) rest ...)
 
282
      (do-command (cons command rest)))
 
283
 
 
284
     ((('string . string) ...)
 
285
      (set! *docstring* string))
 
286
 
 
287
     (x (error (format #f "unknown doc attribute syntax: ~A" x)))))
 
288
 
 
289
  (do-directive l))
 
290
 
 
291
(define (process-singleline l)
 
292
 
 
293
  (define do-argpos
 
294
    (match-lambda
 
295
     ((('id . name) ('int . pos) ('int . line))
 
296
      (let ((idx (list-index *args* name)))
 
297
        (when idx
 
298
          (unless (= (+ idx 1) pos)
 
299
            (display (format #f "~A:~A: wrong position for argument ~A: ~A (should be ~A)\n"
 
300
                             *file* line name pos (+ idx 1))
 
301
                     (current-error-port))))))
 
302
     (x #f)))
 
303
 
 
304
  (define do-command
 
305
    (match-lambda
 
306
     (('(id . argpos) rest ...)
 
307
      (do-argpos rest))
 
308
     (x (error (format #f "unknown check: ~A" x)))))
 
309
 
 
310
  (when *function-name*
 
311
    (do-command l)))
 
312
 
 
313
(define main snarf-check-and-output-texi)