mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
157 lines
5.2 KiB
Scheme
Executable file
157 lines
5.2 KiB
Scheme
Executable file
#!/bin/sh
|
||
# aside from this initial boilerplate, this is actually -*- scheme -*- code
|
||
main="(module-ref (resolve-module '(scripts snarf-check-and-output-texi)) 'main)"
|
||
exec ${GUILE-guile} -c "(apply $main (cdr (command-line)))" "$@"
|
||
!#
|
||
;;; snarf-check-and-output-texi --- called by the doc snarfer.
|
||
|
||
;; Copyright (C) 2001 Free Software Foundation, Inc.
|
||
;;
|
||
;; This program is free software; you can redistribute it and/or
|
||
;; modify it under the terms of the GNU General Public License as
|
||
;; published by the Free Software Foundation; either version 2, or
|
||
;; (at your option) any later version.
|
||
;;
|
||
;; This program is distributed in the hope that it will be useful,
|
||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
;; General Public License for more details.
|
||
;;
|
||
;; You should have received a copy of the GNU General Public License
|
||
;; along with this software; see the file COPYING. If not, write to
|
||
;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||
;; Boston, MA 02111-1307 USA
|
||
|
||
;;; Author: Michael Livshin
|
||
|
||
;;; Code:
|
||
|
||
(define-module (scripts snarf-check-and-output-texi)
|
||
:export (snarf-check-and-output-texi))
|
||
|
||
(define *file* #f)
|
||
(define *line* #f)
|
||
(define *function-name* #f)
|
||
(define *snarf-type* #f)
|
||
(define *args* #f)
|
||
(define *sig* #f)
|
||
(define *docstring* #f)
|
||
|
||
(define (doc-block args)
|
||
(let loop ((args args))
|
||
(if (not (null? args))
|
||
(let ((arg (car args)))
|
||
(if (not (null? arg))
|
||
(begin
|
||
|
||
(case (car arg)
|
||
|
||
((fname)
|
||
(set! *function-name* (cdr arg)))
|
||
|
||
((type)
|
||
(set! *snarf-type* (cdr arg)))
|
||
|
||
((location)
|
||
(set! *file* (cadr arg))
|
||
(set! *line* (cddr arg)))
|
||
|
||
((arglist)
|
||
(set! *args* (cdr arg)))
|
||
|
||
((argsig)
|
||
(set! *sig* (cdr arg)))
|
||
|
||
((docstring)
|
||
(set! *docstring* (cdr arg)))
|
||
|
||
(else
|
||
(error (format #f "unknown doc attribute: ~A" (car arg)))))))
|
||
(loop (cdr args)))))
|
||
(output-doc-block))
|
||
|
||
(define (doc-check arg)
|
||
(if (not (null? arg))
|
||
|
||
(case (car arg)
|
||
|
||
((argpos)
|
||
(let* ((name (cadr arg))
|
||
(pos (caddr arg))
|
||
(line (cadddr arg))
|
||
(idx (list-index *args* name)))
|
||
(cond
|
||
((not idx))
|
||
((not (number? pos)))
|
||
((= 0 pos))
|
||
((not (= (+ idx 1) pos))
|
||
(display (format #f "~A:~A: wrong position for argument \"~A\": ~A (should be ~A)\n"
|
||
*file* line name pos (+ idx 1))
|
||
(current-error-port))))))
|
||
|
||
(else
|
||
(error (format #f "unknown check: ~A" (car arg)))))))
|
||
|
||
(define (output-doc-block)
|
||
(let* ((req (car *sig*))
|
||
(opt (cadr *sig*))
|
||
(var (caddr *sig*))
|
||
(all (+ req opt var)))
|
||
(if (and (not (eqv? *snarf-type* 'register))
|
||
(not (= (length *args*) all)))
|
||
(error (format #f "~A:~A: ~A's C implementation takes ~A args (should take ~A)"
|
||
*file* *line* name (length *args*) all)))
|
||
(let ((nice-sig
|
||
(if (eq? *snarf-type* 'register)
|
||
*function-name*
|
||
(with-output-to-string
|
||
(lambda ()
|
||
(format #t "~A" *function-name*)
|
||
(let loop-req ((r 0))
|
||
(if (< r req)
|
||
(begin
|
||
(format #t " ~A" (list-ref *args* r))
|
||
(loop-req (+ 1 r)))
|
||
(begin
|
||
(if (> opt 0)
|
||
(format #t "~A[" (if (> req 0) " " "")))
|
||
(let loop-opt ((o 0) (space #f))
|
||
(if (< o opt)
|
||
(begin
|
||
(format #t "~A~A" (if space " " "")
|
||
(list-ref *args* (+ r o)))
|
||
(loop-opt (+ 1 o) #t))
|
||
(begin
|
||
(if (> opt 0)
|
||
(format #t "]"))
|
||
(if (> var 0)
|
||
(format #t "~A. ~A" (if (< var all) " " "")
|
||
(car (last-pair *args*)))))))))))))))
|
||
(format #t "\n~A\n" *function-name*)
|
||
(format #t "@c snarfed from ~A:~A\n" *file* *line*)
|
||
(format #t "@deffn primitive ~A\n" nice-sig)
|
||
(let loop ((strings *docstring*))
|
||
(if (not (null? strings))
|
||
(begin
|
||
(display (car strings))
|
||
(loop (cdr strings)))))
|
||
(display "\n@end deffn\n"))))
|
||
|
||
(define (snarf-check-and-output-texi)
|
||
(let loop ((form (read)))
|
||
(if (not (eof-object? form))
|
||
(begin
|
||
(if (not (null? form))
|
||
|
||
(case (car form)
|
||
|
||
((doc-block)
|
||
(doc-block (cdr form)))
|
||
|
||
((doc-check)
|
||
(doc-check (cdr form)))
|
||
|
||
(else (error (format #f "unknown doc command: ~A" (car form))))))
|
||
(loop (read))))))
|
||
|
||
(define main snarf-check-and-output-texi)
|