- Create a structure containing strings and booleans: make sure that you don't allocate your strings on the stack by doing
char* argument = NULL;
and not
char argument[50];
This structure will hold values of every flag.
- Create a 0-terminated array of dash_Longopt options, one for each flag you want. A dash_Longopt structure is defined as follows:
typedef struct { char opt_name; bool allow_flag_unset; bool param_optional; const char* param_name; const char* longopt_name; const char* description; void* user_pointer; } dash_Longopt;
opt_name: A single char defining the short name of the option. If not set, the option has no short name.allow_flag_unsetIndicates if it's possible to write +X instead of -X to remove the X flag. If not set, +X is forbidden.param_optionalIndicates whether or not the parameter of the option can be omitted. This statement as no effect ifparam_nameis unset. If not set, the parameter isn't optional.param_name: The name of the parameter. If not set, the option takes no parameter anduser_pointershould be abool*that points to a boolean. If set,user_pointershould be achar*.longopt_name: the long name of the option, callable with --NAME. If not set, the option has no short name.description: the description of the option for dash_print_usage, every$character will be replaced by the content ofparam_nameuser_pointer: A pointer to the data to register, either abool*or achar*, MUST be set
Example:
char* argument = NULL; bool flag; dash_Longopt options[] = { {.user_pointer = &argument, .longopt_name = "my_flag", .opt_name = 'f', .param_optional = True, .param_name = "flag_argument", .description = "Set value of my flag to $"}, {0} };
[!NOTE] Every entry with no
opt_nameand nolongopt_namewill be considered like the 0-element at the end of the array. - Then for every mandatory argument, create a new NULL-terminated string array, for example:
const char* required_arguments[] = { "output_stream", NULL };
- Finally you can call arg_parser():
if (!dash_arg_parser(&argc, argv, options)) { dash_print_usage(argv[0], "help message header", "help message footer", required_argumnets, options); dash_free(options); exit(1); } // use argument, flag and argv dash_free(options);
- Short / long flags with or without an argument
- Long flags with an argument provided with the '=' sign (e.g.
--output=file) - Unsetting short flags with a plus sign instead of a hyphen (e.g.
+smeans explicitly disable flags) - Multiple short options with a single hyphen (e.g.
-abcmeans-a -b -c) - Short option and argument without a space in between for options requiring arguments (e.g.
-cechomeans-c echo) - Double hyphen marks the end of flags, any argument beginning with an hyphen after that will not be considered as a flag
- A single hyphen will not be considered as a flag, meaning you can use it freely (for example as an alias to /dev/stdin)
A complete example is available in example.c, you can build it with make example, in this example, you can call
./build/example -i --command="echo hi" v1 -s v2 -f +o "autocd noglob" for example, you should get this output:
interactive = (bool) True
command = (string) echo hi
stdin = (bool) True
a = (bool) False
b = (bool) False
C = (bool) False
e = (bool) False
f = (bool) True
h = (bool) False
m = (bool) False
o = (string) +autocd noglob
u = (bool) False
v = (bool) False
x = (bool) False
help = (bool) False
usage = (bool) False
Remaining arguments: ./build/example v1 v2
Other example:
./build/example --help
example shell, version 0.0.1
Usage: ./build/example [options] output_file
-i, --interactive Start an interactive shell
-c, --command line Execute line as a command
-s, --stdin Read commands from standard input
-a/+a Always export variables on assignment
-b/+b Notify asynchronously of background completion
-C/+C Don't overwrite files on redirect with >
-e/+e When any command fails, exit
-f/+f Disable pathname expansion
-h/+h Locate utilities on function definition
-m/+m Print background process status changes before drawing PS1
-o/+o [option] If option is non null, set options to option, else show all enabled options, use +o to print in an inputable format
-u/+u Fail when expanding an unset parameter
-v/+v Write shell input to stderr
-x/+x Print every command after expansion before execution
--help Show this help message
--usage Show this help message
Home page : https://example.com/shell
- This library can only handle boolean flags and flags with string values, it could be improved to handle integers for example.
- You can't set a non-boolean flag several times