(command-line-interface)=
# Command-line interface

:::{wpd} command-line interface
a means of interacting with software via commands. Also called command-line shell.
:::

(main-arguments)=
## `main` arguments

:::{literalinclude} ../code-wi/main-arguments.c
:language: c
:::
:::{command-output} code-wi/main-arguments.exe geko --1 🦎
:::

:::{card} 🤔 Question to ponder
Three arguments are provided to `main-arguments.exe`. But why do we see 4 lines that are printed?
:::
:::{activity} Basic CLI
Create a program that accepts any number of words as arguments and prints them back as a single, space-separated string in reverse order (last argument printed first), but only if the verb is `reverse`. Otherwise it prints usage:
```
$ ./main reverse a b c
c b a
$ ./main a b c
Usage: ./main reverse STRING1 STRING2 ...
```
:::

(exit-status)=
## Exit status

If `main` returns, then the program exits. The program can communicate a status to the command line interface by returning a corresponding integer called *exit status*.

:::{wpd} exit status
an integer returned by a terminated program that is made available to its caller, e.g., the command line interface. 
:::

Every function with a return type other than `void` must return a value. However, `main` is special. If no return value is not specified, it returns automatically `return 0`:

```c
int main() {}
```

:::{list-table}
:header-rows: 1
- * exit code
  * meaning
- * `EXIT_SUCCESS` or 0
  * successful termination
- * `EXIT_FAILURE` or 1
  * unsuccessful termination
- * any `int` other than {0, 1}
  * unsuccessful termination with a special meaning
:::

## CLI design

[Here](https://clig.dev/#help) are good examples for CLI programs.

## VS Code considerations

You cannot use <kbd>F5</kbd> directly, because our program's runtime is now dependent on arguments. There are two solutions:

1. Only build using <kbd>Ctrl</kbd><kbd>Shift</kbd><kbd>b</kbd>. Then run manually on the command line:

   ```sh
   ./main e caesar LEVE
   ```

2. You change `launch.json` to cater for command-line arguments, e.g.,

   ```json
   {
   "version": "0.2.0",
   "configurations": [
     {
       // ...
       "program": "${workspaceFolder}/main",
       "args": [
         "${input:verb}",
         "${input:cipher}",
         "${input:plaintext}"
       ],
       // ...
     }
   ],
   "inputs": [
     {
       "id": "verb",
       "type": "promptString",
       "description": "Enter verb"
     },
     // ...
    ]
   ```