Skip to content

Commit 031684d

Browse files
committed
Add dump_opt_long for #548
1 parent ff8af19 commit 031684d

File tree

8 files changed

+112
-97
lines changed

8 files changed

+112
-97
lines changed

base/hmain.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,69 @@ int parse_opt_long(int argc, char** argv, const option_t* long_options, int size
343343
return 0;
344344
}
345345

346+
int dump_opt_long(const option_t* long_options, int opt_size, char* out_str, int out_size) {
347+
/*
348+
* Usage: program_name [short_options]
349+
* Options:
350+
* -%c|--%s description
351+
* -%c|--%s <value> description
352+
* -%c|--%s [value] description
353+
*/
354+
int align = 0, max_align = 0;
355+
char short_options[256] = {0};
356+
char* p = short_options;
357+
for (int i = 0; i < opt_size; ++i) {
358+
if (long_options[i].short_opt > 0) {
359+
*p++ = long_options[i].short_opt;
360+
}
361+
if (long_options[i].arg_type == NO_ARGUMENT) {
362+
// " -%c|--%s "
363+
align = 9 + strlen(long_options[i].long_opt);
364+
} else {
365+
// " -%c|--%s <value> "
366+
align = 17 + strlen(long_options[i].long_opt);
367+
if (long_options[i].short_opt > 0) {
368+
*p++ = ':';
369+
}
370+
}
371+
if (align > max_align) max_align = align;
372+
}
373+
374+
int offset = 0;
375+
if (*g_main_ctx.program_name) {
376+
offset = snprintf(out_str, out_size, "Usage: %s [%s]\n", g_main_ctx.program_name, short_options);
377+
}
378+
offset += snprintf(out_str + offset, out_size - offset, "Options:\n");
379+
char short_opt_chars[4] = {0};
380+
for (int i = 0; i < opt_size; ++i) {
381+
if (long_options[i].short_opt > 0) {
382+
// -%c|
383+
short_opt_chars[0] = '-';
384+
short_opt_chars[1] = long_options[i].short_opt;
385+
short_opt_chars[2] = '|';
386+
} else {
387+
short_opt_chars[0] = ' ';
388+
short_opt_chars[1] = ' ';
389+
short_opt_chars[2] = ' ';
390+
}
391+
if (long_options[i].arg_type == NO_ARGUMENT) {
392+
// " -%c|--%s "
393+
align = 9 + strlen(long_options[i].long_opt);
394+
} else {
395+
// " -%c|--%s <value> "
396+
align = 17 + strlen(long_options[i].long_opt);
397+
}
398+
offset += snprintf(out_str + offset, out_size - offset, " %s--%s%s %*s%s\n",
399+
short_opt_chars,
400+
long_options[i].long_opt,
401+
long_options[i].arg_type == REQUIRED_ARGUMENT ? " <value>" :
402+
long_options[i].arg_type == OPTIONAL_ARGUMENT ? " [value]" : "",
403+
max_align - align, "",
404+
long_options[i].description ? long_options[i].description : "");
405+
}
406+
return offset;
407+
}
408+
346409
#if defined(OS_UNIX) && !HAVE_SETPROCTITLE
347410
/*
348411
* memory layout

base/hmain.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ typedef struct option_s {
6565
char short_opt;
6666
const char* long_opt;
6767
int arg_type;
68+
const char* description;
6869
} option_t;
6970

7071
HV_EXPORT int main_ctx_init(int argc, char** argv);
@@ -76,7 +77,8 @@ HV_EXPORT void main_ctx_free(void);
7677
// watch -n10 ls
7778
HV_EXPORT int parse_opt(int argc, char** argv, const char* opt);
7879
// gcc -g -Wall -O3 -std=cpp main.c
79-
HV_EXPORT int parse_opt_long(int argc, char** argv, const option_t* long_options, int size);
80+
HV_EXPORT int parse_opt_long(int argc, char** argv, const option_t* long_options, int opt_size);
81+
HV_EXPORT int dump_opt_long(const option_t* long_options, int opt_size, char* out_str, int out_size);
8082
HV_EXPORT const char* get_arg(const char* key);
8183
HV_EXPORT const char* get_env(const char* key);
8284

base/hplatform.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#undef OS_UNIX
4242
#define OS_WIN
4343
#else
44+
#undef OS_WIN
4445
#define OS_UNIX
4546
#endif
4647

docs/API.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@
269269
- main_ctx_init
270270
- parse_opt
271271
- parse_opt_long
272+
- dump_opt_long
272273
- get_arg
273274
- get_env
274275
- setproctitle

examples/hmain_test.cpp

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,36 +38,25 @@ static void print_help();
3838
static int parse_confile(const char* confile);
3939
static void worker_fn(void* userdata);
4040

41-
// short options
42-
static const char options[] = "hvc:ts:dp:";
4341
// long options
4442
static const option_t long_options[] = {
45-
{'h', "help", NO_ARGUMENT},
46-
{'v', "version", NO_ARGUMENT},
47-
{'c', "confile", REQUIRED_ARGUMENT},
48-
{'t', "test", NO_ARGUMENT},
49-
{'s', "signal", REQUIRED_ARGUMENT},
50-
{'d', "daemon", NO_ARGUMENT},
51-
{'p', "port", REQUIRED_ARGUMENT}
43+
{'h', "help", NO_ARGUMENT, "Print this information"},
44+
{'v', "version", NO_ARGUMENT, "Print version"},
45+
{'c', "confile", REQUIRED_ARGUMENT, "Set configure file, default etc/{program}.conf"},
46+
{'t', "test", NO_ARGUMENT, "Test configure file and exit"},
47+
{'s', "signal", REQUIRED_ARGUMENT, "send signal to process, signal=[start,stop,restart,status,reload]"},
48+
{'d', "daemon", NO_ARGUMENT, "Daemonize"},
49+
{'p', "port", REQUIRED_ARGUMENT, "Set listen port"}
5250
};
53-
static const char detail_options[] = R"(
54-
-h|--help Print this information
55-
-v|--version Print version
56-
-c|--confile <confile> Set configure file, default etc/{program}.conf
57-
-t|--test Test configure file and exit
58-
-s|--signal <signal> Send <signal> to process,
59-
<signal>=[start,stop,restart,status,reload]
60-
-d|--daemon Daemonize
61-
-p|--port <port> Set listen port
62-
)";
6351

6452
void print_version() {
6553
printf("%s version %s\n", g_main_ctx.program_name, hv_compile_version());
6654
}
6755

6856
void print_help() {
69-
printf("Usage: %s [%s]\n", g_main_ctx.program_name, options);
70-
printf("Options:\n%s\n", detail_options);
57+
char detail_options[1024] = {0};
58+
dump_opt_long(long_options, ARRAY_SIZE(long_options), detail_options, sizeof(detail_options));
59+
printf("%s\n", detail_options);
7160
}
7261

7362
int parse_confile(const char* confile) {
@@ -170,7 +159,6 @@ int main(int argc, char** argv) {
170159
print_help();
171160
exit(10);
172161
}
173-
// int ret = parse_opt(argc, argv, options);
174162
int ret = parse_opt_long(argc, argv, long_options, ARRAY_SIZE(long_options));
175163
if (ret != 0) {
176164
print_help();

examples/httpd/httpd.cpp

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,25 @@ static void print_help();
1616

1717
static int parse_confile(const char* confile);
1818

19-
// short options
20-
static const char options[] = "hvc:ts:dp:";
2119
// long options
2220
static const option_t long_options[] = {
23-
{'h', "help", NO_ARGUMENT},
24-
{'v', "version", NO_ARGUMENT},
25-
{'c', "confile", REQUIRED_ARGUMENT},
26-
{'t', "test", NO_ARGUMENT},
27-
{'s', "signal", REQUIRED_ARGUMENT},
28-
{'d', "daemon", NO_ARGUMENT},
29-
{'p', "port", REQUIRED_ARGUMENT}
21+
{'h', "help", NO_ARGUMENT, "Print this information"},
22+
{'v', "version", NO_ARGUMENT, "Print version"},
23+
{'c', "confile", REQUIRED_ARGUMENT, "Set configure file, default etc/{program}.conf"},
24+
{'t', "test", NO_ARGUMENT, "Test configure file and exit"},
25+
{'s', "signal", REQUIRED_ARGUMENT, "send signal to process, signal=[start,stop,restart,status,reload]"},
26+
{'d', "daemon", NO_ARGUMENT, "Daemonize"},
27+
{'p', "port", REQUIRED_ARGUMENT, "Set listen port"}
3028
};
31-
static const char detail_options[] = R"(
32-
-h|--help Print this information
33-
-v|--version Print version
34-
-c|--confile <confile> Set configure file, default etc/{program}.conf
35-
-t|--test Test configure file and exit
36-
-s|--signal <signal> Send <signal> to process,
37-
<signal>=[start,stop,restart,status,reload]
38-
-d|--daemon Daemonize
39-
-p|--port <port> Set listen port
40-
)";
4129

4230
void print_version() {
4331
printf("%s version %s\n", g_main_ctx.program_name, hv_compile_version());
4432
}
4533

4634
void print_help() {
47-
printf("Usage: %s [%s]\n", g_main_ctx.program_name, options);
48-
printf("Options:\n%s\n", detail_options);
35+
char detail_options[1024] = {0};
36+
dump_opt_long(long_options, ARRAY_SIZE(long_options), detail_options, sizeof(detail_options));
37+
printf("%s\n", detail_options);
4938
}
5039

5140
int parse_confile(const char* confile) {
@@ -275,7 +264,6 @@ static void on_reload(void* userdata) {
275264
int main(int argc, char** argv) {
276265
// g_main_ctx
277266
main_ctx_init(argc, argv);
278-
//int ret = parse_opt(argc, argv, options);
279267
int ret = parse_opt_long(argc, argv, long_options, ARRAY_SIZE(long_options));
280268
if (ret != 0) {
281269
print_help();

examples/kcptun/client/main.cpp

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,40 +27,27 @@ static int mtu = 1350;
2727
static int sndwnd = 128;
2828
static int rcvwnd = 512;
2929

30-
// short options
31-
static const char options[] = "hvdl:r:m:";
3230
// long options
3331
static const option_t long_options[] = {
34-
{'h', "help", NO_ARGUMENT},
35-
{'v', "version", NO_ARGUMENT},
36-
{'d', "daemon", NO_ARGUMENT},
37-
{'l', "localaddr", REQUIRED_ARGUMENT},
38-
{'r', "remoteaddr", REQUIRED_ARGUMENT},
39-
{'m', "mode", REQUIRED_ARGUMENT},
40-
{ 0, "mtu", REQUIRED_ARGUMENT},
41-
{ 0, "sndwnd", REQUIRED_ARGUMENT},
42-
{ 0, "rcvwnd", REQUIRED_ARGUMENT},
32+
{'h', "help", NO_ARGUMENT, "Print this information"},
33+
{'v', "version", NO_ARGUMENT, "Print version"},
34+
{'d', "daemon", NO_ARGUMENT, "Daemonize"},
35+
{'l', "localaddr", REQUIRED_ARGUMENT, "local listen address (default: \":8388\")"},
36+
{'r', "remoteaddr", REQUIRED_ARGUMENT, "kcp server address (default: \"127.0.0.1:4000\")"},
37+
{'m', "mode", REQUIRED_ARGUMENT, "profiles: fast3, fast2, fast, normal, (default: \"fast\")"},
38+
{ 0, "mtu", REQUIRED_ARGUMENT, "set maxinum transmission unit for UDP packets (default: 1350)"},
39+
{ 0, "sndwnd", REQUIRED_ARGUMENT, "set send window size(num of packets) (default: 128)"},
40+
{ 0, "rcvwnd", REQUIRED_ARGUMENT, "set receive window size(num of packets) (default: 512)"},
4341
};
4442

45-
static const char detail_options[] = R"(
46-
-h|--help Print this information
47-
-v|--version Print version
48-
-d|--daemon Daemonize
49-
-l|--localaddr value local listen address (default: ":8388")
50-
-r|--remoteaddr value kcp server address (default: "127.0.0.1:4000")
51-
-m|--mode value profiles: fast3, fast2, fast, normal (default: "fast")
52-
--mtu value set maximum transmission unit for UDP packets (default: 1350)
53-
--sndwnd value set send window size(num of packets) (default: 128)
54-
--rcvwnd value set receive window size(num of packets) (default: 512)
55-
)";
56-
5743
static void print_version() {
5844
printf("%s version %s\n", g_main_ctx.program_name, hv_compile_version());
5945
}
6046

6147
static void print_help() {
62-
printf("Usage: %s [%s]\n", g_main_ctx.program_name, options);
63-
printf("Options:\n%s\n", detail_options);
48+
char detail_options[1024] = {0};
49+
dump_opt_long(long_options, ARRAY_SIZE(long_options), detail_options, sizeof(detail_options));
50+
printf("%s\n", detail_options);
6451
}
6552

6653
static char listen_host[64] = "0.0.0.0";
@@ -260,7 +247,6 @@ int main(int argc, char** argv) {
260247

261248
// g_main_ctx
262249
main_ctx_init(argc, argv);
263-
//int ret = parse_opt(argc, argv, options);
264250
int ret = parse_opt_long(argc, argv, long_options, ARRAY_SIZE(long_options));
265251
if (ret != 0) {
266252
print_help();

examples/kcptun/server/main.cpp

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,40 +26,27 @@ static int mtu = 1350;
2626
static int sndwnd = 1024;
2727
static int rcvwnd = 1024;
2828

29-
// short options
30-
static const char options[] = "hvdl:t:m:";
3129
// long options
3230
static const option_t long_options[] = {
33-
{'h', "help", NO_ARGUMENT},
34-
{'v', "version", NO_ARGUMENT},
35-
{'d', "daemon", NO_ARGUMENT},
36-
{'l', "listen", REQUIRED_ARGUMENT},
37-
{'t', "target", REQUIRED_ARGUMENT},
38-
{'m', "mode", REQUIRED_ARGUMENT},
39-
{ 0, "mtu", REQUIRED_ARGUMENT},
40-
{ 0, "sndwnd", REQUIRED_ARGUMENT},
41-
{ 0, "rcvwnd", REQUIRED_ARGUMENT},
31+
{'h', "help", NO_ARGUMENT, "Print this information"},
32+
{'v', "version", NO_ARGUMENT, "Print version"},
33+
{'d', "daemon", NO_ARGUMENT, "Daemonize"},
34+
{'l', "listen", REQUIRED_ARGUMENT, "kcp server listen address (default: \":4000\")"},
35+
{'t', "target", REQUIRED_ARGUMENT, "target server address (default: \"127.0.0.1:8080\")"},
36+
{'m', "mode", REQUIRED_ARGUMENT, "profiles: fast3, fast2, fast, normal, (default: \"fast\")"},
37+
{ 0, "mtu", REQUIRED_ARGUMENT, "set maxinum transmission unit for UDP packets (default: 1350)"},
38+
{ 0, "sndwnd", REQUIRED_ARGUMENT, "set send window size(num of packets) (default: 1024)"},
39+
{ 0, "rcvwnd", REQUIRED_ARGUMENT, "set receive window size(num of packets) (default: 1024)"},
4240
};
4341

44-
static const char detail_options[] = R"(
45-
-h|--help Print this information
46-
-v|--version Print version
47-
-d|--daemon Daemonize
48-
-l|--listen value kcp server listen address (default: ":4000")
49-
-t|--target value target server address (default: "127.0.0.1:8080")
50-
-m|--mode value profiles: fast3, fast2, fast, normal (default: "fast")
51-
--mtu value set maximum transmission unit for UDP packets (default: 1350)
52-
--sndwnd value set send window size(num of packets) (default: 1024)
53-
--rcvwnd value set receive window size(num of packets) (default: 1024)
54-
)";
55-
5642
static void print_version() {
5743
printf("%s version %s\n", g_main_ctx.program_name, hv_compile_version());
5844
}
5945

6046
static void print_help() {
61-
printf("Usage: %s [%s]\n", g_main_ctx.program_name, options);
62-
printf("Options:\n%s\n", detail_options);
47+
char detail_options[1024] = {0};
48+
dump_opt_long(long_options, ARRAY_SIZE(long_options), detail_options, sizeof(detail_options));
49+
printf("%s\n", detail_options);
6350
}
6451

6552
static kcp_setting_t s_kcp_setting;
@@ -237,7 +224,6 @@ int main(int argc, char** argv) {
237224

238225
// g_main_ctx
239226
main_ctx_init(argc, argv);
240-
//int ret = parse_opt(argc, argv, options);
241227
int ret = parse_opt_long(argc, argv, long_options, ARRAY_SIZE(long_options));
242228
if (ret != 0) {
243229
print_help();

0 commit comments

Comments
 (0)