@@ 2,6 2,7 @@
* sc-argparse.c: simple argument parsing library
*/
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ 18,11 19,14 @@ enum error {
STOP_PROCESSING,
};
-enum arg {
- POSITIONAL, /* a positional arg */
- FLAG_ONE, /* flag like "-c", or "--key=val" */
- FLAG_TWO, /* flag like "-o filename" or "--key value" */
-};
+#define error(err, state) \
+ do { \
+ if (state->printerr) { \
+ fprintf(stderr, "%s:%d: Encountered %s, argidx=%d\n", \
+ __FILE__, __LINE__, #err, state->argidx); \
+ } \
+ return err; \
+ } while (0)
struct state {
struct sc_arg *argspec;
@@ 30,6 34,7 @@ struct state {
int pos;
char **argv;
int argidx;
+ bool printerr;
};
static struct sc_arg *sc_get_arg_by_flag(struct sc_arg *argspec, char flag)
@@ 60,7 65,7 @@ static enum error sc_process_short_flag(struct state *state, int i)
arg_struct = sc_get_arg_by_flag(state->argspec, arg[i]);
if (!arg_struct)
- return UNKNOWN_SHORT_FLAG;
+ error(UNKNOWN_SHORT_FLAG, state);
arg_struct->seen = true;
if (arg_struct->type == SC_ARG_TYPE_COUNT) {
@@ 71,10 76,10 @@ static enum error sc_process_short_flag(struct state *state, int i)
/* At this point, we must have a value. Ensure that
* there are no short flags after this one. */
if (arg[i + 1] != '\0')
- return SHORT_FLAG_WITH_PARAM_NOT_AT_END;
+ error(SHORT_FLAG_WITH_PARAM_NOT_AT_END, state);
if (state->argidx + 1 >= state->argc)
- return SHORT_FLAG_MISSING_VAL;
+ error(SHORT_FLAG_MISSING_VAL, state);
/* TODO assign args */
if (arg_struct->type == SC_ARG_TYPE_STRING) {
@@ 103,13 108,13 @@ static enum error sc_process_long_flag(struct state *state)
*equal = '=';
}
if (!arg_struct)
- return UNKNOWN_LONG_FLAG;
+ error(UNKNOWN_LONG_FLAG, state);
arg_struct->seen = true;
if (arg_struct->type == SC_ARG_TYPE_COUNT) {
if (equal)
- return LONG_FLAG_NO_PARAM_HAS_PARAM;
+ error(LONG_FLAG_NO_PARAM_HAS_PARAM, state);
arg_struct->val_int++;
return NO_ERROR;
}
@@ 119,7 124,7 @@ static enum error sc_process_long_flag(struct state *state)
value = equal + 1;
} else {
if (state->argidx + 1 >= state->argc)
- return LONG_FLAG_MISSING_VAL;
+ error(LONG_FLAG_MISSING_VAL, state);
value = state->argv[++state->argidx];
}
@@ 165,6 170,7 @@ int sc_argparse(struct sc_arg argspec[], int argc, char **argv)
state.argv = argv;
state.argspec = argspec;
state.pos = 0;
+ state.printerr = true;
for (state.argidx = 0; state.argidx < state.argc; state.argidx++) {
err = sc_process_arg(&state);
if (err == NO_ERROR) {