diff options
author | Etienne Samson <samson.etienne@gmail.com> | 2019-11-06 11:08:30 +0100 |
---|---|---|
committer | Etienne Samson <samson.etienne@gmail.com> | 2019-11-06 11:12:34 +0100 |
commit | 025a93577d9cff75ba36816d8957470aac03f1c7 (patch) | |
tree | 703b6c303ce15218b15e749796c5f9703e61d196 /examples | |
parent | 745ccc8ab98c9bb52099d5fa786158704602b1af (diff) | |
download | libgit2-025a93577d9cff75ba36816d8957470aac03f1c7.tar.gz |
examples: move "args" to its own header
Diffstat (limited to 'examples')
-rw-r--r-- | examples/args.c | 170 | ||||
-rw-r--r-- | examples/args.h | 79 | ||||
-rw-r--r-- | examples/common.c | 168 | ||||
-rw-r--r-- | examples/common.h | 73 |
4 files changed, 251 insertions, 239 deletions
diff --git a/examples/args.c b/examples/args.c new file mode 100644 index 000000000..b228ae3dd --- /dev/null +++ b/examples/args.c @@ -0,0 +1,170 @@ +#include "common.h" +#include "args.h" + +size_t is_prefixed(const char *str, const char *pfx) +{ + size_t len = strlen(pfx); + return strncmp(str, pfx, len) ? 0 : len; +} + +int optional_str_arg( + const char **out, struct args_info *args, const char *opt, const char *def) +{ + const char *found = args->argv[args->pos]; + size_t len = is_prefixed(found, opt); + + if (!len) + return 0; + + if (!found[len]) { + if (args->pos + 1 == args->argc) { + *out = def; + return 1; + } + args->pos += 1; + *out = args->argv[args->pos]; + return 1; + } + + if (found[len] == '=') { + *out = found + len + 1; + return 1; + } + + return 0; +} + +int match_str_arg( + const char **out, struct args_info *args, const char *opt) +{ + const char *found = args->argv[args->pos]; + size_t len = is_prefixed(found, opt); + + if (!len) + return 0; + + if (!found[len]) { + if (args->pos + 1 == args->argc) + fatal("expected value following argument", opt); + args->pos += 1; + *out = args->argv[args->pos]; + return 1; + } + + if (found[len] == '=') { + *out = found + len + 1; + return 1; + } + + return 0; +} + +static const char *match_numeric_arg(struct args_info *args, const char *opt) +{ + const char *found = args->argv[args->pos]; + size_t len = is_prefixed(found, opt); + + if (!len) + return NULL; + + if (!found[len]) { + if (args->pos + 1 == args->argc) + fatal("expected numeric value following argument", opt); + args->pos += 1; + found = args->argv[args->pos]; + } else { + found = found + len; + if (*found == '=') + found++; + } + + return found; +} + +int match_uint16_arg( + uint16_t *out, struct args_info *args, const char *opt) +{ + const char *found = match_numeric_arg(args, opt); + uint16_t val; + char *endptr = NULL; + + if (!found) + return 0; + + val = (uint16_t)strtoul(found, &endptr, 0); + if (!endptr || *endptr != '\0') + fatal("expected number after argument", opt); + + if (out) + *out = val; + return 1; +} + +int match_uint32_arg( + uint32_t *out, struct args_info *args, const char *opt) +{ + const char *found = match_numeric_arg(args, opt); + uint16_t val; + char *endptr = NULL; + + if (!found) + return 0; + + val = (uint32_t)strtoul(found, &endptr, 0); + if (!endptr || *endptr != '\0') + fatal("expected number after argument", opt); + + if (out) + *out = val; + return 1; +} + +static int match_int_internal( + int *out, const char *str, int allow_negative, const char *opt) +{ + char *endptr = NULL; + int val = (int)strtol(str, &endptr, 10); + + if (!endptr || *endptr != '\0') + fatal("expected number", opt); + else if (val < 0 && !allow_negative) + fatal("negative values are not allowed", opt); + + if (out) + *out = val; + + return 1; +} + +int match_bool_arg(int *out, struct args_info *args, const char *opt) +{ + const char *found = args->argv[args->pos]; + + if (!strcmp(found, opt)) { + *out = 1; + return 1; + } + + if (!strncmp(found, "--no-", strlen("--no-")) && + !strcmp(found + strlen("--no-"), opt + 2)) { + *out = 0; + return 1; + } + + *out = -1; + return 0; +} + +int is_integer(int *out, const char *str, int allow_negative) +{ + return match_int_internal(out, str, allow_negative, NULL); +} + +int match_int_arg( + int *out, struct args_info *args, const char *opt, int allow_negative) +{ + const char *found = match_numeric_arg(args, opt); + if (!found) + return 0; + return match_int_internal(out, found, allow_negative, opt); +} diff --git a/examples/args.h b/examples/args.h new file mode 100644 index 000000000..b08a534f3 --- /dev/null +++ b/examples/args.h @@ -0,0 +1,79 @@ +#ifndef INCLUDE_examples_args_h__ +#define INCLUDE_examples_args_h__ + +/** + * Argument-processing helper structure + */ +struct args_info { + int argc; + char **argv; + int pos; +}; +#define ARGS_INFO_INIT { argc, argv, 0, 0 } +#define ARGS_CURRENT(args) args->argv[args->pos] + +/** + * Check if a string has the given prefix. Returns 0 if not prefixed + * or the length of the prefix if it is. + */ +extern size_t is_prefixed(const char *str, const char *pfx); + +/** + * Match an integer string, returning 1 if matched, 0 if not. + */ +extern int is_integer(int *out, const char *str, int allow_negative); + +/** + * Check current `args` entry against `opt` string. If it matches + * exactly, take the next arg as a string; if it matches as a prefix with + * an equal sign, take the remainder as a string; if value not supplied, + * default value `def` will be given. otherwise return 0. + */ +extern int optional_str_arg( + const char **out, struct args_info *args, const char *opt, const char *def); + +/** + * Check current `args` entry against `opt` string. If it matches + * exactly, take the next arg as a string; if it matches as a prefix with + * an equal sign, take the remainder as a string; otherwise return 0. + */ +extern int match_str_arg( + const char **out, struct args_info *args, const char *opt); + +/** + * Check current `args` entry against `opt` string parsing as uint16. If + * `opt` matches exactly, take the next arg as a uint16_t value; if `opt` + * is a prefix (equal sign optional), take the remainder of the arg as a + * uint16_t value; otherwise return 0. + */ +extern int match_uint16_arg( + uint16_t *out, struct args_info *args, const char *opt); + +/** + * Check current `args` entry against `opt` string parsing as uint32. If + * `opt` matches exactly, take the next arg as a uint16_t value; if `opt` + * is a prefix (equal sign optional), take the remainder of the arg as a + * uint32_t value; otherwise return 0. + */ +extern int match_uint32_arg( + uint32_t *out, struct args_info *args, const char *opt); + +/** + * Check current `args` entry against `opt` string parsing as int. If + * `opt` matches exactly, take the next arg as an int value; if it matches + * as a prefix (equal sign optional), take the remainder of the arg as a + * int value; otherwise return 0. + */ +extern int match_int_arg( + int *out, struct args_info *args, const char *opt, int allow_negative); + +/** + * Check current `args` entry against a "bool" `opt` (ie. --[no-]progress). + * If `opt` matches positively, out will be set to 1, or if `opt` matches + * negatively, out will be set to 0, and in both cases 1 will be returned. + * If neither the positive or the negative form of opt matched, out will be -1, + * and 0 will be returned. + */ +extern int match_bool_arg(int *out, struct args_info *args, const char *opt); + +#endif diff --git a/examples/common.c b/examples/common.c index d243785a5..30f6cdc3b 100644 --- a/examples/common.c +++ b/examples/common.c @@ -53,174 +53,6 @@ void fatal(const char *message, const char *extra) exit(1); } -size_t is_prefixed(const char *str, const char *pfx) -{ - size_t len = strlen(pfx); - return strncmp(str, pfx, len) ? 0 : len; -} - -int optional_str_arg( - const char **out, struct args_info *args, const char *opt, const char *def) -{ - const char *found = args->argv[args->pos]; - size_t len = is_prefixed(found, opt); - - if (!len) - return 0; - - if (!found[len]) { - if (args->pos + 1 == args->argc) { - *out = def; - return 1; - } - args->pos += 1; - *out = args->argv[args->pos]; - return 1; - } - - if (found[len] == '=') { - *out = found + len + 1; - return 1; - } - - return 0; -} - -int match_str_arg( - const char **out, struct args_info *args, const char *opt) -{ - const char *found = args->argv[args->pos]; - size_t len = is_prefixed(found, opt); - - if (!len) - return 0; - - if (!found[len]) { - if (args->pos + 1 == args->argc) - fatal("expected value following argument", opt); - args->pos += 1; - *out = args->argv[args->pos]; - return 1; - } - - if (found[len] == '=') { - *out = found + len + 1; - return 1; - } - - return 0; -} - -static const char *match_numeric_arg(struct args_info *args, const char *opt) -{ - const char *found = args->argv[args->pos]; - size_t len = is_prefixed(found, opt); - - if (!len) - return NULL; - - if (!found[len]) { - if (args->pos + 1 == args->argc) - fatal("expected numeric value following argument", opt); - args->pos += 1; - found = args->argv[args->pos]; - } else { - found = found + len; - if (*found == '=') - found++; - } - - return found; -} - -int match_uint16_arg( - uint16_t *out, struct args_info *args, const char *opt) -{ - const char *found = match_numeric_arg(args, opt); - uint16_t val; - char *endptr = NULL; - - if (!found) - return 0; - - val = (uint16_t)strtoul(found, &endptr, 0); - if (!endptr || *endptr != '\0') - fatal("expected number after argument", opt); - - if (out) - *out = val; - return 1; -} - -int match_uint32_arg( - uint32_t *out, struct args_info *args, const char *opt) -{ - const char *found = match_numeric_arg(args, opt); - uint16_t val; - char *endptr = NULL; - - if (!found) - return 0; - - val = (uint32_t)strtoul(found, &endptr, 0); - if (!endptr || *endptr != '\0') - fatal("expected number after argument", opt); - - if (out) - *out = val; - return 1; -} - -static int match_int_internal( - int *out, const char *str, int allow_negative, const char *opt) -{ - char *endptr = NULL; - int val = (int)strtol(str, &endptr, 10); - - if (!endptr || *endptr != '\0') - fatal("expected number", opt); - else if (val < 0 && !allow_negative) - fatal("negative values are not allowed", opt); - - if (out) - *out = val; - - return 1; -} - -int match_bool_arg(int *out, struct args_info *args, const char *opt) -{ - const char *found = args->argv[args->pos]; - - if (!strcmp(found, opt)) { - *out = 1; - return 1; - } - - if (!strncmp(found, "--no-", strlen("--no-")) && - !strcmp(found + strlen("--no-"), opt + 2)) { - *out = 0; - return 1; - } - - *out = -1; - return 0; -} - -int is_integer(int *out, const char *str, int allow_negative) -{ - return match_int_internal(out, str, allow_negative, NULL); -} - -int match_int_arg( - int *out, struct args_info *args, const char *opt, int allow_negative) -{ - const char *found = match_numeric_arg(args, opt); - if (!found) - return 0; - return match_int_internal(out, found, allow_negative, opt); -} - int diff_output( const git_diff_delta *d, const git_diff_hunk *h, diff --git a/examples/common.h b/examples/common.h index 3657e539b..5a029b49a 100644 --- a/examples/common.h +++ b/examples/common.h @@ -52,6 +52,8 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(*x)) #define UNUSED(x) (void)(x) +#include "args.h" + extern int lg2_add(git_repository *repo, int argc, char **argv); extern int lg2_blame(git_repository *repo, int argc, char **argv); extern int lg2_cat_file(git_repository *repo, int argc, char **argv); @@ -97,77 +99,6 @@ extern char *read_file(const char *path); extern void fatal(const char *message, const char *extra); /** - * Check if a string has the given prefix. Returns 0 if not prefixed - * or the length of the prefix if it is. - */ -extern size_t is_prefixed(const char *str, const char *pfx); - -/** - * Match an integer string, returning 1 if matched, 0 if not. - */ -extern int is_integer(int *out, const char *str, int allow_negative); - -struct args_info { - int argc; - char **argv; - int pos; -}; -#define ARGS_INFO_INIT { argc, argv, 0 } - -/** - * Check current `args` entry against `opt` string. If it matches - * exactly, take the next arg as a string; if it matches as a prefix with - * an equal sign, take the remainder as a string; if value not supplied, - * default value `def` will be given. otherwise return 0. - */ -extern int optional_str_arg( - const char **out, struct args_info *args, const char *opt, const char *def); - -/** - * Check current `args` entry against `opt` string. If it matches - * exactly, take the next arg as a string; if it matches as a prefix with - * an equal sign, take the remainder as a string; otherwise return 0. - */ -extern int match_str_arg( - const char **out, struct args_info *args, const char *opt); - -/** - * Check current `args` entry against `opt` string parsing as uint16. If - * `opt` matches exactly, take the next arg as a uint16_t value; if `opt` - * is a prefix (equal sign optional), take the remainder of the arg as a - * uint16_t value; otherwise return 0. - */ -extern int match_uint16_arg( - uint16_t *out, struct args_info *args, const char *opt); - -/** - * Check current `args` entry against `opt` string parsing as uint32. If - * `opt` matches exactly, take the next arg as a uint16_t value; if `opt` - * is a prefix (equal sign optional), take the remainder of the arg as a - * uint32_t value; otherwise return 0. - */ -extern int match_uint32_arg( - uint32_t *out, struct args_info *args, const char *opt); - -/** - * Check current `args` entry against `opt` string parsing as int. If - * `opt` matches exactly, take the next arg as an int value; if it matches - * as a prefix (equal sign optional), take the remainder of the arg as a - * int value; otherwise return 0. - */ -extern int match_int_arg( - int *out, struct args_info *args, const char *opt, int allow_negative); - -/** - * Check current `args` entry against a "bool" `opt` (ie. --[no-]progress). - * If `opt` matches positively, out will be set to 1, or if `opt` matches - * negatively, out will be set to 0, and in both cases 1 will be returned. - * If neither the positive or the negative form of opt matched, out will be -1, - * and 0 will be returned. - */ -extern int match_bool_arg(int *out, struct args_info *args, const char *opt); - -/** * Basic output function for plain text diff output * Pass `FILE*` such as `stdout` or `stderr` as payload (or NULL == `stdout`) */ |