Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
== Outdated egg! This is an egg for CHICKEN 3, the unsupported old release. You're almost certainly looking for [[/eggref/4/tool|the CHICKEN 4 version of this egg]], if it exists. If it does not exist, there may be equivalent functionality provided by another egg; have a look at the [[https://wiki.call-cc.org/chicken-projects/egg-index-4.html|egg index]]. Otherwise, please consider porting this egg to the current version of CHICKEN. == tool [[toc:]] [[tags: egg]] == Introduction The {{tool}} extension provides a flexible declarative alternative to [[http://code.call-cc.org/legacy-eggs/3/srfi-37.html|SRFI-37]] and [[http://code.call-cc.org/legacy-eggs/3/args.html|args]]. == Requirements [[http://code.call-cc.org/legacy-eggs/3/srfi-37.html|srfi-37]], [[args-doc]] and [[http://code.call-cc.org/legacy-eggs/3/srfi-95.html|srfi-95]] == Interface Use {{define-option}} to define command-line options and {{define-command}} for defining ''subcommands'' that control specific sub-functionality. Basic usage of a program that uses this facility is PROGRAM [OPTION | ARGUMENT] ... or PROGRAM [COMMAND [OPTION | ARGUMENT] ...] where {{PROGRAM}} is the program name, {{COMMAND}} is an optional subcommand and {{OPTION}} and {{ARGUMENT}} are command-line options and arguments to those, respectively. {{define-option}} defines global or subcommand-specific command-line options, {{define-command}} defines subcommands and specifies their behaviour. After you have finished declaring options and commands, invoke {{tool-main}} to process the remainingcommand-line arguments and invoke command and option processors. The option {{-h}} / {{--help}} is predefined and invokes {{tool-usage}}. This extension supports static linking. === define-option [syntax] (define-option OPTION DOCUMENTATION [PROC]) Defines the command-line option {{OPTION}} which may be a character, string or SRFI-37 {{option}} value. The option expects a required argument. If an {{option}}, the option argument flag (required or optional) must be a string which is used in {{tool-usage}} to show a more informative option documentation. {{DOCUMENTATION}} should be a string describing the option. {{PROC}}, if given, should be an option-processor as described in [[http://srfi.schemers.org/srfi-37/srfi-37.html|SRFI-37]] or a symbol. If {{PROC}} is a symbol then giving this option on the command line will set the global variable with the same name to the option argument. If {{PROC}} is missing the name of option global variable is the same as {{OPTION}} which should be a string, symbol or character. === define-flag [syntax] (define-flag OPTIONNAME DOCUMENTATION [VARIABLE]) Defines an option that takes no arguments and sets {{VARIABLE}} to {{#t}} if the option is given. If {{VARIABLE}} is not specified, the name of the variable is the same as {{OPTIONNAME}} which should be a string, symbol or character. === define-command [syntax] (define-command NAME DOCUMENTATION BODY ...) Defines a subcommand. {{NAME}} should be a string or symbol. {{DOCUMENTATION}} should be a string describing the operation of this command. {{BODY ...}} is evaluated and should return a one-argument procedure that is invoked when the subcommand is specified on the command-line, with all non-option arguments collected in a list. If a tool provides subcommands, then the command name must be the first program argument given on the command line. Note that you can use {{define-option}} and {{define-flag}} in the body to declare command-specific options. === define-tool [syntax] (define-tool (NAME [INPUTVAR [COUNTVAR [INDEXVAR]]]) HELPSTRING BODY ...) A convenience macro that wraps common uses of {{tool-name}}, {{tool-help}} and {{tool-main}}. Defines a tool named {{NAME}} with a help string {{HELP}}, and calls {{tool-main}} with the value of {{(command-line-arguments)}} and an argument processor that invokes {{body ...}} for each given command line argument, with {{INPUTVAR}} bound to the current argument. If no command line arguments were given, the value of {{(current-input-port)}} will be bound to {{INPUTVAR}}. When {{INPUTVAR}} is missing the variable named {{argument}} is in scope. The number of arguments is bound to {{COUNTVAR}}. When {{COUNTVAR}} is missing the variable named {{arguments-count}} is in scope. The current argument index is bound to {{INDEXVAR}}. When {{INDEXVAR}} is missing the variable named {{arguments-index}} is in scope. {{define-tool}} can be defined like this: <enscript highlight=scheme> (define-macro (define-tool head help . body) (let-optionals head ((name (string->symbol (tool-name))) (input 'argument) (args-cnt-var 'argument-count) (args-idx-var 'argument-index)) (let ((args-var (gensym))) `(begin (tool-name ,(symbol->string name)) (tool-help ,help) (tool-main (command-line-arguments) (lambda (,args-var) (let ((,args-cnt-var (length ,args-var)) (,args-idx-var 0)) (for-each (lambda (,input) ,@body (set! ,args-idx-var (+ ,args-idx-var 1))) (if (null? ,args-var) (list (current-input-port)) ,args-var) ) ) ) ) ) ) ) ) </enscript> === tool-main [procedure] (tool-main ARGUMENTS [PROC [THUNK]]) Starts command-line processing of {{ARGUMENTS}}. If no arguments are given {{THUNK}} is invoked (which defaults to a procedure that calls {{(tool-usage 1)}}). If non-option arguments are supplied, {{PROC}} is called with the argument list, if given. === tool-name [procedure] (tool-name [STRING]) Sets or returns the name of the program, which defaults to {{(car (argv))}}. === tool-help [procedure] (tool-help STRING) Sets or returns the program description. === tool-usage [procedure] (tool-usage STATUS [COMMAND]) Shows usage information collected from {{(tool-help)}} and the option and subcommand documentation and exits with status code {{STATUS}}. If {{COMMAND}} is given, the usage information shown lists global options and the description of the command. If no command is given, then global options and all available subcommands are shown. Finally {{(tool-exit STATUS)}} is invoked. === tool-exit [procedure] (tool-exit [STATUS]) Terminates the program and returns {{STATUS}} (which defaults to 0). If invoked inside the dynamic scope of {{tool-main}}, then the call to {{tool-main}} returns with the given status code. If called outside of the dynamic scope of {{tool-main}}, {{(exit STATUS)}} is performed. === tool-error [procedure] (tool-error MESSAGE [STATUS [COMMAND]]) Displays an error {{MESSAGE}} and invokes {{tool-usage}} with the any optional arguments. Default value for {{STATUS}} is {{1}}. Default value for {{COMMAND}} is the same as {{tool-usage}}. == Example A simple {{cat(1)}} tool: <enscript highlight=scheme> ;;;; cat.scm (use tool utils format-modular) (define-flag #\n "number output lines" numlines) (tool-name "cat") (tool-help "Concatenate input files (or standard input) to standard output") (tool-main (command-line-arguments) (lambda (args) (for-each (lambda (f) (if numlines (do ((i 1 (add1 i)) (lns (read-lines f) (cdr lns)) ) ((null? lns)) (format #t "~6d\t~a~%" i (car lns)) ) (display (read-all f)) ) ) (if (null? args) (list (current-input-port)) args) ) ) ) </enscript> == Authors [[/users/felix winkelmann|felix winkelmann]] == License Copyright (c) 2007, Felix L. Winkelmann All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. == Version History ; 0.703 : added 'tool-error' procedure, "argument-index" to 'define-tool' [Kon Lovett] ; 0.702 : binding of 'tool-exit' in 'tool-main' should be "fluid" [Kon Lovett] ; 0.701 : added count of non-option arguments to 'define-tool' [Kon Lovett] ; 0.7 : didn't work with syntax-case at all ; 0.6 : uses [[args-doc]] for usage information [Thanks to Ivan Shmakov] ; 0.5 : toplevel help output is somewhat compressed ; 0.4 : fixed bug in handling of option processor in {{define-option}} ; 0.3 : order of non-option arguments was reversed ; 0.2 : added {{define-tool}} [suggested by Arto Bendiken] ; 0.1 : initial release
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 19 from 5?