Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added required options #33

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions argparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ argparse_error(struct argparse *self, const struct argparse_option *opt,
}

static int
argparse_getvalue(struct argparse *self, const struct argparse_option *opt,
argparse_getvalue(struct argparse *self, struct argparse_option *opt,
int flags)
{
const char *s = NULL;
opt->parsed = 1;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why setting this for all arguments?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I thought it would be the simplest solution to the problem. You set it to 1 for arguments that are used at the command line and at the end of parsing you simply check if the required options have been parsed (meaning used in this context).

if (!opt->value)
goto skipped;
switch (opt->type) {
Expand Down Expand Up @@ -147,7 +148,7 @@ argparse_options_check(const struct argparse_option *options)
}

static int
argparse_short_opt(struct argparse *self, const struct argparse_option *options)
argparse_short_opt(struct argparse *self, struct argparse_option *options)
{
for (; options->type != ARGPARSE_OPT_END; options++) {
if (options->short_name == *self->optvalue) {
Expand All @@ -159,7 +160,7 @@ argparse_short_opt(struct argparse *self, const struct argparse_option *options)
}

static int
argparse_long_opt(struct argparse *self, const struct argparse_option *options)
argparse_long_opt(struct argparse *self, struct argparse_option *options)
{
for (; options->type != ARGPARSE_OPT_END; options++) {
const char *rest;
Expand Down Expand Up @@ -218,9 +219,22 @@ argparse_describe(struct argparse *self, const char *description,
self->epilog = epilog;
}

void argparse_check_for_required(struct argparse *self, struct argparse_option *options) {
for(; options->type != ARGPARSE_OPT_END; options++) {
// printf("checking %s %d %d\n", options->long_name, options->parsed, options->flags);
if((options->flags & OPT_REQUIRED) == OPT_REQUIRED && !options->parsed) {
// error => required option not parsed
fprintf(stderr, "error: option `%s` required\n", options->long_name);
argparse_usage(self);
exit(1);
}
}
}

int
argparse_parse(struct argparse *self, int argc, const char **argv)
{

self->argc = argc - 1;
self->argv = argv + 1;
self->out = argv;
Expand Down Expand Up @@ -278,6 +292,9 @@ argparse_parse(struct argparse *self, int argc, const char **argv)
}

end:
// check required options and exit if not all flags are satisfied
argparse_check_for_required(self, self->options);

memmove(self->out + self->cpidx, self->argv,
self->argc * sizeof(*self->out));
self->out[self->cpidx + self->argc] = NULL;
Expand All @@ -302,7 +319,7 @@ argparse_usage(struct argparse *self)

fputc('\n', stdout);

const struct argparse_option *options;
struct argparse_option *options;

// figure out best width
size_t usage_opts_width = 0;
Expand Down
22 changes: 14 additions & 8 deletions argparse.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum argparse_option_type {

enum argparse_option_flags {
OPT_NONEG = 1, /* disable negation */
OPT_REQUIRED
};

/**
Expand Down Expand Up @@ -70,6 +71,9 @@ enum argparse_option_flags {
*
* `flags`:
* option flags.
*
* * `parsed`:
* boolean to see if the option showed up in the argument list.
*/
struct argparse_option {
enum argparse_option_type type;
Expand All @@ -80,14 +84,15 @@ struct argparse_option {
argparse_callback *callback;
intptr_t data;
int flags;
int parsed;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need this, you define it as a flag

};

/**
* argpparse
*/
struct argparse {
// user supplied
const struct argparse_option *options;
struct argparse_option *options;
const char *const *usages;
int flags;
const char *description; // a description after usage
Expand All @@ -105,13 +110,14 @@ int argparse_help_cb(struct argparse *self,
const struct argparse_option *option);

// built-in option macros
#define OPT_END() { ARGPARSE_OPT_END, 0, NULL, NULL, 0, NULL, 0, 0 }
#define OPT_BOOLEAN(...) { ARGPARSE_OPT_BOOLEAN, __VA_ARGS__ }
#define OPT_BIT(...) { ARGPARSE_OPT_BIT, __VA_ARGS__ }
#define OPT_INTEGER(...) { ARGPARSE_OPT_INTEGER, __VA_ARGS__ }
#define OPT_FLOAT(...) { ARGPARSE_OPT_FLOAT, __VA_ARGS__ }
#define OPT_STRING(...) { ARGPARSE_OPT_STRING, __VA_ARGS__ }
#define OPT_GROUP(h) { ARGPARSE_OPT_GROUP, 0, NULL, NULL, h, NULL, 0, 0 }
// initially all parsed values for options are 0
#define OPT_END() { ARGPARSE_OPT_END, 0, NULL, NULL, 0, NULL, 0, 0, 0 }
#define OPT_BOOLEAN(...) { ARGPARSE_OPT_BOOLEAN, __VA_ARGS__, 0 }
#define OPT_BIT(...) { ARGPARSE_OPT_BIT, __VA_ARGS__, 0 }
#define OPT_INTEGER(...) { ARGPARSE_OPT_INTEGER, __VA_ARGS__, 0 }
#define OPT_FLOAT(...) { ARGPARSE_OPT_FLOAT, __VA_ARGS__, 0 }
#define OPT_STRING(...) { ARGPARSE_OPT_STRING, __VA_ARGS__, 0 }
#define OPT_GROUP(h) { ARGPARSE_OPT_GROUP, 0, NULL, NULL, h, NULL, 0, 0, 0 }
#define OPT_HELP() OPT_BOOLEAN('h', "help", NULL, \
"show this help message and exit", \
argparse_help_cb, 0, OPT_NONEG)
Expand Down