# fflags **Repository Path**: ascent_zhang/fflags ## Basic Information - **Project Name**: fflags - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-11-28 - **Last Updated**: 2024-05-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # FFlags 参数解析程序 ## 关于FFlags fflags是基于C语言的命令行参数解析程序,它可以支持解析`unix-like`和`windows`风格的命令行程序。 支持使用子程序,例如`math sub xxx`,其中`sub`即`math`的子程序,不同的子程序可以使用不同的解析方式。 fflags是线程安全的,他不是用全局变量来保存数据。 实际上,fflags不仅可以解析命令行参数,还是以解析任意签名为`int argc, char **agrv`函数的参数。 fflags设计被用于项目`aFun`的命令行参数解析,具体可以参考[aFun on github](https://github.com/aFun-org/aFunlang) 。 ## 基本功能 * 针对不同的子程序创建解析语法, 例如`math sub 10 20`中,`sub`即`math`的子程序(`child`),`10`和`20`为`sub`子程序的参数。 * 有默认子程序,例如设置`sub`为默认子程序,则`math 10 20`和`math sub 10 20`使用相同的方式解析参数。 * 支持`unix-like`参数 * 短杠`-`即短参数,例如`-a`。 * 短参数允许多个缩写,例如`-abc` * 双短杠`--`即长参数,例如`--point` * 短参数和长参数统称为选项,选项后可跟附属参数,例如`--point 21` * `--`后链接的参数为非开关参数,即不属于选项参数又不是选项参数的附属参数的其他参数。 * 例如`--point 21 22 -- -p 20`中,`21`是`point`长参数的附属参数,`22 -p 20`是非开关参数 * 支持`windows`的斜杠参数 * 斜杠后只有一个字符的参数即短参数,例如`/a`。 * 斜杠后有多于一个字符的参数即长参数,例如`/point`。 ## 使用方式 在`fflags.h`文件中,定义了可以简便实用fflags的宏。 ### 定义子程序及其参数解析语法 ```c ff_defArg(<子程序名字>, <是否为default true/false>) ff_argRule(<短参书 一个字符(无单引号)>, <长参数>, <是否接受参数, not/can/must>, <标识符 int>) ... ff_endArg(<子程序名字>, <是否为default true/false>); ``` **注意:标识符不建议使用`0`,`-1`以及`-2`。具体见下文。** 例如: ```c ff_defArg(main, true) ff_argRule('m', message, not, 1) ff_argRule('w', msg2, not, 2) ff_argRule('e', msg3, can, 3) ff_argRule('r', msg4, must, 4) ff_endArg(main, true); ``` 如果`ff_argRule`时,长参数包含空格符,则需要使用`ff_argRule_`定义: ```c ff_argRule(<短参书 一个字符(包含单引号)>, <长参数字符串>, <是否接受参数, not/can/must>, <标识符>) ``` ### 定义子程序表 将多个子程序汇聚起来,需要定义一个子程序表 ```c ff_childList(<主程序名字>, ff_child(<子程序名字>) ...); ``` ### 开始解析参数 #### 解析器的创建与释放 使用`ff_initFFlags(<参数个数>, <参数数组>, <是否忽略第一个参数>, <是否支持斜杠参数>, <错误输出位置>, <主程序名字>)`创建一个解析器,例如: ```c ff_FFlags *ff = ff_initFFlags(argc, argv, true, false, sys); ``` 当该操作返回值为`NULL`时,意味着初始化失败,通常的原因是遇到错误的参数或无适配的子程序。 使用`ff_getChild(<解析器>)`获取匹配的子程序名字。 ```c ff_getChild(ff); ``` 参数处理完成后,使用`ff_freeFFlags(<解析器>)`释放解析器,例如: ```c ff_freeFFlags(ff); ``` #### 解析参数 使用`ff_getopt(<字符串指针>, <解析器>);`读取一个选项参数。若选项参数有附属参数,则该参数存储到字符串指针中。 ```c char *text = NULL; int mark = ff_getopt(&text, ff); ``` `mark`即`ff_argRule`时定义的标识符,`test`上的内容即附属参数(若无附属参数则设置为`NULL`)。 执行`ff_getop`会沿顺序读取选项参数,跳过非开关参数。 当`ff_getop`返回值为`0`时,表示参数解析遭遇错误。 当`ff_getop`返回值为`0`或`-2`时,表示参数解析遭遇错误。 当`ff_getop`返回`-1`时,表示选项参数已经全部解析完成。 当`ff_getopt`返回`-1`(即所有参数解析完成时),方可调用`ff_getopt_wild(<字符串指针>, <解析器>)`取出非开关参数。 ```c char *text = NULL; bool re = ff_getopt_wild(&text, ff); ``` `test`上的内容即非开关参数内容。(若读取完成则设置为`NULL`)。 执行`ff_getopt_wild`会沿顺序读取非开关参数。 当`ff_getopt_wild`返回值为`false`代表非开关参数全部读取完成。 当`ff_getopt_wild`返回值为`true`代表非开关参数还未读取完成。 **只有选项参数解析完成后,才可解析非开关参数** ## 构建 FFlags使用`cmake`构建项目。 ```shell $ mkdir build $ cd build $ cmake .. ``` 可以通过`-D`选项添加`cmake`参数。 FFlags支持的参数包括: ``` FFLAGS_BUILD_TEST # 是否构建测试项目 SET_OUTPUT_DIRECTORY # 是否重新设定output位置 (当fflags作为子项目时, 请设置为OFF) ``` 通常,使用`make`工具编译和安装项目。 ```shell $ make $ make install ``` 亦可使用`CTest`运行测试用例。 经测试,可以为`windows`以及`linux`操作系统中,使用`mingw`, `msvc`, `clang`进行编译。 ### 编译目标 编译后可得到`FFlags`动态库,以及`fflags.h`头文件。 使用该库时,将`FFlags`动态库连接到你的程序,并且在程序在包含`fflags.h`头文件即可。 ### 作为子项目 可以直接将`FFlags`作为子项目包含到你的项目中, 在`CMakeLists.txt`添加如下代码: ```c set(FFLAGS_BUILD_TEST OFF) set(SET_OUTPUT_DIRECTORY OFF) add_subdirectory(fflags) ``` ## 声明 ### 免责声明 FFlags为免费开源程序。 编译、运行该程序过程中造成的任何损失(包括但不限于系统损坏、文件丢失)均由您个人承担,与程序的开发者无关。 ### LICENSE FFlags是在 MIT License 下发布的。 FFlags代码归属其代码贡献者。