Skip to content

Comprehensive and configurable command line arguments parser library for C language.

License

Notifications You must be signed in to change notification settings

SourLemonJuice/ArgParseX

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ArgParseX

Comprehensive and configurable command line arguments parser library.
Written for C language.

Documents

At here(Simplified Chinese): docs/

All the functions do not use static variables, so they're thread-safe.
However, the config data structures can't be modified at the same times.

Note the documents are always up-to-date, so make sure to check the corresponding git tag.

Usage

The goal of ArgParseX is not to be simple use, which also make the interface look less nice. Some actual usage at here: example/test.c

In short, the user need create a struct ArgpxStyle and append it with ArgpxGroupAppend() and struct ArgpxGroup.

struct ArgpxStyle style = ARGPX_STYLE_INIT;
ArgpxGroupAppend(&style, &(struct ArgpxGroup){
    .prefix = "--",
    .assigner = "=",
    .delimiter = ",",
});

Although the built-in item is usable enough.

ArgpxGroupAppend(&style, ARGPX_GROUP_GNU);

And add some stop parsing symbols:

ArgpxSymbolAppend(&style, ARGPX_SYMBOL_STOP_PARSING("--"));
ArgpxSymbolAppend(&style, ARGPX_SYMBOL_STOP_PARSING("-"));

Finally, the most important thing to define the content of flags:

struct ArgpxFlagSet flag = ARGPX_FLAGSET_INIT;
ArgpxFlagAppend(&flag, &(struct ArgpxFlag){
    .group_idx = 0, // the first flag group that was be added(here is GNU)
    .name = "setbool",
    .action_type = kArgpxActionSetBool,
    .action_load.set_bool = {.source = true, .target_ptr = &test_bool},
});

It means, if --setbool detected, test_bool will be set to true.

After the configuration, call the main parser:

// skip the first arg, that's the exec command name
struct ArgpxResult *res = ArgpxParse(argc - 1, argv + 1, &style, &flag, NULL);

C standard

Compatibility whit C99 is the main thing.
But i think it might be possible to implement a new interface for C23 with macro switch.
There has auto and typeof()... that could make things easier.

Uses some malloc(), otherwise? Why not use heap memory?
And -Wvla(no Variable-length array).

Code style follows Google C++ Style Guide, and clang-format config.
The "namespace" of identifiers is argpx_xxx.The base pointer of the array is named xxx_v, its counter named xxx_c.

Hash table mode

When building source/argpx.c, add define ARGPX_USE_HASH and link the source/argpx_hash.c unit to enable hash table mode for flag search.
It would not make simple task faster, even slower.
The critical value will be determined in the future.

The hash function used now is FNV-1a 32bit.

Benchmark

In speed there is no advantage of ArgParseX over the classic GNU getopt. But the difference is less then double in the best case.
Here are the benchmark results on my PC:

Test sample:

#define ARGPX_DEV_BM_SAMPLE_ARR \
    (char *[]){ \
        "--config=./a_file.txt", \
        "-abcParamOfC",\
        "--verbose", \
        "param1", \
        "--log-level=1", \
        "param2", \
        "--retry=7", \
    }

Compiler clang version 18.1.8, Target: x86_64-pc-linux-gnu.
Count of loop: 10 * 1000 * 1000
Source code located in: benchmark/

Library Time
GNU getopt 0m1.456s
ArgParseX(-O3) 0m2.580s
ArgParseX(-O0) 0m4.619s

Todo

  • 重复匹配一个标志的后果?

See also

License

Published under MIT license.