Skip to content

ArgRun

Description

ArgParseRun return value. Lets the caller distinguish “continue main” from “help printed, exit 0” from “error printed, exit 1” without overloading bool.

Usage example (Cross-references)

Usage examples (Cross-references)
    
        char  *argv[] = {(char *)"prog", (char *)"--listen", (char *)"0.0.0.0:8080"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_OK) && listen && ZstrCompare(listen, "0.0.0.0:8080") == 0;
    
        char  *argv[] = {(char *)"prog", (char *)"--listen=0.0.0.0:8080"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_OK) && listen && ZstrCompare(listen, "0.0.0.0:8080") == 0;
    
        char  *argv[] = {(char *)"prog", (char *)"-l", (char *)"127.0.0.1:9"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_OK) && listen && ZstrCompare(listen, "127.0.0.1:9") == 0;
    
        char  *argv[] = {(char *)"prog"};
        ArgRun rc     = ArgParseRun(&p, 1, argv);
    
        bool ok = (rc == ARG_RUN_OK) && timeout == 30;
    
        char  *argv[] = {(char *)"prog", (char *)"--timeout", (char *)"5"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_OK) && timeout == 5;
    
        char  *argv[] = {(char *)"prog", (char *)"--verbose"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_OK) && verbose == true;
    
        char  *argv[] = {(char *)"prog"};
        ArgRun rc     = ArgParseRun(&p, 1, argv);
    
        bool ok = (rc == ARG_RUN_OK) && verbose == false;
    
        char  *argv[] = {(char *)"prog", (char *)"-v", (char *)"-v", (char *)"-v"};
        ArgRun rc     = ArgParseRun(&p, 4, argv);
    
        bool ok = (rc == ARG_RUN_OK) && verbose == 3;
    
        char  *argv[] = {(char *)"prog", (char *)"-vvv"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_OK) && verbose == 3;
    
        char  *argv[] = {(char *)"cp", (char *)"a.txt", (char *)"b.txt"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_OK) && ZstrCompare(src, "a.txt") == 0 && ZstrCompare(dst, "b.txt") == 0;
    
        char  *argv[] = {(char *)"cp", (char *)"a.txt", (char *)"-v", (char *)"b.txt"};
        ArgRun rc     = ArgParseRun(&p, 4, argv);
    
        bool ok = (rc == ARG_RUN_OK) && ZstrCompare(src, "a.txt") == 0 && ZstrCompare(dst, "b.txt") == 0 && verbose == true;
    
        char  *argv[] = {(char *)"prog", (char *)"--n=12345"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_OK) && n == 12345;
    
        char  *argv[] = {(char *)"prog", (char *)"--v", (char *)"-42"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_OK) && v == -42;
    
        char  *argv[] = {(char *)"prog", (char *)"--ratio=2.5"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_OK) && ratio > 2.4 && ratio < 2.6;
    
        char  *argv[] = {(char *)"prog", (char *)"--name", (char *)"alice"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_OK) && name.length == 5 && name.data[0] == 'a' && name.data[4] == 'e';
    
        char  *argv[] = {(char *)"prog"};
        ArgRun rc     = ArgParseRun(&p, 1, argv);
    
        bool ok = (rc == ARG_RUN_ERROR) && listen == NULL;
    
        char  *argv[] = {(char *)"cp", (char *)"a.txt"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_ERROR);
    
        char  *argv[] = {(char *)"prog", (char *)"--bogus"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_ERROR);
    
        char  *argv[] = {(char *)"prog", (char *)"--n", (char *)"abc"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_ERROR) && n == 0;
    
        char  *argv[] = {(char *)"prog", (char *)"--v=256"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        bool ok = (rc == ARG_RUN_ERROR) && v == 0;
    
        char  *argv[] = {(char *)"prog", (char *)"first", (char *)"extra"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_ERROR);
        // forces it to be a positional.
        char  *argv[] = {(char *)"cat", (char *)"--", (char *)"--unusual-name"};
        ArgRun rc     = ArgParseRun(&p, 3, argv);
    
        bool ok = (rc == ARG_RUN_OK) && ZstrCompare(file, "--unusual-name") == 0;
    
        char  *argv[] = {(char *)"prog", (char *)"--help"};
        ArgRun rc     = ArgParseRun(&p, 2, argv);
    
        // --help should beat the missing-required check.
    // `ARG_RUN_OK` to continue, `ARG_RUN_HELP` if this token was --help,
    // `ARG_RUN_ERROR` on failure (after printing the error).
    static ArgRun handle_option_token(
        ArgParse   *self,
        const char *tok,  // the current argv[i] token
    // when -v is a Flag or a Count. -lFOO (stuck value) is intentionally
    // not supported in v1.
    static ArgRun handle_short_bundle(ArgParse *self, const char *tok, File *err) {
        // tok looks like "-XYZ..."; verify every char maps to a Flag/Count.
        for (const char *p = tok + 1; *p; ++p) {
    }
    
    ArgRun ArgParseRun(ArgParse *self, int argc, char **argv) {
        if (!self || argc < 0 || (argc > 0 && !argv)) {
            LOG_ERROR("ArgParseRun: bad arguments");
                }
                if (tok[0] == '-' && tok[1] == '-' && tok[2] != '\0') {
                    ArgRun r = handle_option_token(self, tok, &i, argc, argv, &err);
                    if (r != ARG_RUN_OK)
                        return r;
                        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);
                            if (r != ARG_RUN_OK)
                                return r;
                        return ARG_RUN_ERROR;
                    }
                    ArgRun r = handle_option_token(self, tok, &i, argc, argv, &err);
                    if (r != ARG_RUN_OK)
                        return r;
            ARG_RUN_HELP,  // `--help` printed; caller should exit 0
            ARG_RUN_ERROR, // bad input, error printed; caller should exit non-zero
        } ArgRun;
    
        ///
        ///           `ARG_RUN_ERROR` (parse error logged + usage hint).
        ///
        ArgRun ArgParseRun(ArgParse *self, int argc, char **argv);
    
        ///
            ArgRequired(&ap, "-u", "--upstream", &upstream_spec, "upstream host:port");
    
            ArgRun rc = ArgParseRun(&ap, argc, argv);
            ArgParseDeinit(&ap);
            if (rc != ARG_RUN_OK) {
            ArgPositional(&ap, "hostname", &hostname, "name to resolve");
    
            ArgRun rc = ArgParseRun(&ap, argc, argv);
            ArgParseDeinit(&ap);
            if (rc != ARG_RUN_OK) {
Last updated on