- (with-gensyms (topt targ tparser)
- (flet ((frob (clause)
- (destructuring-bind
- (case (&optional arg) &rest forms)
- clause
- (and case
- (list `(,case ,@(if arg
- `(let ((,arg ,targ)) ,@forms)
- forms)))))))
- `(let ((,tparser ,parser))
- (loop
- (multiple-value-bind (,topt ,targ) (option-parse-next ,tparser)
- (declare (ignorable ,targ))
- (unless ,topt (return))
- (case ,topt
- ,@(mapcan #'frob clauses))))
- ,@(let ((tail (find nil clauses :key #'car)))
- (and tail
- (destructuring-bind
- ((&optional arg) &rest forms)
- (cdr tail)
- (list (if arg
- `(let ((,arg (option-parse-remainder
- ,tparser)))
- ,@forms)
- forms)))))))))
+ "Handy all-in-one options parser macro. PARSER defaults to a new options
+ parser using the preset default options structure. The CLAUSES are
+ `case2'-like clauses to match options, and must be exhaustive. If there
+ is a clause (nil (REST) FORMS...) then the FORMS are evaluated after
+ parsing is done with REST bound to the remaining command-line arguments."
+ (with-gensyms (tparser)
+ `(let ((,tparser ,parser))
+ (loop
+ (,(if (find t clauses :key #'car) 'case2 'ecase2)
+ (option-parse-next ,tparser)
+ ((nil) () (return))
+ ,@(remove-if #'null clauses :key #'car)))
+ ,@(let ((tail (find nil clauses :key #'car)))
+ (and tail
+ (destructuring-bind ((&optional arg) &rest forms) (cdr tail)
+ (if arg
+ (list `(let ((,arg (option-parse-remainder ,tparser)))
+ ,@forms))
+ forms)))))))