diff --git a/assets/cli-railroad/diagram/Alphanumeric.svg b/assets/cli-railroad/diagram/Alphanumeric.svg new file mode 100644 index 0000000..0f629e8 --- /dev/null +++ b/assets/cli-railroad/diagram/Alphanumeric.svg @@ -0,0 +1,47 @@ + + + + + + + + + + [0-9] + + + [a-z] + + + [A-Z] + + + + diff --git a/assets/cli-railroad/diagram/AlphanumericAnd.svg b/assets/cli-railroad/diagram/AlphanumericAnd.svg new file mode 100644 index 0000000..d3991eb --- /dev/null +++ b/assets/cli-railroad/diagram/AlphanumericAnd.svg @@ -0,0 +1,63 @@ + + + + + + + + + + [0-9] + + + [a-z] + + + [A-Z] + + + - + + + _ + + + + diff --git a/assets/cli-railroad/diagram/Char.svg b/assets/cli-railroad/diagram/Char.svg new file mode 100644 index 0000000..3302916 --- /dev/null +++ b/assets/cli-railroad/diagram/Char.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + UnicodeExceptDoubleQuotes + + + + \" + + + + diff --git a/assets/cli-railroad/diagram/CmdIdentifier.svg b/assets/cli-railroad/diagram/CmdIdentifier.svg new file mode 100644 index 0000000..e75517d --- /dev/null +++ b/assets/cli-railroad/diagram/CmdIdentifier.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + AlphanumericAnd + + + + + diff --git a/assets/cli-railroad/diagram/Command.svg b/assets/cli-railroad/diagram/Command.svg new file mode 100644 index 0000000..666aca3 --- /dev/null +++ b/assets/cli-railroad/diagram/Command.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + CmdIdentifier + + + + + Option + + + + + Operand + + + + + Command + + + + + diff --git a/assets/cli-railroad/diagram/LongFlagOption.svg b/assets/cli-railroad/diagram/LongFlagOption.svg new file mode 100644 index 0000000..75b5282 --- /dev/null +++ b/assets/cli-railroad/diagram/LongFlagOption.svg @@ -0,0 +1,60 @@ + + + + + + + + + + -- + + + + Alphanumeric + + + + + AlphanumericAnd + + + + + diff --git a/assets/cli-railroad/diagram/LongOption.svg b/assets/cli-railroad/diagram/LongOption.svg new file mode 100644 index 0000000..8ffc45c --- /dev/null +++ b/assets/cli-railroad/diagram/LongOption.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + LongFlagOption + + + + + LongValueOption + + + + + diff --git a/assets/cli-railroad/diagram/LongValueOption.svg b/assets/cli-railroad/diagram/LongValueOption.svg new file mode 100644 index 0000000..df85023 --- /dev/null +++ b/assets/cli-railroad/diagram/LongValueOption.svg @@ -0,0 +1,74 @@ + + + + + + + + + + -- + + + + Alphanumeric + + + + + AlphanumericAnd + + + + + OptionValueDelimiter + + + + + Value + + + + + diff --git a/assets/cli-railroad/diagram/Operand.svg b/assets/cli-railroad/diagram/Operand.svg new file mode 100644 index 0000000..cb8c835 --- /dev/null +++ b/assets/cli-railroad/diagram/Operand.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + Value + + + + + diff --git a/assets/cli-railroad/diagram/Option.svg b/assets/cli-railroad/diagram/Option.svg new file mode 100644 index 0000000..a826d03 --- /dev/null +++ b/assets/cli-railroad/diagram/Option.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + ShortOption + + + + + LongOption + + + + + diff --git a/assets/cli-railroad/diagram/OptionValueDelimiter.svg b/assets/cli-railroad/diagram/OptionValueDelimiter.svg new file mode 100644 index 0000000..2597f51 --- /dev/null +++ b/assets/cli-railroad/diagram/OptionValueDelimiter.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + Space + + + + = + + + + diff --git a/assets/cli-railroad/diagram/ShortFlagOption.svg b/assets/cli-railroad/diagram/ShortFlagOption.svg new file mode 100644 index 0000000..300cccd --- /dev/null +++ b/assets/cli-railroad/diagram/ShortFlagOption.svg @@ -0,0 +1,53 @@ + + + + + + + + + + - + + + + Alphanumeric + + + + + diff --git a/assets/cli-railroad/diagram/ShortOption.svg b/assets/cli-railroad/diagram/ShortOption.svg new file mode 100644 index 0000000..3a997f6 --- /dev/null +++ b/assets/cli-railroad/diagram/ShortOption.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + ShortFlagOption + + + + + ShortValueOption + + + + + diff --git a/assets/cli-railroad/diagram/ShortValueOption.svg b/assets/cli-railroad/diagram/ShortValueOption.svg new file mode 100644 index 0000000..dbe1f24 --- /dev/null +++ b/assets/cli-railroad/diagram/ShortValueOption.svg @@ -0,0 +1,67 @@ + + + + + + + + + + - + + + + Alphanumeric + + + + + OptionValueDelimiter + + + + + Value + + + + + diff --git a/assets/cli-railroad/diagram/Space.svg b/assets/cli-railroad/diagram/Space.svg new file mode 100644 index 0000000..ce1a49f --- /dev/null +++ b/assets/cli-railroad/diagram/Space.svg @@ -0,0 +1,46 @@ + + + + + + + + + + U+0020 + + + + diff --git a/assets/cli-railroad/diagram/Value.svg b/assets/cli-railroad/diagram/Value.svg new file mode 100644 index 0000000..d1475ba --- /dev/null +++ b/assets/cli-railroad/diagram/Value.svg @@ -0,0 +1,75 @@ + + + + + + + + + + + Char + + + + " + + + + Char + + + + + Space + + + + " + + + + diff --git a/assets/cli-railroad/diagram/rr-2.0.svg b/assets/cli-railroad/diagram/rr-2.0.svg new file mode 100644 index 0000000..1de2f82 --- /dev/null +++ b/assets/cli-railroad/diagram/rr-2.0.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + R + R + + diff --git a/assets/cli-railroad/index.md b/assets/cli-railroad/index.md new file mode 100644 index 0000000..4df89c7 --- /dev/null +++ b/assets/cli-railroad/index.md @@ -0,0 +1,222 @@ +**Command:** + +![Command](diagram/Command.svg) + +``` +Command ::= CmdIdentifier Option* ( Operand* | Command+ ) +``` + +referenced by: + +- Command + +**CmdIdentifier:** + +![CmdIdentifier](diagram/CmdIdentifier.svg) + +``` +CmdIdentifier + ::= AlphanumericAnd* +``` + +referenced by: + +- Command + +**Option:** + +![Option](diagram/Option.svg) + +``` +Option ::= ShortOption + | LongOption +``` + +referenced by: + +- Command + +**ShortOption:** + +![ShortOption](diagram/ShortOption.svg) + +``` +ShortOption + ::= ShortFlagOption + | ShortValueOption +``` + +referenced by: + +- Option + +**LongOption:** + +![LongOption](diagram/LongOption.svg) + +``` +LongOption + ::= LongFlagOption + | LongValueOption +``` + +referenced by: + +- Option + +**ShortFlagOption:** + +![ShortFlagOption](diagram/ShortFlagOption.svg) + +``` +ShortFlagOption + ::= '-' Alphanumeric +``` + +referenced by: + +- ShortOption + +**ShortValueOption:** + +![ShortValueOption](diagram/ShortValueOption.svg) + +``` +ShortValueOption + ::= '-' Alphanumeric OptionValueDelimiter Value +``` + +referenced by: + +- ShortOption + +**LongFlagOption:** + +![LongFlagOption](diagram/LongFlagOption.svg) + +``` +LongFlagOption + ::= '--' Alphanumeric AlphanumericAnd* +``` + +referenced by: + +- LongOption + +**LongValueOption:** + +![LongValueOption](diagram/LongValueOption.svg) + +``` +LongValueOption + ::= '--' Alphanumeric AlphanumericAnd* OptionValueDelimiter Value +``` + +referenced by: + +- LongOption + +**OptionValueDelimiter:** + +![OptionValueDelimiter](diagram/OptionValueDelimiter.svg) + +``` +OptionValueDelimiter + ::= Space + | '=' +``` + +referenced by: + +- LongValueOption +- ShortValueOption + +**Alphanumeric:** + +![Alphanumeric](diagram/Alphanumeric.svg) + +``` +Alphanumeric + ::= [0-9a-zA-Z] +``` + +referenced by: + +- LongFlagOption +- LongValueOption +- ShortFlagOption +- ShortValueOption + +**AlphanumericAnd:** + +![AlphanumericAnd](diagram/AlphanumericAnd.svg) + +``` +AlphanumericAnd + ::= [0-9a-zA-Z_#x2D] +``` + +referenced by: + +- CmdIdentifier +- LongFlagOption +- LongValueOption + +**Value:** + +![Value](diagram/Value.svg) + +``` +Value ::= Char* + | '"' ( Char | Space )* '"' +``` + +referenced by: + +- LongValueOption +- Operand +- ShortValueOption + +**Char:** + +![Char](diagram/Char.svg) + +``` +Char ::= UnicodeExceptDoubleQuotes + | '\"' +``` + +referenced by: + +- Value + +**Space:** + +![Space](diagram/Space.svg) + +``` +Space ::= ( U+0020 )* +``` + +referenced by: + +- OptionValueDelimiter +- Value + +**Operand:** + +![Operand](diagram/Operand.svg) + +``` +Operand ::= Value +``` + +referenced by: + +- Command + +## + +![rr-2.0](diagram/rr-2.0.svg) generated by [RR - Railroad Diagram Generator][rr] + +[rr]: http://bottlecaps.de/rr/ui diff --git a/cli-args.md b/cli-args.md new file mode 100644 index 0000000..6062166 --- /dev/null +++ b/cli-args.md @@ -0,0 +1,93 @@ +# Command-line argument conventions + +``` +Code: conv/cli-args +Version: 1.0.0 +Author: Muthu Kumar +Org: Feathers Studio +``` + +## Introduction + +The POSIX standard is often cited when designing command line interfaces. However, the most recent version published as IEEE Std 1003.1-2017 (also published as [The Open Group Base Specifications](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html)) still falls woefully short of modern requirements. The [GNU extensions](https://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html) to POSIX are the most widely used. However, there is still room for disambiguation. This specification addresses them. + +## Specification + +A command MAY accept sub-commands, options, and operands. + +##### Note: This specification is available as a [formal grammar](#formal-grammar), or as a [railroad diagram](./assets/cli-railroad/index.md). + +### Sub-commands + +- A sub-command is a part of the command that acts as a command by itself. In other words, a sub-command is a recursive command. +- Commands (or sub-commands) with sub-commands MUST NOT accept operands. They MAY accept options. +- Any arguments after a sub-command MUST be accepted literally without parsing, even if they start with `-`, `--`, or `=`. They MUST be parsed by the sub-command's own arg parser, following this specification. + +### Options + +- Options are arguments that MAY modify the behaviour of the command. +- Options MAY be supplied in any order. + +#### Boolean options + +- Boolean options MUST NOT accept any value. They are boolean in nature and their presence MUST be inferred as true. +- Boolean options MAY be referred to as "flags". + +#### Non-boolean options + +- A non-boolean option MUST accept a single value. An option MAY be repeated several times to pass multiple values. +- A non-boolean option MUST be separated from their value by a space or "=". + +#### Long-form options + +- Every option MUST have a long-form. This is denoted by the delimiter `--` followed by the option name without spaces. +- Long-form options MUST be at least two characters, and consist of alphanumeric characters, `-`, or `_`. +- Long-form options MUST begin with an alphanumeric character. + +#### Short-form options + +- Options MAY have a short-form. This is denoted by the delimiter `-` and MUST be followed by a single alphanumeric character. +- Every short-form option MUST correspond to a long-form option. The inverse is not required. + +### Operands + +- Operands are any values passed as input to the utility for its primary function. +- Operands MUST be passed after all options. + +### Strict-mode + +- "Strict-mode" MAY be specified by the application developer via the parser library or their own implementation of this specification. +- "Strict-mode" MAY be specified by the application user via the environment variable `ARG_PARSER_STRICT_MODE`. +- In "strict-mode", non-boolean options MUST be separated from their value by "=" only. + +### Special-cases + +- Any arguments after the delimiter `--` followed by space MUST be accepted literally without parsing, even if they start with `-`, `--`, or `=`. +- A single `-` MUST be interpreted as a regular operand. By convention, this MAY represent input from or output to the standard input/output streams. + +## Formal Grammar + +```C +Command ::= CmdIdentifier +Command ::= CmdIdentifier Operand* +Command ::= CmdIdentifier Option* Operand* +Command ::= CmdIdentifier Command* +Command ::= CmdIdentifier Option* Command* +CmdIdentifier ::= AlphanumericAnd* +Option ::= ShortOption | LongOption +ShortOption ::= ShortFlagOption | ShortValueOption +LongOption ::= LongFlagOption | LongValueOption +ShortFlagOption ::= '-' Alphanumeric +ShortValueOption ::= '-' Alphanumeric OptionValueDelimiter Value +LongFlagOption ::= '--' Alphanumeric AlphanumericAnd* +LongValueOption ::= '--' Alphanumeric AlphanumericAnd* OptionValueDelimiter Value +OptionValueDelimiter ::= Space | '=' +Alphanumeric ::= [0-9a-zA-Z] +AlphanumericAnd ::= [0-9a-zA-Z-_] +Value ::= Char* | '"' ( Char | Space )* '"' +Char ::= ( UnicodeExceptDoubleQuotes | '\"' ) +Space ::= ( U+0020 )* +Operand ::= Value +``` + +This grammar is also available as a [railroad diagram](./assets/cli-railroad/index.md).