Skip to content

ArgSpec

Description

Internal registration record. One entry per ArgRequired / ArgOptional / ArgFlag / ArgCount / ArgPositional call. Lives in the ArgParse.specs Vec; populated at registration time, mutated during ArgParseRun.

Usage example (Cross-references)

Usage examples (Cross-references)
    /* ------------------------------------------------------------------ */
    
    static ArgSpec *find_long(ArgParse *self, const char *long_name) {
        VecForeachPtr(&self->specs, sp) {
            if (sp->role == ARG_ROLE_POSITIONAL)
    }
    
    static ArgSpec *find_short(ArgParse *self, const char *short_name) {
        VecForeachPtr(&self->specs, sp) {
            if (sp->role == ARG_ROLE_POSITIONAL)
    // long-flag name upper-cased and hyphens swapped for underscores. For
    // short-only options without a long form we fall back to "VALUE".
    static void append_metavar(Str *out, const ArgSpec *sp) {
        const char *src = sp->long_name;
        if (!src) {
    // Build the "  -l, --listen <LISTEN>" left column for one spec. Returns
    // the visible width so the caller can pad to a shared right margin.
    static u64 spec_format_left(const ArgSpec *sp, Str *out) {
        u64 start = out->length;
        StrPushBackZstr(out, "  ");
        bool printed_options_header    = false;
        for (u64 i = 0; i < n_specs; ++i) {
            ArgSpec *sp = &self->specs.data[i];
            if (sp->role != ARG_ROLE_POSITIONAL)
                continue;
    
        for (u64 i = 0; i < n_specs; ++i) {
            ArgSpec *sp = &self->specs.data[i];
            if (sp->role == ARG_ROLE_POSITIONAL)
                continue;
        }
    
        ArgSpec sp    = {0};
        sp.short_name = short_name;
        sp.long_name  = long_name;
        }
    
        ArgSpec *sp = is_long ? find_long(self, flag) : find_short(self, flag);
        if (!sp) {
            FWriteFmtLn(err, "{}: unknown option: {}", self->name, flag);
        for (const char *p = tok + 1; *p; ++p) {
            char     buf[3] = {'-', *p, 0};
            ArgSpec *sp     = find_short(self, (const char *)buf);
            if (!sp) {
                FWriteFmtLn(err, "{}: unknown option: {}", self->name, (const char *)buf);
        if (!already_has_help) {
            // Help has no target; we short-circuit before any store_value.
            ArgSpec help    = {0};
            help.short_name = "-h";
            help.long_name  = "--help";
                    if (tok[2] != '\0') {
                        char     two[3] = {'-', tok[1], 0};
                        ArgSpec *first  = find_short(self, (const char *)two);
                        if (first && (first->role == ARG_ROLE_FLAG || first->role == ARG_ROLE_COUNT)) {
                            ArgRun r = handle_short_bundle(self, tok, &err);
            // Find the n-th positional spec.
            u64      seen = 0;
            ArgSpec *pos  = NULL;
            VecForeachPtr(&self->specs, sp) {
                if (sp->role != ARG_ROLE_POSITIONAL)
            void       *target;
            bool        seen; // set during parse so missing-required can be checked
        } ArgSpec;
    
        typedef Vec(ArgSpec) ArgSpecs;
        } ArgSpec;
    
        typedef Vec(ArgSpec) ArgSpecs;
    
        ///
Last updated on