Skip to content

Commit 8083b9e

Browse files
committed
CLI help text refactoring to better match http://docopt.org/ standard
1 parent 1a51c11 commit 8083b9e

File tree

14 files changed

+183
-99
lines changed

14 files changed

+183
-99
lines changed

services/cli/cli.c

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,43 @@
22

33
#include "cli.h"
44
#include <lib/toolbox/args.h>
5-
#include "cli_common_helpers.h"
5+
#include "cli_helpers.h"
66
#include "commands/list/list.h"
77
#include "commands/add/add.h"
88
#include "commands/delete/delete.h"
99
#include "commands/timezone/timezone.h"
10-
11-
#define TOTP_CLI_COMMAND_NAME "totp"
12-
#define TOTP_CLI_COMMAND_HELP "help"
10+
#include "commands/help/help.h"
1311

1412
static void totp_cli_print_unknown_command(FuriString* unknown_command) {
1513
TOTP_CLI_PRINTF(
16-
"Command \"%s\" is unknown. Use \"help\" command to get list of available commands.",
14+
"Command \"%s\" is unknown. Use \"" TOTP_CLI_COMMAND_HELP "\" command to get list of available commands.",
1715
furi_string_get_cstr(unknown_command));
1816
}
1917

20-
static void totp_cli_print_help() {
21-
TOTP_CLI_PRINTF("Usage:\r\n");
22-
TOTP_CLI_PRINTF(TOTP_CLI_COMMAND_NAME " <command> <arguments>\r\n");
23-
TOTP_CLI_PRINTF("Command list:\r\n");
24-
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_HELP " - print command usage help\r\n\r\n");
25-
totp_cli_command_list_print_help();
26-
totp_cli_command_delete_print_help();
27-
totp_cli_command_add_print_help();
28-
totp_cli_command_timezone_print_help();
29-
}
30-
3118
static void totp_cli_handler(Cli* cli, FuriString* args, void* context) {
3219
PluginState* plugin_state = (PluginState*)context;
3320

3421
FuriString* cmd = furi_string_alloc();
3522

3623
args_read_string_and_trim(args, cmd);
3724

38-
if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_HELP) == 0 || furi_string_empty(cmd)) {
39-
totp_cli_print_help();
40-
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_ADD) == 0) {
25+
if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_HELP) == 0 ||
26+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_HELP_ALT) == 0 ||
27+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_HELP_ALT2) == 0 ||
28+
furi_string_empty(cmd)) {
29+
totp_cli_command_help_handle();
30+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_ADD) == 0 ||
31+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_ADD_ALT) == 0 ||
32+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_ADD_ALT2) == 0) {
4133
totp_cli_command_add_handle(plugin_state, args, cli);
42-
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST) == 0) {
34+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST) == 0 ||
35+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_LIST_ALT) == 0) {
4336
totp_cli_command_list_handle(plugin_state, cli);
44-
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE) == 0) {
37+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE) == 0 ||
38+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_DELETE_ALT) == 0) {
4539
totp_cli_command_delete_handle(plugin_state, args, cli);
46-
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_TIMEZONE) == 0) {
40+
} else if(furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_TIMEZONE) == 0 ||
41+
furi_string_cmp_str(cmd, TOTP_CLI_COMMAND_TIMEZONE_ALT) == 0) {
4742
totp_cli_command_timezone_handle(plugin_state, args, cli);
4843
} else {
4944
totp_cli_print_unknown_command(cmd);

services/cli/cli_common_helpers.h

Lines changed: 0 additions & 17 deletions
This file was deleted.

services/cli/cli_common_helpers.c renamed to services/cli/cli_helpers.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
1-
#include "cli_common_helpers.h"
1+
#include "cli_helpers.h"
22
#include <cli/cli.h>
33

4-
void totp_cli_print_invalid_arguments() {
5-
TOTP_CLI_PRINTF(
6-
"Invalid command arguments. use \"help\" command to get list of available commands");
7-
}
8-
94
bool totp_cli_ensure_authenticated(PluginState* plugin_state, Cli* cli) {
105
if(plugin_state->current_scene == TotpSceneAuthentication) {
116
TOTP_CLI_PRINTF("Pleases enter PIN on your flipper device\r\n");
127

138
while(plugin_state->current_scene == TotpSceneAuthentication &&
149
!cli_cmd_interrupt_received(cli)) {
15-
furi_delay_tick(0);
10+
furi_delay_ms(100);
1611
}
1712

18-
TOTP_CLI_PRINTF("\033[A\33[2K\r");
13+
TOTP_CLI_DELETE_LAST_LINE();
1914
fflush(stdout);
2015

2116
if(plugin_state->current_scene == TotpSceneAuthentication) {

services/cli/cli_helpers.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <cli/cli.h>
4+
#include "../../types/plugin_state.h"
5+
6+
#define TOTP_CLI_COMMAND_NAME "totp"
7+
8+
#define DOCOPT_ARGUMENT(arg) "<" arg ">"
9+
#define DOCOPT_OPTIONAL(param) "[" param "]"
10+
#define DOCOPT_REQUIRED(param) "(" param ")"
11+
#define DOCOPT_OPTION(option, value) option " " value
12+
#define DOCOPT_SWITCH(option) option
13+
#define DOCOPT_OPTIONS "[options]"
14+
#define DOCOPT_DEFAULT(val) "[default: " val "]"
15+
16+
#define TOTP_CLI_PRINTF(format, ...) \
17+
_Pragma(STRINGIFY(GCC diagnostic push)); \
18+
_Pragma(STRINGIFY(GCC diagnostic ignored "-Wdouble-promotion")); \
19+
printf(format, ##__VA_ARGS__); \
20+
_Pragma(STRINGIFY(GCC diagnostic pop));
21+
22+
#define TOTP_CLI_DELETE_LAST_LINE() TOTP_CLI_PRINTF("\033[A\33[2K\r")
23+
#define TOTP_CLI_DELETE_CURRENT_LINE() TOTP_CLI_PRINTF("\33[2K\r")
24+
#define TOTP_CLI_PRINT_INVALID_ARGUMENTS() TOTP_CLI_PRINTF("Invalid command arguments. use \"help\" command to get list of available commands")
25+
26+
bool totp_cli_ensure_authenticated(PluginState* plugin_state, Cli* cli);

services/cli/commands/add/add.c

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
#include "../../../list/list.h"
55
#include "../../../../types/token_info.h"
66
#include "../../../config/config.h"
7-
#include "../../cli_common_helpers.h"
7+
#include "../../cli_helpers.h"
88
#include "../../../../scenes/scene_director.h"
99

10-
#define TOTP_CLI_COMMAND_ADD_ARG_NAME "NAME"
11-
#define TOTP_CLI_COMMAND_ADD_ARG_ALGO "ALGO"
10+
#define TOTP_CLI_COMMAND_ADD_ARG_NAME "name"
11+
#define TOTP_CLI_COMMAND_ADD_ARG_ALGO "algo"
1212
#define TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX "-a"
13-
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS "DIGITS"
13+
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS "digits"
1414
#define TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX "-d"
1515
#define TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX "-u"
1616

@@ -46,22 +46,26 @@ static bool token_info_set_algo_from_str(TokenInfo* token_info, FuriString* str)
4646
return false;
4747
}
4848

49-
void totp_cli_command_add_print_help() {
50-
TOTP_CLI_PRINTF("\t" TOTP_CLI_COMMAND_ADD " " TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_NAME) " " TOTP_CLI_OPTIONAL_PARAM(
51-
TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX " " TOTP_CLI_ARG(
52-
TOTP_CLI_COMMAND_ADD_ARG_ALGO)) " " TOTP_CLI_OPTIONAL_PARAM(TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX
53-
" " TOTP_CLI_ARG(
54-
TOTP_CLI_COMMAND_ADD_ARG_DIGITS)) " " TOTP_CLI_OPTIONAL_PARAM(TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX) " - add new token\r\n");
55-
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_ADD_ARG_NAME) " - token name\r\n");
56-
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(
57-
TOTP_CLI_COMMAND_ADD_ARG_ALGO) " - " TOTP_CLI_OPTIONAL_PARAM_MARK
58-
" token hashing algorithm, could be one of: sha1, sha256, sha512; default: sha1\r\n");
59-
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_ARG(
60-
TOTP_CLI_COMMAND_ADD_ARG_DIGITS) " - " TOTP_CLI_OPTIONAL_PARAM_MARK
61-
" number of digits to generate, one of: 6, 8; default: 6\r\n");
62-
TOTP_CLI_PRINTF(
63-
"\t\t" TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX " - " TOTP_CLI_OPTIONAL_PARAM_MARK
64-
" to show console user input as-is without masking; default: show masked\r\n\r\n");
49+
void totp_cli_command_add_docopt_commands() {
50+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD ", " TOTP_CLI_COMMAND_ADD_ALT ", " TOTP_CLI_COMMAND_ADD_ALT2 " Add new token\r\n");
51+
}
52+
53+
void totp_cli_command_add_docopt_usage() {
54+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_ADD " | " TOTP_CLI_COMMAND_ADD_ALT " | " TOTP_CLI_COMMAND_ADD_ALT2) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_NAME) " "
55+
DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_ALGO))) " "
56+
DOCOPT_OPTIONAL(DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_DIGITS))) " "
57+
DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX))"\r\n");
58+
}
59+
60+
void totp_cli_command_add_docopt_arguments() {
61+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_ADD_ARG_NAME " Token name\r\n");
62+
}
63+
64+
void totp_cli_command_add_docopt_options() {
65+
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_ALGO_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_ALGO)) " Token hashing algorithm.\r\n");
66+
TOTP_CLI_PRINTF(" Could be one of: sha1, sha256, sha512 " DOCOPT_DEFAULT("sha1") "\r\n");
67+
TOTP_CLI_PRINTF(" " DOCOPT_OPTION(TOTP_CLI_COMMAND_ADD_ARG_DIGITS_PREFIX, DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_ADD_ARG_DIGITS))" Number of digits to generate, one of: 6, 8 " DOCOPT_DEFAULT("6") "\r\n");
68+
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(TOTP_CLI_COMMAND_ADD_ARG_UNSECURE_PREFIX) " Show console user input as-is without masking\r\n");
6569
}
6670

6771
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
@@ -72,7 +76,7 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
7276

7377
// Reading token name
7478
if(!args_read_probably_quoted_string_and_trim(args, temp_str)) {
75-
totp_cli_print_invalid_arguments();
79+
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
7680
furi_string_free(temp_str);
7781
token_info_free(token_info);
7882
return;
@@ -117,7 +121,7 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
117121
}
118122

119123
if(!parsed) {
120-
totp_cli_print_invalid_arguments();
124+
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
121125
furi_string_free(temp_str);
122126
token_info_free(token_info);
123127
return;
@@ -126,7 +130,7 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
126130

127131
// Reading token secret
128132
furi_string_reset(temp_str);
129-
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]:\r\n");
133+
TOTP_CLI_PRINTF("Enter token secret and confirm with [ENTER]\r\n");
130134

131135
uint8_t c;
132136
while(cli_read(cli, &c, 1) == 1) {
@@ -135,6 +139,7 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
135139
cli_read_timeout(cli, &c2, 1, 0);
136140
cli_read_timeout(cli, &c2, 1, 0);
137141
} else if(c == CliSymbolAsciiETX) {
142+
TOTP_CLI_DELETE_CURRENT_LINE();
138143
TOTP_CLI_PRINTF("Cancelled by user");
139144
furi_string_free(temp_str);
140145
token_info_free(token_info);
@@ -162,6 +167,8 @@ void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cl
162167

163168
temp_cstr = furi_string_get_cstr(temp_str);
164169

170+
TOTP_CLI_DELETE_LAST_LINE();
171+
165172
if(!totp_cli_ensure_authenticated(plugin_state, cli)) {
166173
furi_string_free(temp_str);
167174
token_info_free(token_info);

services/cli/commands/add/add.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
#include "../../../../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_ADD "add"
7+
#define TOTP_CLI_COMMAND_ADD_ALT "mk"
8+
#define TOTP_CLI_COMMAND_ADD_ALT2 "new"
79

810
void totp_cli_command_add_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
9-
void totp_cli_command_add_print_help();
11+
void totp_cli_command_add_docopt_commands();
12+
void totp_cli_command_add_docopt_usage();
13+
void totp_cli_command_add_docopt_arguments();
14+
void totp_cli_command_add_docopt_options();

services/cli/commands/delete/delete.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,34 @@
55
#include <lib/toolbox/args.h>
66
#include "../../../list/list.h"
77
#include "../../../config/config.h"
8-
#include "../../cli_common_helpers.h"
8+
#include "../../cli_helpers.h"
99
#include "../../../../scenes/scene_director.h"
1010

11-
#define TOTP_CLI_COMMAND_DELETE_ARG_INDEX "INDEX"
11+
#define TOTP_CLI_COMMAND_DELETE_ARG_INDEX "index"
1212
#define TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX "-f"
1313

14-
void totp_cli_command_delete_print_help() {
15-
TOTP_CLI_PRINTF(
16-
"\t" TOTP_CLI_COMMAND_DELETE
17-
" " TOTP_CLI_ARG(TOTP_CLI_COMMAND_DELETE_ARG_INDEX) " " TOTP_CLI_OPTIONAL_PARAM(
18-
TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX) " - delete token\r\n");
19-
TOTP_CLI_PRINTF(
20-
"\t\t" TOTP_CLI_ARG(TOTP_CLI_COMMAND_DELETE_ARG_INDEX) " - token index in the list\r\n");
21-
TOTP_CLI_PRINTF("\t\t" TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX
22-
" - " TOTP_CLI_OPTIONAL_PARAM_MARK
23-
" force command to do not ask user for interactive confirmation\r\n\r\n");
14+
void totp_cli_command_delete_docopt_commands() {
15+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_DELETE ", " TOTP_CLI_COMMAND_DELETE_ALT " Delete existing token\r\n");
16+
}
17+
18+
void totp_cli_command_delete_docopt_usage() {
19+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_DELETE " | " TOTP_CLI_COMMAND_DELETE_ALT) " " DOCOPT_ARGUMENT(TOTP_CLI_COMMAND_DELETE_ARG_INDEX) " "
20+
DOCOPT_OPTIONAL(DOCOPT_SWITCH(TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX)) "\r\n");
21+
}
22+
23+
void totp_cli_command_delete_docopt_arguments() {
24+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_DELETE_ARG_INDEX " Token index in the list\r\n");
25+
}
26+
27+
void totp_cli_command_delete_docopt_options() {
28+
TOTP_CLI_PRINTF(" " DOCOPT_SWITCH(TOTP_CLI_COMMAND_DELETE_ARG_FORCE_SUFFIX) " Force command to do not ask user for interactive confirmation\r\n");
2429
}
2530

2631
void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli) {
2732
int token_number;
2833
if(!args_read_int_and_trim(args, &token_number) || token_number <= 0 ||
2934
token_number > plugin_state->tokens_count) {
30-
totp_cli_print_invalid_arguments();
35+
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
3136
return;
3237
}
3338

@@ -38,7 +43,7 @@ void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args,
3843
confirm_needed = false;
3944
} else {
4045
TOTP_CLI_PRINTF("Unknown argument \"%s\"\r\n", furi_string_get_cstr(temp_str));
41-
totp_cli_print_invalid_arguments();
46+
TOTP_CLI_PRINT_INVALID_ARGUMENTS();
4247
furi_string_free(temp_str);
4348
return;
4449
}

services/cli/commands/delete/delete.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include "../../../../types/plugin_state.h"
55

66
#define TOTP_CLI_COMMAND_DELETE "delete"
7+
#define TOTP_CLI_COMMAND_DELETE_ALT "rm"
78

89
void totp_cli_command_delete_handle(PluginState* plugin_state, FuriString* args, Cli* cli);
9-
void totp_cli_command_delete_print_help();
10+
void totp_cli_command_delete_docopt_commands();
11+
void totp_cli_command_delete_docopt_usage();
12+
void totp_cli_command_delete_docopt_arguments();
13+
void totp_cli_command_delete_docopt_options();

services/cli/commands/help/help.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "help.h"
2+
#include "../../cli_helpers.h"
3+
#include "../add/add.h"
4+
#include "../delete/delete.h"
5+
#include "../list/list.h"
6+
#include "../timezone/timezone.h"
7+
8+
void totp_cli_command_help_docopt_commands() {
9+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_HELP ", " TOTP_CLI_COMMAND_HELP_ALT ", " TOTP_CLI_COMMAND_HELP_ALT2 " Show command usage help\r\n");
10+
}
11+
12+
void totp_cli_command_help_docopt_usage() {
13+
TOTP_CLI_PRINTF(" " TOTP_CLI_COMMAND_NAME " " DOCOPT_REQUIRED(TOTP_CLI_COMMAND_HELP " | " TOTP_CLI_COMMAND_HELP_ALT " | " TOTP_CLI_COMMAND_HELP_ALT2) "\r\n");
14+
}
15+
16+
void totp_cli_command_help_handle() {
17+
TOTP_CLI_PRINTF("Usage:\r\n");
18+
totp_cli_command_help_docopt_usage();
19+
totp_cli_command_list_docopt_usage();
20+
totp_cli_command_add_docopt_usage();
21+
totp_cli_command_delete_docopt_usage();
22+
totp_cli_command_timezone_docopt_usage();
23+
cli_nl();
24+
TOTP_CLI_PRINTF("Commands:\r\n");
25+
totp_cli_command_help_docopt_commands();
26+
totp_cli_command_list_docopt_commands();
27+
totp_cli_command_add_docopt_commands();
28+
totp_cli_command_delete_docopt_commands();
29+
totp_cli_command_timezone_docopt_commands();
30+
cli_nl();
31+
TOTP_CLI_PRINTF("Arguments:\r\n");
32+
totp_cli_command_add_docopt_arguments();
33+
totp_cli_command_delete_docopt_arguments();
34+
totp_cli_command_timezone_docopt_arguments();
35+
cli_nl();
36+
TOTP_CLI_PRINTF("Options:\r\n");
37+
totp_cli_command_add_docopt_options();
38+
totp_cli_command_delete_docopt_options();
39+
}

services/cli/commands/help/help.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#pragma once
2+
3+
#include <cli/cli.h>
4+
5+
#define TOTP_CLI_COMMAND_HELP "help"
6+
#define TOTP_CLI_COMMAND_HELP_ALT "h"
7+
#define TOTP_CLI_COMMAND_HELP_ALT2 "?"
8+
9+
void totp_cli_command_help_handle();
10+
void totp_cli_command_help_docopt_commands();
11+
void totp_cli_command_help_docopt_usage();

0 commit comments

Comments
 (0)