<commit_before># Command Line Parser

## Summary

For command line parsing the POSIX `getopt` and `getopt_long` are available.
Those functions have several downsides:

 * Are not available on all platforms (Windows).
 * Are error prone to use. The user has to consider all conversion edge cases
    and verify the syntax.
 * Are hard to use and the API is hard to read.
 * One has to write a lot of code to use them, even for minimal problems.
 * How the help is shown, how the help is formatted and certain syntax decision
    can vary from binary to binary in iceoryx. A unified appearance and usage
    across all applications would increase the user experience.

Since we would like to offer command line support on all platforms we either
have to rewrite `getopt` and `getopt_long` from scratch or write a modern C++
alternative.

## Terminology

| Name              | Description                                              |
| :---------------- | :------------------------------------------------------- |
| switch            | When provided as argument the switch is activated, see `-h` and `--help`. A boolean signals to the user whether the switch was provided (activated) or not. |
| optional value    | A value which can be provided via command line but is not required. Every optional value requires a default value. |
| required value    | A value which has to be provided via command line. Does not require a default value. |
| argc & argv       | Taken from `int main(int argc, char* argv[])`. Provides access to the command line arguments. |
| short option      | Consists of a minus followed by a non minus symbol, see `-h` or `-a 123`. |
| long option       | Has a double minus prefix followed by a string, see `--help` or `--set-thing 123` |

## Design

### Considerations

The solution shall be:

 * easy to use by the developer
 * provide a unified appearance and syntax in all applications with command line arguments
    * the help must be generated by the parser
    * the help shall contain the type if an argument requires a value
    * the syntax is defined by the parser not the developer as much as possible
 * shall be type safe when command line arguments are converted to types like `int` or `float`
    * underflow, overflow shall be handled
    * a detailed error explanation shall be presented to the user when cast fails

### Solution

#### Class Diagram

```
+----------------------------------------------+  Task:
| CommandLineParser                            |     * extract user defined values as string from command line
|                                              |     * "parse" creates a CommandLineOptions object through
|  - CommandLineParser & addSwitch(...)        |         which those values can be accessed
|  - CommandLineParser & addOptionalValue(...) |     * it generates the help output based on the provided user
|  - CommandLineParser & addRequiredValue(...) |         arguments and prints it on syntax failure or user
|                                              |         request (-h or --help)
|  - CommandLineOptions parse(argc, argv, ...) |
+----------------------------------------------+
                      |
                      | creates CommandLineOptions
                     \ /
+----------------------------------------------+  Task:
| CommandLineOptions                           |     * provides a type safe access to the user defined command
|                                              |         line values with `get`, `has` or `binaryName`
|  +----------------------------+              |
|  | Result [enum class]        |              |
|  |  # UNABLE_TO_CONVERT_VALUE |              |
|  |  # NO_SUCH_VALUE           |              |
|  +----------------------------+              |
|                                              |
|  - template<typename T>                      |
|    cxx::expected<T, Result> get(optionName)  |
|  - bool has(switchName)                      |
|  - binaryName_t binaryName()                 |
|                                              |
+----------------------------------------------+
```

#### Macro Based Code Generator

The macros `COMMAND_LINE`, `SWITCH`, `OPTIONAL_VALUE` and `REQUIRED_VALUE`
provide building blocks so that the user can generate a struct. The members of that
struct are defined via the macros and set in the constructor of that struct which
will use `CommandLineParser` and `CommandLineOptions` to parse and extract the
values safely.

The struct constructor can be called with `argc` and `argv` as arguments from 
`int main(int argc, char* argv[])`.

### Code example

```cpp
struct CommandLine
{<commit_msg>iox-#1067 Add sequence diagram to command line parser design doc<commit_after># Command Line Parser

## Summary

For command line parsing the POSIX `getopt` and `getopt_long` are available.
Those functions have several downsides:

 * Are not available on all platforms (Windows).
 * Are error prone to use. The user has to consider all conversion edge cases
    and verify the syntax.
 * Are hard to use and the API is hard to read.
 * One has to write a lot of code to use them, even for minimal problems.
 * How the help is shown, how the help is formatted and certain syntax decision
    can vary from binary to binary in iceoryx. A unified appearance and usage
    across all applications would increase the user experience.

Since we would like to offer command line support on all platforms we either
have to rewrite `getopt` and `getopt_long` from scratch or write a modern C++
alternative.

## Terminology

| Name              | Description                                              |
| :---------------- | :------------------------------------------------------- |
| switch            | When provided as argument the switch is activated, see `-h` and `--help`. A boolean signals to the user whether the switch was provided (activated) or not. |
| optional value    | A value which can be provided via command line but is not required. Every optional value requires a default value. |
| required value    | A value which has to be provided via command line. Does not require a default value. |
| argc & argv       | Taken from `int main(int argc, char* argv[])`. Provides access to the command line arguments. |
| short option      | Consists of a minus followed by a non minus symbol, see `-h` or `-a 123`. |
| long option       | Has a double minus prefix followed by a string, see `--help` or `--set-thing 123` |

## Design

### Considerations

The solution shall be:

 * easy to use by the developer
 * provide a unified appearance and syntax in all applications with command line arguments
    * the help must be generated by the parser
    * the help shall contain the type if an argument requires a value
    * the syntax is defined by the parser not the developer as much as possible
 * shall be type safe when command line arguments are converted to types like `int` or `float`
    * underflow, overflow shall be handled
    * a detailed error explanation shall be presented to the user when cast fails

### Solution

#### Class Diagram

```
+----------------------------------------------+  Task:
| CommandLineParser                            |     * extract user defined values as string from command line
|                                              |     * "parse" creates a CommandLineOptions object through
|  - CommandLineParser & addSwitch(...)        |         which those values can be accessed
|  - CommandLineParser & addOptionalValue(...) |     * it generates the help output based on the provided user
|  - CommandLineParser & addRequiredValue(...) |         arguments and prints it on syntax failure or user
|                                              |         request (-h or --help)
|  - CommandLineOptions parse(argc, argv, ...) |
+----------------------------------------------+
                      |
                      | creates CommandLineOptions
                     \ /
+----------------------------------------------+  Task:
| CommandLineOptions                           |     * provides a type safe access to the user defined command
|                                              |         line values with `get`, `has` or `binaryName`
|  +----------------------------+              |
|  | Result [enum class]        |              |
|  |  # UNABLE_TO_CONVERT_VALUE |              |
|  |  # NO_SUCH_VALUE           |              |
|  +----------------------------+              |
|                                              |
|  - template<typename T>                      |
|    cxx::expected<T, Result> get(optionName)  |
|  - bool has(switchName)                      |
|  - binaryName_t binaryName()                 |
|                                              |
+----------------------------------------------+
```

#### Sequence Diagram

Lets assume we would like to add a switch, an optional and a required value, parse
them and print them on the console.

```
  User
   |  CommandLineParser()    CommandLineParser
   | ------------------------------> |
   |                                 |
   |    addSwitch()                  |
   | ------------------------------> |
   |                                 |
   |    addOptionalValue()           |
   | ------------------------------> |
   |                                 |
   |    addRequiredValue()           |
   | ------------------------------> |
   |                                 |
   |    parse()                      |
   | ------------------------------> |
   |    CommandLineOptions                   CommandLineOptions
   |                                                 |
   |                has(switchName)                  |
   | ----------------------------------------------> |
   |                bool                             |
   |                                                 |
   |                get<TypeName>(optionalValueName) |
   | ----------------------------------------------> |
   |                TypeName                         |
   |                                                 |
   |                get<TypeName>(requiredValueName) |
   | ----------------------------------------------> |
   |                TypeName                         |
```

#### Macro Based Code Generator

The macros `COMMAND_LINE`, `SWITCH`, `OPTIONAL_VALUE` and `REQUIRED_VALUE`
provide building blocks so that the user can generate a struct. The members of that
struct are defined via the macros and set in the constructor of that struct which
will use `CommandLineParser` and `CommandLineOptions` to parse and extract the
values safely.

The struct constructor can be called with `argc` and `argv` as arguments from 
`int main(int argc, char* argv[])`.

### Code example

```cpp
struct CommandLine
{
{'fraction_non_alphanumeric': 0.15036968576709797, 'fraction_numerical': 0.0014787430683918669, 'mean_word_length': 1.422431161853593, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 39, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6254061', 'n_tokens_mistral': 2392, 'n_tokens_neox': 2308, 'n_words': 1081}