This module provides a user-driven command line lexer.
Unlike std/parseopt, this lexer parses command line tokens as requested by the caller.
Example:
import experimental/lexopt import std/options type Opts = object paths: seq[string] color: bool output: string var lexer = initCmdLexer(["--color", "/", "-o", "outfile.txt"]) var (kind, option) = lexer.next() var opts = Opts() while kind != cmdEnd: if (kind == cmdLong and option == "color") or (kind == cmdShort and option == "c"): opts.color = true elif (kind == cmdLong and option == "output") or (kind == cmdShort and option == "o"): let value = lexer.value() if value.isNone: quit "error: '--output' must be followed by a value" opts.output = value.get() elif kind == cmdValue: opts.paths.add option (kind, option) = lexer.next() doAssert opts.paths == ["/"] doAssert opts.color == true doAssert opts.output == "outfile.txt"
Types
CmdLexer = object cmdline: seq[string] ## The command line to parse index: int ## The index of `cmdline` to be processed valueIdx: int ## For long options, the index of `ValueSeparators`. ## ## For short options, the index of the next flag to be processed. ## ## Otherwise, it is unused.
- Source Edit
CmdlineKind = enum cmdEnd, ## End of command line cmdLong, ## A long option (i.e. `--opt`) cmdShort, ## A short option (i.e. `-o`) cmdValue ## A value that is not an option
- Source Edit
LexError = object of CatchableError
- Errors occurring during lexing. Source Edit
Consts
ValueSeparators = {':', '='}
- Characters that separate an option's name from its value Source Edit
Procs
proc initCmdLexer(args: openArray[string]): CmdLexer {....raises: [], tags: [].}
- Creates a new CmdLexer. args should be the command line parameters as returned by commandLineParams. Source Edit
proc initCmdLexer(args: sink seq[string]): CmdLexer {....raises: [], tags: [].}
- Creates a new CmdLexer. args should be the command line parameters as returned by commandLineParams. Source Edit
proc isLongOpt(s: string): bool {....raises: [], tags: [].}
- Returns whether s can be parsed as a long option. Source Edit
proc isShortOpt(s: string): bool {....raises: [], tags: [].}
- Returns whether s can be parsed as a short option. Source Edit
proc next(l: var CmdLexer): (CmdlineKind, string) {. ...raises: [UnexpectedValueError], tags: [].}
-
Consume the next option.
The following section describes how various syntaxes are handled:
- -- and - are considered values.
--foo:bar and --foo=bar are treated as long options with key foo and bar is considered the value of foo.
If this value is not consumed before the next call to next(), an error will be raised. See below for more details.
- --foo is treated as a long option with key foo.
- -a:foo and -a=foo are treated as short options with key a and value foo.
- -a is treated as a short option with key a.
- -abco is equivalent to -a, -b, -c, -o appearing in sequence. Four calls to next() are required to consume -abco.
-abco:foo and -abco=foo are equivalent to -a, -b, -c, -o:foo appearing in sequence.
If this value is not consumed before the next call to next(), an error will be raised. See below for more details
- Everything else is considered values.
If the previous option have an unconsumed value (e.g. value() was not called for --opt:foo), UnexpectedValueError will be raised.
Source Edit proc prefix(kind: CmdlineKind): string {....raises: [], tags: [].}
- Returns the prefix string for a given command line parameter kind. Source Edit
proc value(l: var CmdLexer; delimitedOnly = false): Option[string] {....raises: [], tags: [].}
-
Consume the value for the current option, if any.
The following section describes how various syntaxes are handled:
- --foo:bar or --foo=bar yields bar if called after next() returns foo.
- -abco:foo or -abco=foo yields foo if called after next() returns o.
- If delimitedOnly is true, syntaxes below will not be considered.
- -abcooutput.txt yields output.txt if called after next() returns o.
- The current parameter is treated as a value, regardless of whether it can be considered as an option (ie. --foo --bar will yield --bar if this procedure is called after --foo).
Iterators
iterator remaining(l: var CmdLexer): string {....raises: [UnexpectedValueError], tags: [].}
-
Consume the remaining unprocessed parameters.
If the previous option returned from next() have a value that was not consumed by value(), UnexpectedValueError will be raised.
As a special case, any short options within a bundle (ie. -abcde) that have not been processed by next() is considered the value of the last short option returned and will raise UnexpectedValueError.
Source Edit