From 667fd14abb591810e7c617a68e99510ec3b2985b Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Mon, 24 May 2021 20:33:56 +0800 Subject: [PATCH] parse cmd options strictly --- src/sf_types.h | 7 ++++ src/sf_util.c | 92 +++++++++++++++++++++++++++++++++++++++----------- src/sf_util.h | 40 ++++++---------------- 3 files changed, 90 insertions(+), 49 deletions(-) diff --git a/src/sf_types.h b/src/sf_types.h index 7f0b8cc..b75e511 100644 --- a/src/sf_types.h +++ b/src/sf_types.h @@ -200,6 +200,13 @@ typedef struct sf_key_value_array { int alloc; } SFKeyValueArray; +typedef struct sf_cmd_option { + string_t name; + int val; + bool has_arg; + const char *desc; +} SFCMDOption; + typedef enum sf_server_group_index_type { sf_server_group_index_type_cluster = 1, sf_server_group_index_type_service diff --git a/src/sf_util.c b/src/sf_util.c index e8ff82d..ee3cd4f 100644 --- a/src/sf_util.c +++ b/src/sf_util.c @@ -93,31 +93,70 @@ int sf_printbuffer(char* buffer,int32_t len) return(0); } -void sf_usage_ex1(const char *program, const str_ptr_array_t *other_options) +void sf_usage_ex(const char *program, const SFCMDOption *other_options) { - int i; - fprintf(stderr, "\nUsage: %s [options] " "[start | stop | restart]\n\noptions:\n", program); if (other_options != NULL) { - for (i=0; icount; i++) { - fprintf(stderr, "\t%s\n", other_options->strs[i]); + const SFCMDOption *option; + option = other_options; + while (option->name.str != NULL) { + fprintf(stderr, "\t%s\n", option->desc); + option++; } } - fprintf(stderr, "\t-N | --without-daemon | --no-daemon: " - "run in foreground\n" + fprintf(stderr, "\t-N | --no-daemon: run in foreground\n" "\t-V | --version: show version info\n" "\t-h | --help: for this usage\n\n"); } -const char *sf_parse_daemon_mode_and_action_ex1(int argc, char *argv[], +static int match_option(const char *str, const SFCMDOption *option) +{ + const char *start; + const char *end; + + if (str[1] == '-') { + start = str + 2; + while (option->name.str != NULL) { + if (strncmp(option->name.str, start, + option->name.len) == 0) + { + end = start + option->name.len; + if (*end == '\0') { + return option->has_arg ? 2 : 1; + } else if (*end == '=') { + return 1; + } + } + + option++; + } + } else { + while (option->name.str != NULL) { + if (option->val == str[1]) { + if (str[2] == '\0') { + return option->has_arg ? 2 : 1; + } else { + return 1; + } + } + option++; + } + } + + return 0; +} + + +const char *sf_parse_daemon_mode_and_action_ex(int argc, char *argv[], const Version *version, bool *daemon_mode, char **action, - const char *default_action, const str_ptr_array_t *other_options) + const char *default_action, const SFCMDOption *other_options) { #define CMD_NORMAL_ARG_COUNT 2 int i; + bool inc; struct { int argc; char *argv[CMD_NORMAL_ARG_COUNT]; @@ -126,24 +165,26 @@ const char *sf_parse_daemon_mode_and_action_ex1(int argc, char *argv[], normal.argc = 0; *daemon_mode = true; - for (i=1; i 0) { + i += inc; + continue; + } } + if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--version") == 0) { @@ -161,14 +202,25 @@ const char *sf_parse_daemon_mode_and_action_ex1(int argc, char *argv[], if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { - sf_usage_ex1(argv[0], other_options); + sf_usage_ex(argv[0], other_options); + return NULL; + } + + if (strcmp(argv[i], "-N") == 0 || + strcmp(argv[i], "--no-daemon") == 0) + { + *daemon_mode = false; + i++; + } else { + fprintf(stderr, "\nError: unrecognized option: %s\n", argv[i]); + sf_usage_ex(argv[0], other_options); return NULL; } } if (normal.argc == 0) { fprintf(stderr, "\nError: expect config file!\n"); - sf_usage_ex1(argv[0], other_options); + sf_usage_ex(argv[0], other_options); return NULL; } diff --git a/src/sf_util.h b/src/sf_util.h index 2a827b3..1528195 100644 --- a/src/sf_util.h +++ b/src/sf_util.h @@ -18,6 +18,7 @@ #ifndef _SF_UTIL_H_ #define _SF_UTIL_H_ +#include #include "fastcommon/logger.h" #include "fastcommon/sched_thread.h" #include "sf_define.h" @@ -58,13 +59,19 @@ __FILE__, eln, eres, emsg, strerror(eres)) #define dszoffset(cls, mem) ((char*)&((cls*)0)->mem - ((char*)0)) -#define sf_usage(program) sf_usage_ex1(program, NULL) +#define sf_usage(program) sf_usage_ex(program, NULL) #define sf_parse_daemon_mode_and_action(argc, argv, \ version, daemon_mode, action) \ sf_parse_daemon_mode_and_action_ex1(argc, argv, \ version, daemon_mode, action, "start", NULL) +#define SF_COMMON_OPT_STRING "NVh" +#define SF_COMMON_LONG_OPTIONS \ + {"no-daemon", no_argument, NULL, 'N'}, \ + {"version", no_argument, NULL, 'V'}, \ + {"help", no_argument, NULL, 'h'} + #ifdef __cplusplus extern "C" { #endif @@ -76,36 +83,11 @@ void log_plus(const int priority, const char *file, int sf_printbuffer(char *buffer,int32_t len); -void sf_usage_ex1(const char *program, const str_ptr_array_t *other_options); +void sf_usage_ex(const char *program, const SFCMDOption *other_options); -static inline void sf_usage_ex(const char *program, const char *other_option) -{ - const char *strs[1]; - str_ptr_array_t options; - - strs[0] = other_option; - options.count = 1; - options.strs = (char **)strs; - sf_usage_ex1(program, &options); -} - -const char *sf_parse_daemon_mode_and_action_ex1(int argc, char *argv[], +const char *sf_parse_daemon_mode_and_action_ex(int argc, char *argv[], const Version *version, bool *daemon_mode, char **action, - const char *default_action, const str_ptr_array_t *other_options); - -static inline const char *sf_parse_daemon_mode_and_action_ex(int argc, - char *argv[], const Version *version, bool *daemon_mode, - char **action, const char *default_action, const char *other_option) -{ - const char *strs[1]; - str_ptr_array_t options; - - strs[0] = other_option; - options.count = 1; - options.strs = (char **)strs; - return sf_parse_daemon_mode_and_action_ex1(argc, argv, version, - daemon_mode, action, default_action, &options); -} + const char *default_action, const SFCMDOption *other_options); void sf_parse_cmd_option_bool(int argc, char *argv[], const string_t *short_option, const string_t *long_option,