Giter Site home page Giter Site logo

optparse's Introduction

optparse

optparse是一个开源, 可移植的, 可重入的和可嵌入的类getopt命令行参数解析器. 它支持POSIX getopt选项字符串, GNU风格的长参数解析, 参数置换和子命令处理.

1. 为什么不在RTT下直接使用getopt函数?

POSIX getopt解析器有三个致命的缺陷. 这些缺陷都是可以通过optparse来解决的:

  1. getopt的解析状态存储在全局变量中, 其中一些变量是静态不可访问的. 这意味着在RTT(RT-Thread)下只能有一个msh命令可以使用getopt, 其他msh命令再次使用getopt会出现bug. 而optparse将每次解析的状态存储在一个属于msh的私有结构体中, 每一个optparse命令解析器不会相互影响.

  2. 在RTT中BSP一般支持Keil, IAR和GCC, 对于keil环境下是无法支持原生的POSIX getopt解析器, 这样就造成了在RTT下实现命令解析是无法移植到Keil中使用的, 代码的兼容性降低!

  3. 在getopt中, 错误消息被打印到stderr. 使用opterr可以禁用此功能, 但消息本身仍然不可访问. optparse通过将错误消息写入它的errmsg字段来解决这个问题, 该字段可以被打印到任何地方. optparse的缺点是, 这个错误消息总是用英语而不是当前语言环境.

2. 命令顺序

默认情况下, argv在被解析时会将非选项的参数移动到数组的末尾. 可以通过在初始化后将permute字段设置为0来禁用它.

struct optparse options;
optparse_init(&options, argv);
options.permute = 0;

3. 对比

optparse的接口应该是任何熟悉getopt的人都熟悉的. 选项字符串具有相同的格式, 解析器结构体成员变量与getopt全局变量(optarg、optind、optopt)具有相同的名称.

long选项解析器optparse_long()API与GNU的getopt_long()非常相似,可以作为替代api.

optparse没有分配内存. 此外optparse没有依赖项, 包括libc本身. 因此可以在标准C库无法使用的情况下使用.

查看optparse.h文件可以了解完整的API.

4. 示例使用

这是一个通用的getopt命令解析代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <getopt.h>

int main(int argc, char **argv)
{
    bool amend = false;
    bool brief = false;
    const char *color = "white";
    int delay = 0;

    int option;
    while ((option = getopt(argc, argv, "abc:d::")) != -1) {
        switch (option) {
        case 'a':
            amend = true;
            break;
        case 'b':
            brief = true;
            break;
        case 'c':
            color = optarg;
            break;
        case 'd':
            delay = optarg ? atoi(optarg) : 1;
            break;
        case '?':
            return EXIT_FAILURE;
        }
    }

    /* Print remaining arguments. */
    for (; optind < argc; optind++)
        printf("%s\n", argv[optind]);
    return 0;
}

如果使用optparse在RTT下解析, 同样的功能将使用如下的代码的实现:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "optparse.h"

int cmd_parse(int argc, char **argv)
{
    bool amend = false;
    bool brief = false;
    const char *color = "white";
    int delay = 0;

    char *arg;
    int option;
    struct optparse options;

    optparse_init(&options, argv);
    while ((option = optparse(&options, "abc:d::")) != -1) {
        switch (option) {
        case 'a':
            amend = true;
            break;
        case 'b':
            brief = true;
            break;
        case 'c':
            color = options.optarg;
            break;
        case 'd':
            delay = options.optarg ? atoi(options.optarg) : 1;
            break;
        case '?':
            fprintf(stderr, "%s: %s\n", argv[0], options.errmsg);
            return EXIT_FAILURE;
        }
    }

    /* Print remaining arguments. */
    while ((arg = optparse_arg(&options)))
        printf("%s\n", arg);
    return 0;
}
MSH_CMD_EXPORT(cmd_parse, cmd description);

这是optparse对长选项参数的支持:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "optparse.h"

int main(int argc, char **argv)
{
    struct optparse_long longopts[] = {
        {"amend", 'a', OPTPARSE_NONE},
        {"brief", 'b', OPTPARSE_NONE},
        {"color", 'c', OPTPARSE_REQUIRED},
        {"delay", 'd', OPTPARSE_OPTIONAL},
        {0}
    };

    bool amend = false;
    bool brief = false;
    const char *color = "white";
    int delay = 0;

    char *arg;
    int option;
    struct optparse options;

    optparse_init(&options, argv);
    while ((option = optparse_long(&options, longopts, NULL)) != -1) {
        switch (option) {
        case 'a':
            amend = true;
            break;
        case 'b':
            brief = true;
            break;
        case 'c':
            color = options.optarg;
            break;
        case 'd':
            delay = options.optarg ? atoi(options.optarg) : 1;
            break;
        case '?':
            fprintf(stderr, "%s: %s\n", argv[0], options.errmsg);
            return EXIT_FAILURE;
        }
    }

    /* Print remaining arguments. */
    while ((arg = optparse_arg(&options)))
        printf("%s\n", arg);

    return 0;
}

5. 感谢

  1. 该库移植于https://github.com/skeeto/optparse.
  2. 感谢skeeto. 本移植是修改了部分原作者的代码针对RTT在线包实现的版本, 该仓库保留原作者的许可声明! 具体原作者许可请查看https://github.com/skeeto/optparse/blob/master/UNLICENSE.

optparse's People

Contributors

liu2guang avatar mysterywolf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

optparse's Issues

请教一下

https://github.com/Droid-MAX/spi-nand-prog
这个repo目前测试仅能在x86/x64平台的linux系统上正常使用,在其他嵌入式平台,比如arm平台的嵌入式linux系统上无法正常使用
现象,在正常情况下x86/x64平台执行程序(默认无参),是会输出missing action提示字符串,而在arm平台上执行程序时却无任何输出且出现阻塞现象,使用strace和gdb调试初步发现很有可能是getopt这块出了问题,然后就没了头绪。。还望高人指点一二,谢谢!

长命令选项

长命令参数选项为OPTPARSE_REQUIRED时,无法正确解析
···
if (option[1])
options->optarg = option + 1;
else
options->optarg = 0;
···

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.