⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getopt-long.scm

📁 MSYS在windows下模拟了一个类unix的终端
💻 SCM
📖 第 1 页 / 共 2 页
字号:
;;; Copyright (C) 1998, 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 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;;;;;; As a special exception, the Free Software Foundation gives permission;;; for additional uses of the text contained in its release of GUILE.;;;;;; The exception is that, if you link the GUILE library with other files;;; to produce an executable, this does not by itself cause the;;; resulting executable to be covered by the GNU General Public License.;;; Your use of that executable is in no way restricted on account of;;; linking the GUILE library code into it.;;;;;; This exception does not however invalidate any other reasons why;;; the executable file might be covered by the GNU General Public License.;;;;;; This exception applies only to the code released by the;;; Free Software Foundation under the name GUILE.  If you copy;;; code from other Free Software Foundation releases into a copy of;;; GUILE, as the General Public License permits, the exception does;;; not apply to the code that you add in this way.  To avoid misleading;;; anyone as to the status of such modified files, you must delete;;; this exception notice from them.;;;;;; If you write modifications of your own for GUILE, it is your choice;;; whether to permit this exception to apply to your modifications.;;; If you do not wish that, delete this exception notice.;;; Author: Russ McManus (rewritten by Thien-Thi Nguyen);;; Commentary:;;; This module implements some complex command line option parsing, in;;; the spirit of the GNU C library function `getopt_long'.  Both long;;; and short options are supported.;;;;;; The theory is that people should be able to constrain the set of;;; options they want to process using a grammar, rather than some arbitrary;;; structure.  The grammar makes the option descriptions easy to read.;;;;;; `getopt-long' is a procedure for parsing command-line arguments in a;;; manner consistent with other GNU programs.  `option-ref' is a procedure;;; that facilitates processing of the `getopt-long' return value.;;; (getopt-long ARGS GRAMMAR);;; Parse the arguments ARGS according to the argument list grammar GRAMMAR.;;;;;; ARGS should be a list of strings.  Its first element should be the;;; name of the program; subsequent elements should be the arguments;;; that were passed to the program on the command line.  The;;; `program-arguments' procedure returns a list of this form.;;;;;; GRAMMAR is a list of the form:;;; ((OPTION (PROPERTY VALUE) ...) ...);;;;;; Each OPTION should be a symbol.  `getopt-long' will accept a;;; command-line option named `--OPTION'.;;; Each option can have the following (PROPERTY VALUE) pairs:;;;;;;   (single-char CHAR) --- Accept `-CHAR' as a single-character;;;		equivalent to `--OPTION'.  This is how to specify traditional;;;		Unix-style flags.;;;   (required? BOOL) --- If BOOL is true, the option is required.;;;		getopt-long will raise an error if it is not found in ARGS.;;;   (value BOOL) --- If BOOL is #t, the option accepts a value; if;;;		it is #f, it does not; and if it is the symbol;;;		`optional', the option may appear in ARGS with or;;;		without a value.;;;   (predicate FUNC) --- If the option accepts a value (i.e. you;;;		specified `(value #t)' for this option), then getopt;;;		will apply FUNC to the value, and throw an exception;;;		if it returns #f.  FUNC should be a procedure which;;;		accepts a string and returns a boolean value; you may;;;		need to use quasiquotes to get it into GRAMMAR.;;;;;; The (PROPERTY VALUE) pairs may occur in any order, but each;;; property may occur only once.  By default, options do not have;;; single-character equivalents, are not required, and do not take;;; values.;;;;;; In ARGS, single-character options may be combined, in the usual;;; Unix fashion: ("-x" "-y") is equivalent to ("-xy").  If an option;;; accepts values, then it must be the last option in the;;; combination; the value is the next argument.  So, for example, using;;; the following grammar:;;;      ((apples    (single-char #\a));;;       (blimps    (single-char #\b) (value #t));;;       (catalexis (single-char #\c) (value #t)));;; the following argument lists would be acceptable:;;;    ("-a" "-b" "bang" "-c" "couth")     ("bang" and "couth" are the values;;;                                         for "blimps" and "catalexis");;;    ("-ab" "bang" "-c" "couth")         (same);;;    ("-ac" "couth" "-b" "bang")         (same);;;    ("-abc" "couth" "bang")             (an error, since `-b' is not the;;;                                         last option in its combination);;;;;; If an option's value is optional, then `getopt-long' decides;;; whether it has a value by looking at what follows it in ARGS.  If;;; the next element is does not appear to be an option itself, then;;; that element is the option's value.;;;;;; The value of a long option can appear as the next element in ARGS,;;; or it can follow the option name, separated by an `=' character.;;; Thus, using the same grammar as above, the following argument lists;;; are equivalent:;;;   ("--apples" "Braeburn" "--blimps" "Goodyear");;;   ("--apples=Braeburn" "--blimps" "Goodyear");;;   ("--blimps" "Goodyear" "--apples=Braeburn");;;;;; If the option "--" appears in ARGS, argument parsing stops there;;;; subsequent arguments are returned as ordinary arguments, even if;;; they resemble options.  So, in the argument list:;;;         ("--apples" "Granny Smith" "--" "--blimp" "Goodyear");;; `getopt-long' will recognize the `apples' option as having the;;; value "Granny Smith", but it will not recognize the `blimp';;; option; it will return the strings "--blimp" and "Goodyear" as;;; ordinary argument strings.;;;;;; The `getopt-long' function returns the parsed argument list as an;;; assocation list, mapping option names --- the symbols from GRAMMAR;;; --- onto their values, or #t if the option does not accept a value.;;; Unused options do not appear in the alist.;;;;;; All arguments that are not the value of any option are returned;;; as a list, associated with the empty list.;;;;;; `getopt-long' throws an exception if:;;; - it finds an unrecognized property in GRAMMAR;;; - the value of the `single-char' property is not a character;;; - it finds an unrecognized option in ARGS;;; - a required option is omitted;;; - an option that requires an argument doesn't get one;;; - an option that doesn't accept an argument does get one (this can;;;   only happen using the long option `--opt=value' syntax);;; - an option predicate fails;;;;;; So, for example:;;;;;; (define grammar;;;   `((lockfile-dir (required? #t);;;                   (value #t);;;                   (single-char #\k);;;                   (predicate ,file-is-directory?));;;     (verbose (required? #f);;;              (single-char #\v);;;              (value #f));;;     (x-includes (single-char #\x));;;     (rnet-server (single-char #\y);;;                  (predicate ,string?))));;;;;; (getopt-long '("my-prog" "-vk" "/tmp" "foo1" "--x-includes=/usr/include";;;                "--rnet-server=lamprod" "--" "-fred" "foo2" "foo3");;;                grammar);;; => ((() "foo1" "-fred" "foo2" "foo3");;; 	(rnet-server . "lamprod");;; 	(x-includes . "/usr/include");;; 	(lockfile-dir . "/tmp");;; 	(verbose . #t));;; (option-ref OPTIONS KEY DEFAULT);;; Return value in alist OPTIONS using KEY, a symbol; or DEFAULT if not;;; found.  The value is either a string or `#t'.;;;;;; For example, using the `getopt-long' return value from above:;;;;;; (option-ref (getopt-long ...) 'x-includes 42) => "/usr/include";;; (option-ref (getopt-long ...) 'not-a-key! 31) => 31;;; Code:(define-module (ice-9 getopt-long)  :use-module ((ice-9 common-list) :select (some remove-if-not))  :export (getopt-long option-ref))(define option-spec-fields '(name                             value                             required?                             single-char                             predicate                             value-policy))(define option-spec (make-record-type 'option-spec option-spec-fields))(define make-option-spec (record-constructor option-spec option-spec-fields))(define (define-one-option-spec-field-accessor field)  `(define ,(symbol-append 'option-spec-> field)        ;;; name slib-compat     (record-accessor option-spec ',field)))(define (define-one-option-spec-field-modifier field)  `(define ,(symbol-append 'set-option-spec- field '!)  ;;; name slib-compat     (record-modifier option-spec ',field)))(defmacro define-all-option-spec-accessors/modifiers ()  `(begin     ,@(map define-one-option-spec-field-accessor option-spec-fields)     ,@(map define-one-option-spec-field-modifier option-spec-fields)))(define-all-option-spec-accessors/modifiers)(define make-option-spec  (let ((ctor (record-constructor option-spec '(name))))    (lambda (name)      (ctor name))))(define (parse-option-spec desc)  (let ((spec (make-option-spec (symbol->string (car desc)))))    (for-each (lambda (desc-elem)                (let ((given (lambda () (cadr desc-elem))))                  (case (car desc-elem)                    ((required?)                     (set-option-spec-required?! spec (given)))                    ((value)                     (set-option-spec-value-policy! spec (given)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -