Skip to content

Instantly share code, notes, and snippets.

@shanna
Last active December 12, 2015 02:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shanna/4700362 to your computer and use it in GitHub Desktop.
Save shanna/4700362 to your computer and use it in GitHub Desktop.
Simple C flag parser using uthash. http://troydhanson.github.com/uthash/
#include "flags.h"
#define isopt(text) strncmp(text, "--", 2) == 0
#define isneg(text) strncmp(text, "--no-", 4) == 0
flags_t *flags_parse(int argc, char *argv[]) {
int n;
char *option, *value;
flags_t *flags = NULL, *flag;
for (n = 0, option = argv[0]; n < argc; n++, option = argv[n]) {
if (!isopt(option)) continue;
flag = (flags_t *)malloc(sizeof(flags_t));
if (isneg(option)) { // negation, always boolean
flag->option = option + 5;
flag->value = "false";
}
else if ((value = strchr(option, '='))) {
*value = 0;
flag->option = option + 2;
flag->value = value + 1;
}
else if (n < argc - 1) {
if (isopt(argv[n + 1])) {
flag->option = option + 2;
flag->value = "true";
}
else {
flag->option = option + 2;
flag->value = argv[n + 1];
n++;
}
}
else { // last one, so booleanish
flag->option = option + 2;
flag->value = "true";
}
HASH_ADD_KEYPTR(hh, flags, flag->option, strlen(flag->option), flag);
}
return flags;
}
char *flags_value(const flags_t *flags, const char *option) {
flags_t *flag;
HASH_FIND_STR(flags, option, flag);
return flag ? flag->value : NULL;
}
void flags_destroy(flags_t *flags) {
flags_t *flag, *tmp;
HASH_ITER(hh, flags, flag, tmp) {
HASH_DEL(flags, flag);
free(flag);
}
}
#ifndef _FLAGS_H_
#define _FLAGS_H_
#include <string.h>
#include <stdlib.h>
#include "uthash.h"
typedef struct {
char *option; // Key.
char *value;
UT_hash_handle hh;
} flags_t;
flags_t *flags_parse(int argc, char *argv[]);
char *flags_value(const flags_t *flags, const char *option);
void flags_destory(flags_t *flags);
#endif
#include <stdio.h>
#include "flags.h"
int main(int argc, char *argv[]) {
// Parse all flags.
flags_t *flags = flags_parse(argc, argv);
/*
Print test flag value.
--test #=> "test: true"
--test=true #=> "test: true"
--no-test #=> "test: false"
--test=false #=> "test: false"
--test="hello" #=> "test: hello"
*/
printf("test: %s\n", flags_value("test"));
flags_destroy(flags);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment