parse cmd options strictly
parent
d5fb83a140
commit
667fd14abb
|
|
@ -200,6 +200,13 @@ typedef struct sf_key_value_array {
|
||||||
int alloc;
|
int alloc;
|
||||||
} SFKeyValueArray;
|
} 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 {
|
typedef enum sf_server_group_index_type {
|
||||||
sf_server_group_index_type_cluster = 1,
|
sf_server_group_index_type_cluster = 1,
|
||||||
sf_server_group_index_type_service
|
sf_server_group_index_type_service
|
||||||
|
|
|
||||||
|
|
@ -93,31 +93,70 @@ int sf_printbuffer(char* buffer,int32_t len)
|
||||||
return(0);
|
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] <config_file> "
|
fprintf(stderr, "\nUsage: %s [options] <config_file> "
|
||||||
"[start | stop | restart]\n\noptions:\n", program);
|
"[start | stop | restart]\n\noptions:\n", program);
|
||||||
|
|
||||||
if (other_options != NULL) {
|
if (other_options != NULL) {
|
||||||
for (i=0; i<other_options->count; i++) {
|
const SFCMDOption *option;
|
||||||
fprintf(stderr, "\t%s\n", other_options->strs[i]);
|
option = other_options;
|
||||||
|
while (option->name.str != NULL) {
|
||||||
|
fprintf(stderr, "\t%s\n", option->desc);
|
||||||
|
option++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "\t-N | --without-daemon | --no-daemon: "
|
fprintf(stderr, "\t-N | --no-daemon: run in foreground\n"
|
||||||
"run in foreground\n"
|
|
||||||
"\t-V | --version: show version info\n"
|
"\t-V | --version: show version info\n"
|
||||||
"\t-h | --help: for this usage\n\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 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
|
#define CMD_NORMAL_ARG_COUNT 2
|
||||||
int i;
|
int i;
|
||||||
|
bool inc;
|
||||||
struct {
|
struct {
|
||||||
int argc;
|
int argc;
|
||||||
char *argv[CMD_NORMAL_ARG_COUNT];
|
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;
|
normal.argc = 0;
|
||||||
*daemon_mode = true;
|
*daemon_mode = true;
|
||||||
for (i=1; i<argc; i++) {
|
i = 1;
|
||||||
|
while (i < argc) {
|
||||||
if (argv[i][0] != '-') {
|
if (argv[i][0] != '-') {
|
||||||
if (normal.argc == CMD_NORMAL_ARG_COUNT) {
|
if (normal.argc == CMD_NORMAL_ARG_COUNT) {
|
||||||
fprintf(stderr, "\nError: too many arguments!\n");
|
fprintf(stderr, "\nError: too many arguments!\n");
|
||||||
sf_usage_ex1(argv[0], other_options);
|
sf_usage_ex(argv[0], other_options);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
normal.argv[normal.argc++] = argv[i];
|
normal.argv[normal.argc++] = argv[i++];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "-N") == 0 ||
|
if (other_options != NULL) {
|
||||||
strcmp(argv[i], "--without-daemon") == 0 ||
|
inc = match_option(argv[i], other_options);
|
||||||
strcmp(argv[i], "--no-daemon") == 0)
|
if (inc > 0) {
|
||||||
{
|
i += inc;
|
||||||
*daemon_mode = false;
|
continue;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(argv[i], "-V") == 0 ||
|
if (strcmp(argv[i], "-V") == 0 ||
|
||||||
strcmp(argv[i], "--version") == 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 ||
|
if (strcmp(argv[i], "-h") == 0 ||
|
||||||
strcmp(argv[i], "--help") == 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normal.argc == 0) {
|
if (normal.argc == 0) {
|
||||||
fprintf(stderr, "\nError: expect config file!\n");
|
fprintf(stderr, "\nError: expect config file!\n");
|
||||||
sf_usage_ex1(argv[0], other_options);
|
sf_usage_ex(argv[0], other_options);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#ifndef _SF_UTIL_H_
|
#ifndef _SF_UTIL_H_
|
||||||
#define _SF_UTIL_H_
|
#define _SF_UTIL_H_
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
#include "fastcommon/logger.h"
|
#include "fastcommon/logger.h"
|
||||||
#include "fastcommon/sched_thread.h"
|
#include "fastcommon/sched_thread.h"
|
||||||
#include "sf_define.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 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, \
|
#define sf_parse_daemon_mode_and_action(argc, argv, \
|
||||||
version, daemon_mode, action) \
|
version, daemon_mode, action) \
|
||||||
sf_parse_daemon_mode_and_action_ex1(argc, argv, \
|
sf_parse_daemon_mode_and_action_ex1(argc, argv, \
|
||||||
version, daemon_mode, action, "start", NULL)
|
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
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -76,36 +83,11 @@ void log_plus(const int priority, const char *file,
|
||||||
|
|
||||||
int sf_printbuffer(char *buffer,int32_t len);
|
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 *sf_parse_daemon_mode_and_action_ex(int argc, char *argv[],
|
||||||
{
|
|
||||||
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 Version *version, bool *daemon_mode, char **action,
|
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);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sf_parse_cmd_option_bool(int argc, char *argv[],
|
void sf_parse_cmd_option_bool(int argc, char *argv[],
|
||||||
const string_t *short_option, const string_t *long_option,
|
const string_t *short_option, const string_t *long_option,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue