margp is a miniature argument parsing library for standard C.
It parses simple POSIX-style short and long flags.
It is licensed under the MIT license.
Short flags are provided in arguments taking the form of -[flags][VALUE], where [flags] is
one or more characters, each of which represents some option. Some flags require a string value -
once one of these flags is encountered, the rest of the argument is stored as its value ([VALUE]).
If the argument just ends after that flag, the next argument will be used as its value instead.
Long flags are provided as arguments in the form --flag, where flag is the name of some option.
If this particular option requires a string value, the next argument will be used as its value.
The special argument -- indicates that all further arguments should not be handled as flags.
To specify the flags your program accepts, you define a list of margp_t values. This must end in an margp_t with its
type set to margpEnd.
The margp_t structure looks like this:
enum {
margpEnd = 0,
margpString,
margpFlag
} type;
char shorthand;
char *name;
void *target;
int setFlagTo;type specifies the purpose of this option - the significance of this option will be explained soon!
shorthand is a single character representing the shorthand flag for this option.
name is a string specifying the longhand name for this option, without the --.
Depending on the given type, the meaning of the rest of the struct changes:
-
If type is
margpString, this option will expect a string value.targetshould be a pointer to achar*variable, and when this option is encountered, margp will set that variable to the value it finds. -
If type is
margpFlag, this option will not expect a value.targetshould be a pointer to anintvariable, and when this option is encountered, margp will set that variable to the value specified insetFlagTo. -
If the type is
margpEnd, this does not specify an actual option, but denotes the end of the list of options.
margp_t flags[] = {
// The `-h` or `--help` flag sets action to actHelp.
{ margpFlag, 'h', "help", &action, actHelp },
// The `-v` or `--version` flag sets action to actVersion.
{ margpFlag, 'v', "version", &action, actVersion },
// The name flag (short `-nNAME` or `-n NAME`, long `--name NAME`)
// sets name to the passed NAME value.
{ margpString, 'n', "name", &name },
// Signify end of margp list
{ margpEnd }
};To parse margp options, invoke int margp(margp_t *args, int argc, char **argv, int *remainArgc, char ***remainArgv).
argsshould contain your list of options, in the format specified above.argcandargvshould be yourmainfunction's argc and argv values.remainArgcandremainArgvshould point to anintandchar**variable, respectively. These will be populated with any arguments that aren't parsed as options by margp. Ifmargpfinishes successfully, the variable you pointedremainArgvto will contain a pointer which needs to be freed when you are done with it.
After parsing, margp returns 1 on success, and 0 on failure. On failure, margp has already printed an error
message.
/* Example invocations and output:
*
* example hello world
* DefaultName says: hello world
*
* example -nJoe hello world
*. Joe says: hello world
*
* example hello --name Joe there, world!
*. Joe says: hello there, world!
*
* example -hn Joe hello world
*. THIS IS THE HELP SCREEN
*
* example -nh Joe hello world
*. h says: Joe hello world
*
* example -nJoe -- hello --help world
*. Joe says: hello --help world
*/
#include "margp.h"
#include <stdio.h>
int main(int argc, char **argv)
{
char *name = "DefaultName";
enum { actDefault, actHelp, actVersion } action = actDefault;
int remainArgc, result;
char **remainArgv;
// Parse arguments.
result = margp((margp_t[]) {
// The `-h` or `--help` flag sets action to actHelp.
{ margpFlag, 'h', "help", &action, actHelp },
// The `-v` or `--version` flag sets action to actVersion.
{ margpFlag, 'v', "version", &action, actVersion },
// The name flag (short `-nNAME` or `-n NAME`, long `--name NAME`)
// sets name to the passed NAME value.
{ margpString, 'n', "name", &name },
// Signify end of margp list
{ margpEnd }
}, argc, argv, &remainArgc, &remainArgv);
// Check margp results and print usage if it failed.
if (!result) {
printf("Usage: example [-hvnNAME] [--name name | --help | --version] [message]\n");
return 0;
}
switch (action) {
case actHelp:
printf("THIS IS THE HELP SCREEN\n");
break;
case actVersion:
printf("THIS IS THE VERSION SCREEN\n");
break;
case actDefault:
printf("%s says: ", name);
// Print all non-flag arguments!
for (int i = 0; i < remainArgc; i++)
printf("%s ", remainArgv[i]);
printf("\n");
break;
default:
break;
}
free(remainArgv);
}Licensed under the MIT license:
Copyright © 2020 Ethan McTague.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.