LIB-ZC, 一个跨平台(Linux)平台通用C/C++扩展库,命令行参数和配置文件
LIB-ZC, 一个跨平台(Linux)平台通用C/C++扩展库,命令行参数和配置文件
- 本库 打通了命令行参数和配置文件.
- 推荐但不强制使用
命令行
命令行参数, 风格/例子
./cmd -name1 val1 arg1 -name2 val2 --bool1 --bool2 arg2 arg3
- 1个横杠 - 开始的是"参数名", 后面必须跟一个"参数值"
- 2个横杠 – 开始的是布尔型的参数, 后面没有"参数值", (逻辑上)值为真
- 其他参数为普通参数
命令行方法
// 命名空间 zcc::main_argument
// 默认全局配置
extern zcc::config var_main_config;
struct option
{
const char *key;
const char *val;
};
// main 函数入口的 argc
extern int var_argc;
// main 函数入口的 argv
extern char **var_argv;
// 命令行参数的 key/value 对
extern std::vector<option> var_options;
// 命令行的参数
extern std::vector<const char *> var_parameters;
// var_parameters.size()
extern int var_parameter_argc;
// (char **)(var_parameters.c_str())
extern char **var_parameter_argv;
// 解析命令行
void run(int argc, char **argv, bool cmd_mode = true);
执行逻辑
已知:
./cmd -name1 val1 arg1 -name2 val2 --bool1 --bool2 arg2 arg3
调用函数
zcc::main_argument::run(argc, argv);
有如下效果:
系统会初始化全局配置变量
var_argc = argc;
var_argv = argv;
progname = argv[0];
而且逻辑上:
// var_main_config
zcc::var_main_config[name1] = val1
zcc::var_main_config[name2] = val2
zcc::var_main_config[bool1] = "yes"
zcc::var_main_config[bool2] = "yes"
// var_options
var_options = {{name1, val1}, {name2, val2}, {boo1, yes}, {bool2, yes}}
// var_parameters
var_parameters = {arg1, arg2, arg3}
另外
- 如果参数中出现(可以多组) -config somepath.cf, 那么会立即加载配置文件somepath.cf到 zcc::var_main_config
- 遵循规则: 后加载的配置项覆盖先加载的配置项
- 遵循规则: 命令行上的配置项覆盖配置文件中的配置项
配置
先看一个配置文件例子,内容如下
# 忽略空行
# 行首第一个非空字符是#, 则忽略本行
#
# 每配置行以 "=" 为分隔符
# 配置项和配置值都需要过滤掉两侧的空白
# 不支持任何转义
server-command = bin/milter
server-log = syslog,mail
# 相同配置项, 以后一个为准
spamd_server = var/socket/spamd
spamd_server = var/socket/spamd222
config 类
// 线程, 读写不安全
// 线程, 只有读是安全的
class config : public std::map<std::string, std::string>
{
public:
config();
~config();
config &reset();
virtual inline void afterUpdate() {};
config &update(const char *key, const char *val, int vlen = -1);
config &update(const char *key, const std::string &val);
config &update(const std::string &key, const std::string &val);
config &remove(const char *key);
config &remove(const std::string &key);
// 从文件加载配置, 且覆盖
bool load_from_file(const char *pathname);
bool load_from_file(const std::string &pathname)
{
return load_from_file(pathname.c_str());
}
// 从另一个配置复制
config &load_another(config &another);
config &debug_show();
// 获取值
std::string *get_value(const char *key);
std::string *get_value(const std::string &key);
const char *get_cstring(const char *key, const char *def_val = "");
const char *get_cstring(const std::string &key, const char *def_val = "");
std::string get_string(const char *key, const char *def_val = "");
std::string get_string(const std::string &key, const char *def_val = "");
const std::string &get_string(const std::string &key, const std::string &def_val);
// 获取布尔值, y/Y/t/T/1 => true, n/N/f/F/0 => false
bool get_bool(const char *key, bool def_val = false);
bool get_bool(const std::string &key, bool def_val = false);
// atoi
int get_int(const char *key, int def_val = 0);
int get_int(const std::string &key, int def_val = 0);
// atol
int64_t get_long(const char *key, int64_t def_val = 0);
int64_t get_long(const std::string &key, int64_t def_val = 0);
// 获取时间秒值 1s, 1m, 1h, 1d, 1w
int64_t get_second(const char *key, int64_t def_val = 0);
int64_t get_second(const std::string &key, int64_t def_val = 0);
// 获取大小字节 1b, 1k, 1m, 1g
int64_t get_size(const char *key, int64_t def_val = 0);
int64_t get_size(const std::string &key, int64_t def_val = 0);
private:
void *unused_;
};