diff options
author | Xavier Mendez <me@jmendeth.com> | 2014-10-20 00:10:31 +0200 |
---|---|---|
committer | Xavier Mendez <me@jmendeth.com> | 2014-10-20 00:10:31 +0200 |
commit | 5368b351530563dd3a1c94cd0a8b65d7a8a15b85 (patch) | |
tree | b20c78a8be75c8969cf72719e2a606e045e563bb | |
parent | c8ae964a569c67a90ac4da8bd24bb820bf8762fe (diff) | |
download | rust-hoedown-5368b351530563dd3a1c94cd0a8b65d7a8a15b85.tar.gz |
bin-refactor: Add parse_options generic method
-rw-r--r-- | bin/common.h | 76 |
1 files changed, 69 insertions, 7 deletions
diff --git a/bin/common.h b/bin/common.h index 9074bd6..14f850d 100644 --- a/bin/common.h +++ b/bin/common.h @@ -11,7 +11,8 @@ #define count_of(arr) (sizeof(arr)/sizeof(0[arr])) int -parseint(const char *string, long *result) { +parseint(const char *string, long *result) +{ char *end; errno = 0; *result = strtol(string, &end, 10); @@ -19,7 +20,8 @@ parseint(const char *string, long *result) { } const char * -strprefix(const char *str, const char *prefix) { +strprefix(const char *str, const char *prefix) +{ while (*prefix) { if (!(*str && *str == *prefix)) return 0; prefix++; str++; @@ -28,7 +30,8 @@ strprefix(const char *str, const char *prefix) { } void -print_option(char short_opt, const char *long_opt, const char *description) { +print_option(char short_opt, const char *long_opt, const char *description) +{ if (short_opt) printf(" -%c, ", short_opt); else @@ -38,8 +41,67 @@ print_option(char short_opt, const char *long_opt, const char *description) { } void -print_version() { - int major, minor, revision; - hoedown_version(&major, &minor, &revision); - printf("Built with Hoedown v%d.%d.%d.\n", major, minor, revision); +print_version() +{ + printf("Built with Hoedown " HOEDOWN_VERSION ".\n"); +} + +int +parse_options( + int argc, char **argv, + int(*parse_short_option)(char opt, char *next, void *opaque), + int(*parse_long_option)(char *opt, char *next, void *opaque), + int(*parse_argument)(int argn, char *arg, int is_forced, void *opaque), + void *opaque) +{ + int result; + int i = 1, regular_args = 0; + + /* Parse options mixed with arguments */ + while (i < argc) { + char *arg = argv[i]; + + if (arg[0] == '-' && arg[1]) { + char *next_arg = (i+1 < argc) ? argv[i+1] : NULL; + + if (arg[1] == '-' && !arg[2]) { + /* '--' signals end of options */ + i++; + break; + } + + if (arg[1] == '-') { + /* Long option */ + result = parse_long_option(arg + 2, next_arg, opaque); + if (!result) return 0; + i += result; + } else { + /* Sequence of short options */ + size_t pos; + for (pos = 1; arg[pos]; pos++) { + char *next = (arg[pos+1]) ? arg + pos+1 : next_arg; + result = parse_short_option(arg[pos], next, opaque); + if (!result) return 0; + if (result == 2) { + i++; + break; + } + } + i++; + } + } else { + /* Argument */ + result = parse_argument(regular_args++, arg, 0, opaque); + if (!result) return 0; + i++; + } + } + + /* Parse rest as forced arguments */ + while (i < argc) { + parse_argument(regular_args++, argv[i], 1, opaque); + i++; + } + + return 1; } |