From cc32dafada8bc79f8a5a03a7f76f54e4c0e2dc00 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Wed, 22 Feb 2023 02:41:25 +0530 Subject: [PATCH 1/3] feat(proposal): cli-args --- assets/cli-railroad/diagram/Alphanumeric.svg | 47 ++++ assets/cli-railroad/diagram/Char.svg | 53 +++++ assets/cli-railroad/diagram/CmdIdentifier.svg | 45 ++++ assets/cli-railroad/diagram/Command.svg | 59 +++++ .../cli-railroad/diagram/LongFlagOption.svg | 53 +++++ assets/cli-railroad/diagram/LongOption.svg | 52 +++++ .../cli-railroad/diagram/LongValueOption.svg | 67 ++++++ assets/cli-railroad/diagram/Operand.svg | 44 ++++ assets/cli-railroad/diagram/Option.svg | 52 +++++ .../diagram/OptionValueDelimiter.svg | 53 +++++ .../cli-railroad/diagram/ShortFlagOption.svg | 53 +++++ assets/cli-railroad/diagram/ShortOption.svg | 52 +++++ .../cli-railroad/diagram/ShortValueOption.svg | 67 ++++++ assets/cli-railroad/diagram/Space.svg | 46 ++++ assets/cli-railroad/diagram/Value.svg | 75 +++++++ assets/cli-railroad/diagram/rr-2.0.svg | 57 +++++ assets/cli-railroad/index.md | 204 ++++++++++++++++++ cli-args.md | 88 ++++++++ 18 files changed, 1167 insertions(+) create mode 100644 assets/cli-railroad/diagram/Alphanumeric.svg create mode 100644 assets/cli-railroad/diagram/Char.svg create mode 100644 assets/cli-railroad/diagram/CmdIdentifier.svg create mode 100644 assets/cli-railroad/diagram/Command.svg create mode 100644 assets/cli-railroad/diagram/LongFlagOption.svg create mode 100644 assets/cli-railroad/diagram/LongOption.svg create mode 100644 assets/cli-railroad/diagram/LongValueOption.svg create mode 100644 assets/cli-railroad/diagram/Operand.svg create mode 100644 assets/cli-railroad/diagram/Option.svg create mode 100644 assets/cli-railroad/diagram/OptionValueDelimiter.svg create mode 100644 assets/cli-railroad/diagram/ShortFlagOption.svg create mode 100644 assets/cli-railroad/diagram/ShortOption.svg create mode 100644 assets/cli-railroad/diagram/ShortValueOption.svg create mode 100644 assets/cli-railroad/diagram/Space.svg create mode 100644 assets/cli-railroad/diagram/Value.svg create mode 100644 assets/cli-railroad/diagram/rr-2.0.svg create mode 100644 assets/cli-railroad/index.md create mode 100644 cli-args.md 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/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..10ea49f --- /dev/null +++ b/assets/cli-railroad/diagram/CmdIdentifier.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + Alphanumeric + + + + + diff --git a/assets/cli-railroad/diagram/Command.svg b/assets/cli-railroad/diagram/Command.svg new file mode 100644 index 0000000..cd7bec8 --- /dev/null +++ b/assets/cli-railroad/diagram/Command.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + CmdIdentifier + + + + + Option + + + + + Operand + + + + + diff --git a/assets/cli-railroad/diagram/LongFlagOption.svg b/assets/cli-railroad/diagram/LongFlagOption.svg new file mode 100644 index 0000000..70d6c87 --- /dev/null +++ b/assets/cli-railroad/diagram/LongFlagOption.svg @@ -0,0 +1,53 @@ + + + + + + + + + + -- + + + + Alphanumeric + + + + + 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..b259028 --- /dev/null +++ b/assets/cli-railroad/diagram/LongValueOption.svg @@ -0,0 +1,67 @@ + + + + + + + + + + -- + + + + Alphanumeric + + + + + 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..4430268 --- /dev/null +++ b/assets/cli-railroad/index.md @@ -0,0 +1,204 @@ +**Command:** + +![Command](diagram/Command.svg) + +``` +Command ::= CmdIdentifier Option* Operand* +``` + +**CmdIdentifier:** + +![CmdIdentifier](diagram/CmdIdentifier.svg) + +``` +CmdIdentifier + ::= Alphanumeric* +``` + +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+ +``` + +referenced by: + +- LongOption + +**LongValueOption:** + +![LongValueOption](diagram/LongValueOption.svg) + +``` +LongValueOption + ::= '--' Alphanumeric+ 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: + +- CmdIdentifier +- LongFlagOption +- LongValueOption +- ShortFlagOption +- ShortValueOption + +**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..cf0f959 --- /dev/null +++ b/cli-args.md @@ -0,0 +1,88 @@ +# 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. + +### 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 + +```grammar +Command ::= CmdIdentifier +Command ::= CmdIdentifier Operand* +Command ::= CmdIdentifier Option* Operand* +CmdIdentifier ::= Alphanumeric* +Option ::= ShortOption | LongOption +ShortOption ::= ShortFlagOption | ShortValueOption +LongOption ::= LongFlagOption | LongValueOption +ShortFlagOption ::= '-' Alphanumeric +ShortValueOption ::= '-' Alphanumeric OptionValueDelimiter Value +LongFlagOption ::= '--' Alphanumeric Alphanumeric* +LongValueOption ::= '--' Alphanumeric Alphanumeric* OptionValueDelimiter Value +OptionValueDelimiter ::= Space | '=' +Alphanumeric ::= [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.md). From fa5207b5a45cbcf8fe89cc4a49a10127b88741c7 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Wed, 22 Feb 2023 02:56:00 +0530 Subject: [PATCH 2/3] feat(cli-args): allow sub-commands in grammar --- .../cli-railroad/diagram/AlphanumericAnd.svg | 63 +++++++++++++++++++ assets/cli-railroad/diagram/CmdIdentifier.svg | 18 +++--- assets/cli-railroad/diagram/Command.svg | 21 ++++--- .../cli-railroad/diagram/LongFlagOption.svg | 31 +++++---- .../cli-railroad/diagram/LongValueOption.svg | 43 +++++++------ assets/cli-railroad/index.md | 28 +++++++-- cli-args.md | 15 +++-- 7 files changed, 163 insertions(+), 56 deletions(-) create mode 100644 assets/cli-railroad/diagram/AlphanumericAnd.svg 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/CmdIdentifier.svg b/assets/cli-railroad/diagram/CmdIdentifier.svg index 10ea49f..e75517d 100644 --- a/assets/cli-railroad/diagram/CmdIdentifier.svg +++ b/assets/cli-railroad/diagram/CmdIdentifier.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/cli-railroad/diagram/Command.svg b/assets/cli-railroad/diagram/Command.svg index cd7bec8..666aca3 100644 --- a/assets/cli-railroad/diagram/Command.svg +++ b/assets/cli-railroad/diagram/Command.svg @@ -1,5 +1,5 @@ - + diff --git a/assets/cli-railroad/diagram/LongFlagOption.svg b/assets/cli-railroad/diagram/LongFlagOption.svg index 70d6c87..75b5282 100644 --- a/assets/cli-railroad/diagram/LongFlagOption.svg +++ b/assets/cli-railroad/diagram/LongFlagOption.svg @@ -1,5 +1,5 @@ - + - - - + + + - -- + -- - - - Alphanumeric + + + Alphanumeric + + + + + AlphanumericAnd - - + d="m17 51 h2 m0 0 h10 m32 0 h10 m0 0 h10 m106 0 h10 m20 0 h10 m0 0 h140 m-170 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -14 q0 -10 10 -10 m150 34 l20 0 m-20 0 q10 0 10 -10 l0 -14 q0 -10 -10 -10 m-150 0 h10 m130 0 h10 m23 34 h-3"/> + + diff --git a/assets/cli-railroad/diagram/LongValueOption.svg b/assets/cli-railroad/diagram/LongValueOption.svg index b259028..df85023 100644 --- a/assets/cli-railroad/diagram/LongValueOption.svg +++ b/assets/cli-railroad/diagram/LongValueOption.svg @@ -1,5 +1,5 @@ - + - - - + + + - -- + -- - - - Alphanumeric + + + Alphanumeric + + + + + AlphanumericAnd - - - OptionValueDelimiter + + + OptionValueDelimiter - - - Value + + + Value - - + d="m17 51 h2 m0 0 h10 m32 0 h10 m0 0 h10 m106 0 h10 m20 0 h10 m0 0 h140 m-170 0 l20 0 m-1 0 q-9 0 -9 -10 l0 -14 q0 -10 10 -10 m150 34 l20 0 m-20 0 q10 0 10 -10 l0 -14 q0 -10 -10 -10 m-150 0 h10 m130 0 h10 m20 34 h10 m154 0 h10 m0 0 h10 m56 0 h10 m3 0 h-3"/> + + diff --git a/assets/cli-railroad/index.md b/assets/cli-railroad/index.md index 4430268..4df89c7 100644 --- a/assets/cli-railroad/index.md +++ b/assets/cli-railroad/index.md @@ -3,16 +3,20 @@ ![Command](diagram/Command.svg) ``` -Command ::= CmdIdentifier Option* Operand* +Command ::= CmdIdentifier Option* ( Operand* | Command+ ) ``` +referenced by: + +- Command + **CmdIdentifier:** ![CmdIdentifier](diagram/CmdIdentifier.svg) ``` CmdIdentifier - ::= Alphanumeric* + ::= AlphanumericAnd* ``` referenced by: @@ -92,7 +96,7 @@ referenced by: ``` LongFlagOption - ::= '--' Alphanumeric+ + ::= '--' Alphanumeric AlphanumericAnd* ``` referenced by: @@ -105,7 +109,7 @@ referenced by: ``` LongValueOption - ::= '--' Alphanumeric+ OptionValueDelimiter Value + ::= '--' Alphanumeric AlphanumericAnd* OptionValueDelimiter Value ``` referenced by: @@ -138,12 +142,26 @@ Alphanumeric referenced by: -- CmdIdentifier - 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) diff --git a/cli-args.md b/cli-args.md index cf0f959..be26819 100644 --- a/cli-args.md +++ b/cli-args.md @@ -15,6 +15,8 @@ The POSIX standard is often cited when designing command line interfaces. Howeve 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. @@ -65,23 +67,26 @@ A command MAY accept sub-commands, options, and operands. ## Formal Grammar -```grammar +```C Command ::= CmdIdentifier Command ::= CmdIdentifier Operand* Command ::= CmdIdentifier Option* Operand* -CmdIdentifier ::= Alphanumeric* +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 Alphanumeric* -LongValueOption ::= '--' Alphanumeric 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 )\* +Space ::= ( U+0020 )* Operand ::= Value ``` From 5611a136f0e70cf3853c6b6e0a1fb168be9384e5 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Wed, 22 Feb 2023 03:09:03 +0530 Subject: [PATCH 3/3] fix(cli-args): broken link --- cli-args.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli-args.md b/cli-args.md index be26819..6062166 100644 --- a/cli-args.md +++ b/cli-args.md @@ -90,4 +90,4 @@ Space ::= ( U+0020 )* Operand ::= Value ``` -This grammar is also available as a [railroad diagram](./assets/cli-railroad.md). +This grammar is also available as a [railroad diagram](./assets/cli-railroad/index.md).