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)
            void   *target;
            bool    seen; // set during parse so missing-required can be checked
        } ArgSpec;
    
        typedef Vec(ArgSpec) ArgSpecs;
        } ArgSpec;
    
        typedef Vec(ArgSpec) ArgSpecs;
    
        ///
    // ---------------------------------------------------------------------------
    
    static ArgSpec *find_long(ArgParse *self, Zstr long_name) {
        VecForeachPtr(&self->specs, sp) {
            if (sp->role == ARG_ROLE_POSITIONAL)
    }
    
    static ArgSpec *find_short(ArgParse *self, Zstr 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) {
        Zstr 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 = StrLen(out);
        StrPushBackMany(out, "  ");
        bool printed_options_header    = false;
        for (u64 i = 0; i < n_specs; ++i) {
            ArgSpec *sp = VecPtrAt(&self->specs, i);
            if (sp->role != ARG_ROLE_POSITIONAL)
                continue;
    
        for (u64 i = 0; i < n_specs; ++i) {
            ArgSpec *sp = VecPtrAt(&self->specs, 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);
                StrResize(&buf, 2);
    
                ArgSpec *sp = find_short(self, (Zstr)data);
                if (!sp) {
                    FWriteFmtLn(err, "{}: unknown option: {}", self->name, (Zstr)data);
        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";
                            StrResize(&two, 2);
    
                            ArgSpec *first = find_short(self, (Zstr)data);
                            if (first && (first->role == ARG_ROLE_FLAG || first->role == ARG_ROLE_COUNT)) {
                                decision = BUNDLE_TRY;
            // Find the n-th positional spec.
            u64      seen = 0;
            ArgSpec *pos  = NULL;
            VecForeachPtr(&self->specs, sp) {
                if (sp->role != ARG_ROLE_POSITIONAL)
Last updated on