;;;; ;;;; getopt.stk -- getopt ;;;; ;;;; Copyright © 2001-2011 Erick Gallesio - I3S-CNRS/ESSI ;;;; ;;;; ;;;; 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 of the License, 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 program; if not, write to the Free Software ;;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ;;;; USA. ;;;; ;;;; Author: Erick Gallesio [eg@unice.fr] ;;;; Creation date: 26-Oct-2001 08:40 (eg) ;;;; Last file update: 27-Jul-2011 22:53 (eg) ;;;; ;;;; ;;;; %PRINT--USAGE ;;;; ;;;; pretty print options usage ;;;; #| |# (define (%print-usage port clauses sexpr) (define (make-line-info l) (let ((opt (car l)) (help (key-get (cdr l) :help #f)) (alt (key-get (cdr l) :alternate #f)) (arg (key-get (cdr l) :arg #f)) (pretty (lambda (s arg) (let ((long? (> (string-length s) 1))) (string-append (if long? "--" "-") s (if arg (string-append (if long? "=<" " <") (symbol->string arg) ">") "")))))) (if help ; We have an help string, return something like ("--long, -l" . "help") (cons (if alt (format #f "~A, ~A" (pretty opt arg) (pretty alt arg)) (format #f "~A" (pretty opt arg))) help) ; No help string '()))) (define (print-as-sexpr clauses) (format port "(\n") (for-each (lambda (x) (when (and (pair? x) (pair? (car x))) (let ((info (make-line-info (car x)))) (format port "(~S ~S)\n" (car info) (cdr info))))) clauses) (format port ")\n")) ;; ;; functions starts here ;; (if sexpr ;; print usage as a sexpr (print-as-sexpr clauses) ;; Pretty print the options on given port (let* ((lines (map (lambda (clause) (cond ((string? clause) clause) ((pair? (car clause)) (make-line-info (car clause))) (else #f))) clauses)) (len (apply max (map (lambda (x) (if (pair? x) (string-length (car x)) 0)) lines)))) ;; lines contains the line to be displayed and len is the length of the ;; longest option. Pretty print the options from those values (for-each (lambda (x) (cond ((pair? x) (format port " ~A~A ~A\n" (car x) (make-string (- len (string-length (car x))) #\space) (cdr x))) ((string? x) (format port "~A\n" x)))) lines)))) ;;;; ;;;; PARSE-ARGUMENTS ;;;; ;;;; Do argument parsing using GNU getopt ;;;; #| ...) * * The |parse-arguments| special form is used to parse the * command line arguments of a Scheme script. The implementation of * this form internally uses the GNU C |getopt| function. As a * consequence |parse-arguments| accepts options which start with * the '-' (short option) or '--' characters (long option). * ,(linebreak) * The first argument of |parse-arguments| is a list of the arguments * given to the program (comprising the program name in the CAR of this * list). Following arguments are clauses. Clauses are described later. * ,(linebreak) * By default, |parse-arguments| permutes the contents of (a copy) of * the arguments as it scans, so that eventually all the non-options are * at the end. However, if the shell environment variable |POSIXLY_CORRECT| * is set, then option processing stops as soon as a non-option argument * is encountered. * ,(linebreak) * A clause must follow the syntax: * ,(raw-code [ * => string @pipe * => (