* fspec2c 1.0
@ 2003-11-04 2:11 Thien-Thi Nguyen
0 siblings, 0 replies; only message in thread
From: Thien-Thi Nguyen @ 2003-11-04 2:11 UTC (permalink / raw)
Cc: guile-user
this may make it into the guile 1.4.x scripts collection if i can
generalize it enough. "flag"-specific because enum values tend to be
linear so simpler methods are indicated for reverse-mapping them. at
least, this is true for /usr/include/SDL/*.h enums and flags. who knows
for other header domains? what a mess, the terminology of programmers!
if any gperf hackers are reading this: thanks for writing gperf.
it was worth installing g++ to compile 3.0.1, for "--output-file".
i will post a sample FSPEC file next.
thi
______________________________________________________________________________
#!/bin/sh
exec ${GUILE-guile} -e "(guile-sdl scripts fspec2c)" -s $0 "$@" # -*-scheme-*-
!#
;;; fspec2c --- translate flag spec to C code
;; Copyright (C) 2003 Thien-Thi Nguyen
;;
;; 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
;;; Commentary:
;; Usage: fspec2c [OPTIONS] FSPEC
;;
;; Write C fragment to stdout derived from running gperf (GNU perfect hash
;; function generator) on the flags mined from the header as specified in
;; FSPEC. OPTIONS are zero or more of:
;;
;; -o, --output FILE -- write to FILE instead of stdout
;; -I, --include DIR -- look in DIR instead of /usr/include
;; -n, --no-cgen -- write generated gperf input instead
;; of actually sending it to gperf
;;
;; The FSPEC file contents is a Scheme list with alternating keyword and data
;; elements. Currently, these keywords are recognized:
;;
;; #:infile RELPATH -- which header to scan (string)
;; #:regexp REGEXP -- regexp w/ at least one subexpression (string)
;; #:key-match-num NUM -- which subexpression is the key
;; #:struct SPEC -- struct-member specifiers (list, see below)
;; #:struct-name NAME -- for "struct NAME { ... }" (string)
;; #:gperf-options OPT -- additional options for gperf (string)
;; #:pre-boilerplate S -- gperf "%{ ... %}" declarations (symbol, see below)
;; #:post-boilerplate S -- direct C inclusion (symbol, see below)
;;
;; SPEC is a list of struct-member specifiers, each a list of the form:
;;
;; (MATCH C-TYPE-COMPONENT-1 [C-TYPE-COMPONENT-2 ...] C-VAR-NAME)
;;
;; MATCH can be a number to specify a subexpression of REGEXP to use for
;; static-data initialization, or #f to indicate no initialization. Per info
;; node "(gperf)User-supplied Struct", the first element of SPEC must be:
;;
;; (1 char * name)
;;
;; This restriction may be lifted in the future, as fspec2c is enhanced to
;; interoperate better with those features of gperf that allow customization
;; of this struct element.
;;
;; The #:pre-boilerplate and #:post-boilerplate data elements are symbols
;; rather than strings, in order to minimize quoting headaches. Such symbols
;; have the syntax: #{ TEXT }# where TEXT can include anything (including
;; spaces, newlines, and quote characters) except the closing curly-brace-hash
;; token. Boilerplate text is passed straight-through by both fspec2c and
;; gperf; errors in the code will only be flagged during compilation.
;;; Code:
(define-module (guile-sdl scripts fspec2c)
#:use-module (scripts PROGRAM)
#:use-module (ice-9 rdelim)
#:use-module (ice-9 regex)
#:autoload (ice-9 popen) (open-output-pipe))
(define (fspec2c/qop qop)
(let* ((info (read (open-input-file
(let ((args (qop '())))
(or (and (pair? args) (car args))
(error "no input specified"))))))
(spec (lambda (kw) (and=> (memq kw info) cadr)))
(gperf-input '()))
(let* ((p (open-input-file (in-vicinity
(or (qop 'include) "/usr/include")
(spec #:infile))))
(rx (make-regexp (spec #:regexp))))
(let loop ((line (read-line p)))
(or (eof-object? line)
(begin
(cond ((regexp-exec rx line)
=> (lambda (m)
(set! gperf-input (cons m gperf-input)))))
(loop (read-line p)))))
(close-port p))
;; feed gperf (unless --no-cgen)
(let* ((kw-num (spec #:key-match-num))
(struct (or (spec #:struct) '()))
(op (if (qop 'no-cgen)
(or (qop 'output open-output-file)
(current-output-port))
(open-output-pipe
(format #f "gperf~A~A --output-file=~A"
(if (null? struct) "" " -t")
(cond ((spec #:gperf-options)
=> (lambda (o) (format #f " ~A" o)))
(else ""))
(or (qop 'output) "-"))))))
(cond ((spec #:pre-boilerplate)
=> (lambda (x)
(display "%{\n" op)
(display (symbol->string x) op)
(display "\n%}\n" op))))
(cond ((null? struct))
(else
(format op "struct ~A {" (or (spec #:struct-name)
"randomstructname"))
(for-each (lambda (x)
(for-each (lambda (xx)
(format op " ~A" xx))
(cdr x))
(format op ";"))
struct)
(format op " };\n%%\n")))
(for-each (lambda (m)
(display (match:substring m kw-num) op)
(for-each (lambda (x)
(and=> (car x)
(lambda (num)
(format op ", ~A"
(match:substring m num)))))
;; 1st fixed; see "(gperf)User-supplied Struct"
(cdr struct))
(newline op))
gperf-input)
(cond ((spec #:post-boilerplate)
=> (lambda (x)
(display "%%\n" op)
(display (symbol->string x) op))))
(or (eq? op (current-output-port))
(close-port op)))
#t))
(define (main args)
(HVQC-MAIN args fspec2c/qop
'(usage . commentary)
'(package . "guile-sdl")
'(version . "1.0")
'(option-spec (output (single-char #\o) (value #t))
(include (single-char #\I) (value #t))
(no-cgen (single-char #\n)))))
;;; fspec2c ends here
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-11-04 2:11 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-11-04 2:11 fspec2c 1.0 Thien-Thi Nguyen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).