diff --git a/readopt.c b/readopt.c index 2ec2129..8776a4e 100644 --- a/readopt.c +++ b/readopt.c @@ -26,9 +26,6 @@ static void permute_val(struct readopt_parser *rp, struct readopt_view_strings * static void incr_between(const char **start, const char **stop, struct readopt_view_strings *curr, struct readopt_view_strings *exclude); static void permute_rest(const char **target, struct readopt_view_strings start); -static void format_usage_opts(struct readopt_format_context *ctx, struct readopt_opt *opts); -static void format_usage_opers(struct readopt_format_context *ctx, struct readopt_oper *opers); - int readopt_parse(struct readopt_parser *rp) { @@ -419,226 +416,3 @@ readopt_select_lower(struct readopt_bounds bounds) { return bounds.inf ? readopt_select_upper(bounds) : bounds.val[0] < bounds.val[1] ? bounds.val[0] : bounds.val[1]; } - -char * -readopt_keyval(char *s) -{ - while (*s != '=') ++s; - *s = '\0'; - return ++s; -} - -int -readopt_put_error(enum readopt_error e, struct readopt_write_context *ctx) -{ - const char *s; - switch (e) { - case READOPT_ERROR_SUCCESS: s = "Success"; break; - case READOPT_ERROR_NOVAL: s = "Option did not receive its required value"; break; - case READOPT_ERROR_NOTREQ: s = "No value required for option"; break; - case READOPT_ERROR_NOTOPT: s = "Specified option does not exist"; break; - case READOPT_ERROR_RANGEOPT: s = "Option(s) are not within the defined limits"; break; - case READOPT_ERROR_RANGEOPER: s = "Operand(s) are not within the defined limits"; break; - default: return 0; - } - - readopt_write_string(ctx, s); - return 1; -} - -void -readopt_put_usage(struct readopt_parser *rp, struct readopt_format_context *ctx) -{ - assert(ctx->fmt == READOPT_FORMAT_MDOC || ctx->fmt == READOPT_FORMAT_PLAIN); - ctx->esc.needles = "-"; - ctx->esc.pre = '\\'; - format_usage_opts(ctx, rp->opts); - format_usage_opers(ctx, rp->opers); -} - -static void -format_usage_opts(struct readopt_format_context *ctx, struct readopt_opt *opts) -{ - int nxvalid = readopt_validate_opt(opts); - for (size_t i = 0; nxvalid; i++) { - nxvalid = readopt_validate_opt(opts + i + 1); - size_t lower = readopt_select_lower(opts[i].cont.oper.bounds); - size_t upper = readopt_select_upper(opts[i].cont.oper.bounds); - int inf = opts[i].cont.oper.bounds.inf; - size_t nforms = sizeof opts[i].names / sizeof *opts[i].names; - - for (size_t j = 0; j < (upper ? upper : !!inf); j++) { - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, '.'); - if (j >= lower) { - readopt_cond_write_string(READOPT_FORMAT_MDOC, ctx, "Op "); - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, '['); - } - - for (size_t k = 0; k < nforms; k++) { - int grp = 0; - if (opts[i].names[k]) { - for (size_t l = 0; opts[i].names[k][l]; l++) { - if (!grp) { - readopt_cond_write_string(READOPT_FORMAT_MDOC, ctx, "Fl \\&"); - - if (k == READOPT_FORM_SHORT) { - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, '-'); - } - - if (k == READOPT_FORM_LONG) { - readopt_cond_write_string(READOPT_FORMAT_MDOC, ctx, "\\-"); - readopt_cond_write_string(READOPT_FORMAT_PLAIN, ctx, "--"); - } - } - - readopt_cond_write_esc_string(READOPT_FORMAT_MDOC, ctx, opts[i].names[k][l]); - readopt_cond_write_string(READOPT_FORMAT_PLAIN, ctx, opts[i].names[k][l]); - - if (k == READOPT_FORM_SHORT) { - grp = 1; - if (!opts[i].names[k][l + 1]) { - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, ' '); - readopt_write_string(ctx->wr, ", "); - } - continue; - } else if (k + 1 < nforms || opts[i].names[k][l + 1]) { - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, ' '); - readopt_write_string(ctx->wr, ", "); - } else { - if (opts[i].cont.req){ - readopt_write_char(ctx->wr, ' '); - readopt_cond_write_string(READOPT_FORMAT_MDOC, ctx, "Ar "); - if (opts[i].cont.oper.name) { - readopt_cond_write_esc_string(READOPT_FORMAT_MDOC, ctx, opts[i].cont.oper.name); - readopt_cond_write_string(READOPT_FORMAT_PLAIN, ctx, opts[i].cont.oper.name); - } else { - readopt_write_string(ctx->wr, "value"); - } - - if (inf) { - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, ' '); - readopt_write_string(ctx->wr, "..."); - } - } - } - } - } - } - - if (j >= lower) { - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, ']'); - } - - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, '\n'); - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, ' '); - } - } -} - -static void -format_usage_opers(struct readopt_format_context *ctx, struct readopt_oper *opers) -{ - int nxvalid = readopt_validate_oper(opers); - for (size_t i = 0; nxvalid; i++) { - nxvalid = readopt_validate_oper(opers + i + 1); - size_t lower = readopt_select_lower(opers[i].bounds); - size_t upper = readopt_select_upper(opers[i].bounds); - int inf = opers[i].bounds.inf; - - for (size_t j = 0; j < lower; j++) { - readopt_cond_write_string(READOPT_FORMAT_MDOC, ctx, ".Ar \\&"); - - readopt_cond_write_esc_string(READOPT_FORMAT_MDOC, ctx, opers[i].name); - readopt_cond_write_string(READOPT_FORMAT_PLAIN, ctx, opers[i].name); - - if (inf && j + 1 == lower) { - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, ' '); - readopt_write_string(ctx->wr, "..."); - } - - if (nxvalid) { - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, ' '); - } - - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, '\n'); - } - - size_t amt = upper ? upper : inf ? lower + 1 : 0; - for (size_t j = lower; j < amt; j++) { - readopt_cond_write_string(READOPT_FORMAT_MDOC, ctx, ".Op Ar \\&"); - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, '['); - - readopt_cond_write_esc_string(READOPT_FORMAT_MDOC, ctx, opers[i].name); - readopt_cond_write_string(READOPT_FORMAT_PLAIN, ctx, opers[i].name); - - if (inf && j + 1 == amt) { - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, ' '); - readopt_write_string(ctx->wr, "..."); - } - - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, ']'); - - if (nxvalid) { - readopt_cond_write_char(READOPT_FORMAT_PLAIN, ctx, ' '); - } - - readopt_cond_write_char(READOPT_FORMAT_MDOC, ctx, '\n'); - } - } -} - -void -readopt_cond_write_esc_string(enum readopt_format desired, struct readopt_format_context *ctx, const char *string) -{ - if (ctx->fmt == desired) readopt_write_esc_string(ctx, string); -} - -void -readopt_cond_write_string(enum readopt_format desired, struct readopt_format_context *ctx, const char *string) -{ - if (ctx->fmt == desired) readopt_write_string(ctx->wr, string); -} - -void -readopt_cond_write_char(enum readopt_format desired, struct readopt_format_context *ctx, char ch) -{ - if (ctx->fmt == desired) readopt_write_char(ctx->wr, ch); -} - -void -readopt_write_esc_string(struct readopt_format_context *ctx, const char *string) -{ - char *s = (char *)string; - for (; *s; ++s) { - if (strchr(ctx->esc.needles, *s) && *s) { - readopt_write_char(ctx->wr, ctx->esc.pre); - } - readopt_write_char(ctx->wr, *s); - } -} - -void -readopt_write_string(struct readopt_write_context *ctx, const char *string) -{ - ctx->src.len = strlen(string); - ctx->src.payload = string; - readopt_write_stream(ctx); -} - -void -readopt_write_char(struct readopt_write_context *ctx, char ch) -{ - ctx->src.len = sizeof (ch); - ctx->src.payload = &ch; - readopt_write_stream(ctx); -} - -void -readopt_write_stream(struct readopt_write_context *ctx) -{ - while (ctx->callback && (ctx->src.len > ctx->dest.size || !ctx->dest.stream)) - if (!ctx->callback(ctx)) - return; - - ctx->written += fwrite(ctx->src.payload, ctx->src.len, 1, ctx->dest.stream); -} diff --git a/readopt.h b/readopt.h index 8bd183c..fc0cf05 100644 --- a/readopt.h +++ b/readopt.h @@ -115,18 +115,3 @@ int readopt_validate_within(struct readopt_oper *oper); size_t readopt_select_upper(struct readopt_bounds bounds); /* get the lower limit (this does not always return the minimum, if e.g. .val is {0, 1} and inf != 0, then 1 will be considered the lower limit as well as the upper limit) */ size_t readopt_select_lower(struct readopt_bounds bounds); -/* pass a string like "thing=value" and get "value" back */ -char *readopt_keyval(char *s); - -/* write the passed error as a string via ctx */ -int readopt_put_error(enum readopt_error error, struct readopt_write_context *ctx); -/* write the usage string, either as plaintext or mdoc format */ -void readopt_put_usage(struct readopt_parser *rp, struct readopt_format_context *ctx); - -void readopt_write_stream(struct readopt_write_context *ctx); -void readopt_write_string(struct readopt_write_context *ctx, const char *string); -void readopt_write_char(struct readopt_write_context *ctx, char ch); -void readopt_cond_write_string(enum readopt_format desired, struct readopt_format_context *ctx, const char *string); -void readopt_cond_write_char(enum readopt_format desired, struct readopt_format_context *ctx, char ch); -void readopt_write_esc_string(struct readopt_format_context *ctx, const char *string); -void readopt_cond_write_esc_string(enum readopt_format desired, struct readopt_format_context *ctx, const char *string);