args-fold: a program argument processor
Anthony Carrico
Many operating systems make the set of argument strings used to invoke a program available (often following the program name string in an array called argv). Most programs need to parse and process these argument strings in one way or another. This SRFI describes a set of procedures that support processing program arguments according to POSIX and GNU C Library Reference Manual guidelines.
This SRFI does not address how to obtain the program arguments from the operating system (but maybe it should).
This SRFI does not address long option abbreviations. Presumably some implementations might support such abbreviations (as an optional extension), but it is also debatable if long argument abbreviations are desirable, so they are not included in this SRFI.
As usual when folding multiple values, zero seeds produces zero results, which requires a continuation accepting zero values. (It might be desirable for this SRFI to point out this pitfall to beginners.)
Should the NAME argument of an option-processor be eq? or equal? to one of the OPTION's option-names. Probably eq?: fix the reference implementation.
Program arguments are the primary interface to many programs, so processing arguments is a common programming task. There are many common (often conflicting) ways take care of this task, so a custom processor is often necessary; however, many programmers (and their users) would welcome a convenient interface supporting common guidelines.
POSIX provides several guidelines for the specification of program options, option-arguments, and operands. It also notes historical exceptions to these guidelines. The GNU C Library Reference Manual describes long option extensions to the POSIX guidelines.
This SRFI supports creating programs following the guidelines mentioned above by
Preliminary versions of this interface are already available for some Scheme implementations: here for Chicken, and here for Scsh.
Args-fold is an iterator similar to SRFI 1's fold procedure ("the fundamental list iterator"). As it parses options and operands, it calls their corresponding operand and option processors. Unlike mapping, folding passes state, called seeds, from one processor to the next.
For example, a program may need a list of operands and a table of options. To build these, args-fold could be seeded with an empty operand list, and an empty option table. The operand processor could add the operands to the operand list, and the option processors could add the options to the option table. Along the way, some option processors might even take immediate action for options like --version or --help. This kind of heterogeneous processing is appropriate for program arguments, and folding allows a functional implementation if desired.
procedure prototype: (option-processor OPTION NAME ARG SEEDS ...)
Prototype for an option-processor. It should return the next seeds as values. OPTION will be the option. NAME will be one of the OPTION's option-names as encountered by args-fold. ARG will be a string, or #f if args-fold didn't encounter an option-argument.
procedure prototype: (operand-processor OPERAND SEEDS ...)
Prototype for an operand-processor. It should return the next seeds as values. OPERAND will be a string.
procedure: (option NAMES REQUIRED-ARG? OPTIONAL-ARG? OPTION-PROC)
Return an option. NAMES is a list of short (character) and long (string) option names. REQUIRED-ARG? specifies if this options requires an option-argument (boolean). OPTIONAL-ARG? specifies if this option can accept an option-argument (boolean). OPTION-PROC is a procedure (following the option-processor prototype) used to process this option.
procedure: (option-names OPTION) procedure: (option-required-arg? OPTION) procedure: (option-optional-arg? OPTION) procedure: (option-processor OPTION)
Return the contents of corresponding fields of OPTION.
procedure: (args-fold ARGS OPTIONS UNRECOGNIZED-OPTION-PROC OPERAND-PROC SEEDS ...)
Parse argument strings left-to-right, calling the appropriate processors in-order (for the parsed known options, unknown options, and operands), passing the seed values from one processor to the next and returning the final seeds values as results. ARGS is a list of strings. OPTIONS is a list of options. UNRECOGNIZED-OPTION-PROC is a procedure (following the option-processor prototype) for unrecognized options. NOTE: args-fold will create temporary options as necessary for the UNRECOGNIZED-OPTION-PROC. OPERAND-PROC is a procedure (following the operand-processor prototype) for operands.
Source for the reference implementation.This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Scheme Request For Implementation process or editors, except as needed for the purpose of developing SRFIs in which case the procedures for copyrights defined in the SRFI process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the authors or their successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.