guile-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

guile/guile-core/ice-9 getopt-long.scm


From: Thien-Thi Nguyen
Subject: guile/guile-core/ice-9 getopt-long.scm
Date: Thu, 02 Aug 2001 03:26:52 -0700

CVSROOT:        /cvs
Module name:    guile
Changes by:     Thien-Thi Nguyen <address@hidden>       01/08/02 03:26:52

Modified files:
        guile-core/ice-9: getopt-long.scm 

Log message:
        Refill to fit in 80 columns.
        
        (process-long-option): Fix bug: Keep track of `optional' value-required
        info and use this to determine whether or not the next element is to be
        taken as the option arg.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/guile/guile-core/ice-9/getopt-long.scm.diff?cvsroot=OldCVS&tr1=1.4&tr2=1.5&r1=text&r2=text

Patches:
Index: guile/guile-core/ice-9/getopt-long.scm
diff -u guile/guile-core/ice-9/getopt-long.scm:1.4 
guile/guile-core/ice-9/getopt-long.scm:1.5
--- guile/guile-core/ice-9/getopt-long.scm:1.4  Sun Jun  3 16:29:45 2001
+++ guile/guile-core/ice-9/getopt-long.scm      Thu Aug  2 03:26:52 2001
@@ -1,5 +1,5 @@
 ;;; Author: Russ McManus
-;;; $Id: getopt-long.scm,v 1.4 2001/06/03 23:29:45 mvo Exp $
+;;; $Id: getopt-long.scm,v 1.5 2001/08/02 10:26:52 ttn Exp $
 ;;;
 ;;; Copyright (C) 1998, 2001 Free Software Foundation, Inc.
 ;;;
@@ -190,147 +190,147 @@
 (begin (define
          option-spec->name
          (lambda
-           (obj)
+             (obj)
            (if (option-spec? obj)
                (vector-ref obj 1)
                (slib:error
-                 (quote option-spec->name)
-                 ": bad record"
-                 obj))))
+                (quote option-spec->name)
+                ": bad record"
+                obj))))
        (define
          option-spec->value
          (lambda
-           (obj)
+             (obj)
            (if (option-spec? obj)
                (vector-ref obj 2)
                (slib:error
-                 (quote option-spec->value)
-                 ": bad record"
-                 obj))))
+                (quote option-spec->value)
+                ": bad record"
+                obj))))
        (define
          option-spec->value-required?
          (lambda
-           (obj)
+             (obj)
            (if (option-spec? obj)
                (vector-ref obj 3)
                (slib:error
-                 (quote option-spec->value-required?)
-                 ": bad record"
-                 obj))))
+                (quote option-spec->value-required?)
+                ": bad record"
+                obj))))
        (define
          option-spec->single-char
          (lambda
-           (obj)
+             (obj)
            (if (option-spec? obj)
                (vector-ref obj 4)
                (slib:error
-                 (quote option-spec->single-char)
-                 ": bad record"
-                 obj))))
+                (quote option-spec->single-char)
+                ": bad record"
+                obj))))
        (define
          option-spec->predicate-ls
          (lambda
-           (obj)
+             (obj)
            (if (option-spec? obj)
                (vector-ref obj 5)
                (slib:error
-                 (quote option-spec->predicate-ls)
-                 ": bad record"
-                 obj))))
+                (quote option-spec->predicate-ls)
+                ": bad record"
+                obj))))
        (define
          option-spec->parse-ls
          (lambda
-           (obj)
+             (obj)
            (if (option-spec? obj)
                (vector-ref obj 6)
                (slib:error
-                 (quote option-spec->parse-ls)
-                 ": bad record"
-                 obj))))
+                (quote option-spec->parse-ls)
+                ": bad record"
+                obj))))
        (define
          set-option-spec-name!
          (lambda
-           (obj val)
+             (obj val)
            (if (option-spec? obj)
                (vector-set! obj 1 val)
                (slib:error
-                 (quote set-option-spec-name!)
-                 ": bad record"
-                 obj))))
+                (quote set-option-spec-name!)
+                ": bad record"
+                obj))))
        (define
          set-option-spec-value!
          (lambda
-           (obj val)
+             (obj val)
            (if (option-spec? obj)
                (vector-set! obj 2 val)
                (slib:error
-                 (quote set-option-spec-value!)
-                 ": bad record"
-                 obj))))
+                (quote set-option-spec-value!)
+                ": bad record"
+                obj))))
        (define
          set-option-spec-value-required?!
          (lambda
-           (obj val)
+             (obj val)
            (if (option-spec? obj)
                (vector-set! obj 3 val)
                (slib:error
-                 (quote set-option-spec-value-required?!)
-                 ": bad record"
-                 obj))))
+                (quote set-option-spec-value-required?!)
+                ": bad record"
+                obj))))
        (define
          set-option-spec-single-char!
          (lambda
-           (obj val)
+             (obj val)
            (if (option-spec? obj)
                (vector-set! obj 4 val)
                (slib:error
-                 (quote set-option-spec-single-char!)
-                 ": bad record"
-                 obj))))
+                (quote set-option-spec-single-char!)
+                ": bad record"
+                obj))))
        (define
          set-option-spec-predicate-ls!
          (lambda
-           (obj val)
+             (obj val)
            (if (option-spec? obj)
                (vector-set! obj 5 val)
                (slib:error
-                 (quote set-option-spec-predicate-ls!)
-                 ": bad record"
-                 obj))))
+                (quote set-option-spec-predicate-ls!)
+                ": bad record"
+                obj))))
        (define
          set-option-spec-parse-ls!
          (lambda
-           (obj val)
+             (obj val)
            (if (option-spec? obj)
                (vector-set! obj 6 val)
                (slib:error
-                 (quote set-option-spec-parse-ls!)
-                 ": bad record"
-                 obj))))
+                (quote set-option-spec-parse-ls!)
+                ": bad record"
+                obj))))
        (define
          option-spec?
          (lambda
-           (obj)
+             (obj)
            (and (vector? obj)
                 (= (vector-length obj) 7)
                 (eq? (vector-ref obj 0) (quote option-spec)))))
        (define
          make-option-spec
          (lambda
-           (option-spec->name
-             option-spec->value
-             option-spec->value-required?
-             option-spec->single-char
-             option-spec->predicate-ls
-             option-spec->parse-ls)
+             (option-spec->name
+              option-spec->value
+              option-spec->value-required?
+              option-spec->single-char
+              option-spec->predicate-ls
+              option-spec->parse-ls)
            (vector
-             (quote option-spec)
-             option-spec->name
-             option-spec->value
-             option-spec->value-required?
-             option-spec->single-char
-             option-spec->predicate-ls
-             option-spec->parse-ls))))
+            (quote option-spec)
+            option-spec->name
+            option-spec->value
+            option-spec->value-required?
+            option-spec->single-char
+            option-spec->predicate-ls
+            option-spec->parse-ls))))
 
 
 ;;;
@@ -394,80 +394,102 @@
                      (let ((key (car ls))
                            (val (cadr ls)))
                        (cond ((and (eq? key 'required?) val)
-                              ;; required values are implemented as a predicate
-                              (parse-iter (make-option-spec (option-spec->name 
spec)
-                                                            
(option-spec->value spec)
-                                                            
(option-spec->value-required? spec)
-                                                            
(option-spec->single-char spec)
-                                                            (cons 
(make-option-required-predicate)
-                                                                  
(option-spec->predicate-ls spec))
-                                                            (cdr parse-ls))))
-                             ;; if the value is not required, then don't add a 
predicate,
+                              ;; required values implemented as a predicate
+                              (parse-iter
+                                (make-option-spec
+                                 (option-spec->name spec)
+                                 (option-spec->value spec)
+                                 (option-spec->value-required? spec)
+                                 (option-spec->single-char spec)
+                                 (cons (make-option-required-predicate)
+                                       (option-spec->predicate-ls spec))
+                                 (cdr parse-ls))))
+                             ;; if value not required, don't add predicate,
                              ((eq? key 'required?)
-                              (parse-iter (make-option-spec (option-spec->name 
spec)
-                                                            
(option-spec->value spec)
-                                                            
(option-spec->value-required? spec)
-                                                            
(option-spec->single-char spec)
-                                                            
(option-spec->predicate-ls spec)
-                                                            (cdr parse-ls))))
+                              (parse-iter
+                                (make-option-spec
+                                 (option-spec->name spec)
+                                 (option-spec->value spec)
+                                 (option-spec->value-required? spec)
+                                 (option-spec->single-char spec)
+                                 (option-spec->predicate-ls spec)
+                                 (cdr parse-ls))))
                              ;; handle value specification
                              ((eq? key 'value)
                               (cond ((eq? val #t)
-                                     ;; when value is required, add a 
predicate to that effect
-                                     ;; and record the fact in value-required? 
field.
-                                     (parse-iter (make-option-spec 
(option-spec->name spec)
-                                                                   
(option-spec->value spec)
-                                                                   #t
-                                                                   
(option-spec->single-char spec)
-                                                                   (cons 
(make-required-value-fn)
-                                                                         
(option-spec->predicate-ls spec))
-                                                                   (cdr 
parse-ls))))
+                                     ;; when value is required, add a
+                                     ;; predicate to that effect and record
+                                     ;; the fact in value-required? field.
+                                     (parse-iter
+                                       (make-option-spec
+                                        (option-spec->name spec)
+                                        (option-spec->value spec)
+                                        #t
+                                        (option-spec->single-char spec)
+                                        (cons (make-required-value-fn)
+                                              (option-spec->predicate-ls spec))
+                                        (cdr parse-ls))))
                                     ((eq? val #f)
-                                     ;; when the value is not allowed, add a 
predicate to that effect.
-                                     ;; one can detect that a value is not 
supplied by checking the option
-                                     ;; value against #f.
-                                     (parse-iter (make-option-spec 
(option-spec->name spec)
-                                                                   
(option-spec->value spec)
-                                                                   #f
-                                                                   
(option-spec->single-char spec)
-                                                                   (cons 
(make-not-allowed-value-fn)
-                                                                         
(option-spec->predicate-ls spec))
-                                                                   (cdr 
parse-ls))))
+                                     ;; when the value is not allowed, add a
+                                     ;; predicate to that effect.  one can
+                                     ;; detect that a value is not supplied
+                                     ;; by checking the option value against
+                                     ;; #f.
+                                     (parse-iter
+                                       (make-option-spec
+                                        (option-spec->name spec)
+                                        (option-spec->value spec)
+                                        #f
+                                        (option-spec->single-char spec)
+                                        (cons (make-not-allowed-value-fn)
+                                              (option-spec->predicate-ls spec))
+                                        (cdr parse-ls))))
                                     ((eq? val 'optional)
-                                     ;; for optional values, don't add a 
predicate.  do, however
-                                     ;; put the value 'optional in the 
value-required? field.  this
-                                     ;; setting checks whether optional values 
are 'greedy'.  set
-                                     ;; to #f to make optional value clauses 
'non-greedy'.
-
-                                     (parse-iter (make-option-spec 
(option-spec->name spec)
-                                                                   
(option-spec->value spec)
-                                                                   'optional
-                                                                   
(option-spec->single-char spec)
-                                                                   
(option-spec->predicate-ls spec)
-                                                                   (cdr 
parse-ls))))
+                                     ;; for optional values, don't add a
+                                     ;; predicate.  do, however put the value
+                                     ;; 'optional in the value-required?
+                                     ;; field.  this setting checks whether
+                                     ;; optional values are 'greedy'.  set to
+                                     ;; #f to make optional value clauses
+                                     ;; 'non-greedy'.
+                                     (parse-iter
+                                       (make-option-spec
+                                        (option-spec->name spec)
+                                        (option-spec->value spec)
+                                        'optional
+                                        (option-spec->single-char spec)
+                                        (option-spec->predicate-ls spec)
+                                        (cdr parse-ls))))
                                     (#t
                                      ;; error case
-                                     (error "Bad value specification for 
option:" (cons key val)))))
-                             ;; specify which single char is defined for this 
option.
+                                     (error "Bad value specification for 
option:"
+                                             (cons key val)))))
+                             ;; specify single char defined for this option.
                              ((eq? key 'single-char)
                               (if (not (single-char-value? val))
-                                  (error "Not a single-char-value:" val " for 
option:" key)
-                                  (parse-iter (make-option-spec 
(option-spec->name spec)
-                                                                
(option-spec->value spec)
-                                                                
(option-spec->value-required? spec)
-                                                                val
-                                                                
(option-spec->predicate-ls spec)
-                                                                (cdr 
parse-ls)))))
+                                  (error "Not a single-char-value:"
+                                          val " for option:" key)
+                                  (parse-iter
+                                    (make-option-spec
+                                     (option-spec->name spec)
+                                     (option-spec->value spec)
+                                     (option-spec->value-required? spec)
+                                     val
+                                     (option-spec->predicate-ls spec)
+                                     (cdr parse-ls)))))
                              ((eq? key 'predicate)
                               (if (procedure? val)
-                                  (parse-iter (make-option-spec 
(option-spec->name spec)
-                                                                
(option-spec->value spec)
-                                                                
(option-spec->value-required? spec)
-                                                                
(option-spec->single-char spec)
-                                                                (cons 
(make-user-predicate val)
-                                                                      
(option-spec->predicate-ls spec))
-                                                                (cdr 
parse-ls)))
-                                  (error "Bad predicate specified for option:" 
(cons key val))))))))))))
+                                  (parse-iter
+                                    (make-option-spec
+                                     (option-spec->name spec)
+                                     (option-spec->value spec)
+                                     (option-spec->value-required? spec)
+                                     (option-spec->single-char spec)
+                                     (cons (make-user-predicate val)
+                                           (option-spec->predicate-ls spec))
+                                     (cdr parse-ls)))
+                                  (error "Bad predicate specified for option:"
+                                          (cons key val))))))))))))
     (if (or (not (pair? desc))
            (string? (car desc)))
        (error "Bad option specification:" desc))
@@ -514,26 +536,30 @@
            ((is-short-opt? (car opt-ls))
             (let* ((orig-str (car opt-ls))
                    (match-pair (vector-ref response 2))
-                   (match-str (substring orig-str (car match-pair) (cdr 
match-pair))))
+                   (match-str (substring orig-str (car match-pair)
+                                          (cdr match-pair))))
               (if (= (string-length match-str) 1)
                   (iter (cdr opt-ls)
                         (cons (string-append "-" match-str) ret-ls))
-                  (iter (cons (string-append "-" (substring match-str 1)) (cdr 
opt-ls))
-                        (cons (string-append "-" (substring match-str 0 1)) 
ret-ls)))))
+                  (iter (cons (string-append "-" (substring match-str 1))
+                               (cdr opt-ls))
+                        (cons (string-append "-" (substring match-str 0 1))
+                               ret-ls)))))
            (#t (iter (cdr opt-ls)
                      (cons (car opt-ls) ret-ls)))))
     (iter opt-ls '())))
 
 (define (process-short-option specifications argument-ls alist)
   "Process a single short option that appears at the front of the ARGUMENT-LS,
-according to SPECIFICATIONS.  Returns #f is there is no such argument.  
Otherwise
-returns a pair whose car is the list of remaining arguments, and whose cdr is a
-new association list, constructed by adding a pair to the supplied ALIST.
-The pair on the front of the returned association list describes the  option
-found at the head of ARGUMENT-LS.  The way this routine currently works, an
-option that never takes a value that is followed by a non option will cause
-an error, which is probably a bug.  To fix the bug the option specification
-needs to record whether the option ever can take a value."
+according to SPECIFICATIONS.  Returns #f is there is no such argument.
+Otherwise returns a pair whose car is the list of remaining arguments, and
+whose cdr is a new association list, constructed by adding a pair to the
+supplied ALIST.  The pair on the front of the returned association list
+describes the option found at the head of ARGUMENT-LS.  The way this routine
+currently works, an option that never takes a value that is followed by a non
+option will cause an error, which is probably a bug.  To fix the bug the
+option specification needs to record whether the option ever can take a
+value."
   (define (short-option->char option)
     (string-ref option 1))
   (define (is-short-option? option)
@@ -543,29 +569,36 @@
        (regexp-exec long-opt-no-value-rx option)))
   (define (find-matching-spec option)
     (let ((key (short-option->char option)))
-      (find-if (lambda (spec) (eq? key (option-spec->single-char spec))) 
specifications)))
+      (find-if (lambda (spec)
+                 (eq? key (option-spec->single-char spec))) specifications)))
   (let ((option (car argument-ls)))
     (if (is-short-option? option)
        (let ((spec (find-matching-spec option)))
          (if spec
-             (let* ((next-value (if (null? (cdr argument-ls)) #f (cadr 
argument-ls)))
+             (let* ((next-value (if (null? (cdr argument-ls))
+                                     #f
+                                     (cadr argument-ls)))
                     (option-value (if (and next-value
                                            (not (is-short-option? next-value))
                                            (not (is-long-option? next-value))
                                            (option-spec->value-required? spec))
                                       next-value
                                       #t))
-                    (new-alist (cons (cons (option-spec->name spec) 
option-value) alist)))
+                    (new-alist (cons (cons (option-spec->name spec)
+                                            option-value)
+                                      alist)))
                (cons (if (eq? option-value #t)
-                         (cdr argument-ls)   ; there was one value specified, 
skip just one
-                         (cddr argument-ls)) ; there must have been a value 
specified, skip two
+                         (cdr argument-ls) ; one value, skip just one
+                         (cddr argument-ls)) ; must be a value, skip two
                      new-alist))
              (error "No such option:" option)))
        #f)))
 
 (define (process-long-option specifications argument-ls alist)
   (define (find-matching-spec key)
-    (find-if (lambda (spec) (eq? key (option-spec->name spec))) 
specifications))
+    (find-if (lambda (spec)
+               (eq? key (option-spec->name spec)))
+             specifications))
   (define (split-long-option option)
     ;; returns a pair whose car is a symbol naming the option, cdr is
     ;; the option value.  as a special case, if the option value is
@@ -577,27 +610,50 @@
          ;; Maybe we need to grab a value from argument-ls.  To find
          ;; out we need to refer to the option-spec.
          (let* ((key-pair (vector-ref resp 2))
-                (key (string->symbol (substring option (car key-pair) (cdr 
key-pair))))
+                (key (string->symbol
+                       (substring option (car key-pair) (cdr key-pair))))
                 (spec (find-matching-spec key)))
-           (cons key (if (option-spec->value-required? spec) #f #t)))
+            (let* ((req (option-spec->value-required? spec))
+                   (retval (cons key (if req #f #t))))
+              ;; this is a fucking kludge, i hate it.  it's necessary because
+              ;; the protocol (return #f to indicate next element is an option
+              ;; arg) is insufficient.  needs redesign.  why am i checking in
+              ;; such ugliness?  read moby dick!  -ttn
+              (and (eq? 'optional req)
+                   (set-object-property! retval 'optional #t))
+              retval))
          (let ((resp (regexp-exec long-opt-with-value-rx option)))
            ;; Aha, we've found a long option with an equal sign.  The
            ;; option value is simply the value to the right of the
            ;; equal sign.
            (if resp
                (let* ((key-pair (vector-ref resp 2))
-                      (key (string->symbol (substring option (car key-pair) 
(cdr key-pair))))
+                      (key (string->symbol
+                             (substring option
+                                        (car key-pair) (cdr key-pair))))
                       (value-pair (vector-ref resp 3))
-                      (value (substring option (car value-pair) (cdr 
value-pair))))
+                      (value (substring option
+                                         (car value-pair) (cdr value-pair))))
                  (cons key value))
-                 #f)))))
+                #f)))))
   (let* ((option (car argument-ls))
         (pair (split-long-option option)))
     (cond ((and pair (eq? (cdr pair) #f))
-          (if (null? (cdr argument-ls))
-              (error "Not enough options.")
-              (cons (cddr argument-ls)
-                    (cons (cons (car pair) (cadr argument-ls)) alist))))
+           (cond ((and (null? (cdr argument-ls))
+                       (not (object-property pair 'optional)))
+                  (error "Not enough options."))
+                 ((null? (cdr argument-ls))
+                  (cons '() (cons (cons (car pair) #t) alist)))
+                 ((let* ((next (cadr argument-ls))
+                         (m (or (regexp-exec short-opt-rx next)
+                                (regexp-exec long-opt-with-value-rx next)
+                                (regexp-exec long-opt-no-value-rx next))))
+                    (and m (object-property pair 'optional)))
+                  (cons (cdr argument-ls)
+                        (cons (cons (car pair) #t) alist)))
+                 (else
+                  (cons (cddr argument-ls)
+                        (cons (cons (car pair) (cadr argument-ls)) alist)))))
          (pair
           (cons (cdr argument-ls) (cons pair alist)))
          (else #f))))
@@ -611,7 +667,8 @@
              (let ((argument-ls (car pair))
                    (alist (cdr pair)))
                (iter argument-ls alist rest-ls))
-             (let ((pair (process-long-option specifications argument-ls 
alist)))
+             (let ((pair (process-long-option
+                           specifications argument-ls alist)))
                (if pair
                    (let ((argument-ls (car pair))
                          (alist (cdr pair)))
@@ -659,11 +716,12 @@
     (let* ((opt-pair (process-options specifications split-ls))
           (alist (car opt-pair))
           (rest-ls (append (cdr opt-pair) non-split-ls)))
-      ;; loop through the returned alist, and set the values into the 
specifications
+      ;; loop through returned alist, set values into specifications
       (for-each (lambda (pair)
                  (let* ((key (car pair))
                         (val (cdr pair))
-                        (spec (find-if (lambda (spec) (eq? key 
(option-spec->name spec)))
+                        (spec (find-if (lambda (spec)
+                                          (eq? key (option-spec->name spec)))
                                        specifications)))
                    (if spec (set-option-spec-value! spec val))))
                alist)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]