Skip to content

argparse-c

argparse-c is a C99 CLI parsing library with a Python argparse-style authoring experience.

Build C99 CLIs with Python argparse-like ergonomics — including completion, manpage generation, subcommands, and known-args parsing.

This repository is maintained with a full AI-coding workflow (design, implementation, and documentation updates are AI-assisted end to end).

README (日本語) Docs (English) Docs (日本語) Docs (简体中文) Docs (Español) Docs (Português (Brasil))

Start here

Legend:

  • Full support: English / 日本語 (README + GitHub Pages are maintained together).
  • Partial support: 简体中文 / Español / Português (Brasil) (GitHub Pages is available with staged rollout coverage).

If you want the installation steps, completion setup, package metadata, or API details, jump to GitHub Pages first. The repository README now stays focused on what this library is, why it is useful, and which examples to open next.

What is argparse-c?

The English and Japanese READMEs are kept at the same level of detail for the overview, benefits, and feature list. Detailed setup and feature usage live in the docs site.

argparse-c helps you define command-line interfaces in C99 without hand-writing low-level argument scanning and validation logic. You declare a parser, add options and positionals, parse argv, and read values from a namespace.

It is designed for applications that want modern CLI behavior while keeping control in the application:

  • Python argparse-inspired parser construction
  • Optional arguments, positional arguments, defaults, required flags, and choices
  • nargs, append/count/store-const actions, and mutually exclusive groups
  • Nested subcommands
  • Shell completion for bash/fish/zsh and manpage generation from the same parser definition
  • ap_parse_known_args(...) for forwarding unknown arguments
  • Non-exit error handling so your app decides what to print and when to return

Why it is convenient

1. Write CLIs in a familiar style

If you already know Python argparse, the overall flow will feel familiar: create a parser, add arguments, parse, then read typed values.

2. Cover real CLI needs without bolting on extra tooling

A single parser definition can power:

  • user-facing help
  • shell completion entrypoints
  • manpage generation
  • nested command trees
  • known/unknown argument splitting for wrapper commands

3. Keep control in the application

argparse-c does not force exit() on parse failure. Your program receives structured errors and can decide whether to format them, recover, or continue.

See the experience

Animated terminal demo showing argparse-c surfacing help output, shell completion candidates, and friendly validation errors from one sample parser definition.

This animation is generated from the runnable sample/example_completion.c flow. It focuses on the end-user experience you get after wiring one parser definition:

  • --help
  • hidden __complete transport for shell completion
  • clear validation errors when input is wrong

What kind of CLI can you build quickly?

Examples that are easy to assemble with argparse-c:

  • a single-command tool with required flags and positional files
  • a Git-style multi-command CLI with nested subcommands
  • a wrapper command that parses known flags and forwards the rest
  • a CLI that generates bash/fish/zsh completion scripts and a manpage from one definition

See these runnable samples in this repository:

For the walkthrough behind those examples, use GitHub Pages:

Minimal example

#include <stdio.h>
#include <stdlib.h>

#include "argparse-c.h"

int main(int argc, char **argv) {
  ap_error err = {0};
  ap_namespace *ns = NULL;
  ap_parser *parser = ap_parser_new("demo", "demo parser");

  ap_arg_options text = ap_arg_options_default();
  text.required = true;
  text.help = "input text";
  ap_add_argument(parser, "-t, --text", text, &err);

  if (ap_parse_args(parser, argc, argv, &ns, &err) != 0) {
    char *message = ap_format_error(parser, &err);
    fprintf(stderr, "%s", message ? message : err.message);
    free(message);
    ap_parser_free(parser);
    return 1;
  }

  {
    const char *value = NULL;
    if (ap_ns_get_string(ns, "text", &value)) {
      printf("text=%s\n", value);
    }
  }

  ap_namespace_free(ns);
  ap_parser_free(parser);
  return 0;
}

Want the full setup, build commands, and next APIs to learn? Go to:

Installation and packaging

argparse-c provides both CMake package metadata and a pkg-config file after installation.

GitHub Releases also publish an install-tree tarball for library consumers. The README keeps this short on purpose; use Getting Started for the exact commands and layout details.

Completion (bash/fish/zsh), manpages, and API reference

The README no longer carries the detailed setup steps. Use the docs site for complete guidance:

Documentation map

English

日本語

Security validation status and scope

Out of guarantee scope

  • Input/output validation in the consuming application remains the responsibility of the application developer.
  • Runtime/library/toolchain differences across operating systems and dependency environments can affect behavior and risk, and are outside this library's full guarantee scope.

Update rule

  • At each release, we review and update the wording in this section against the current CI/test evidence and the latest security-test procedure.

Development

Recommended common entry point for both AI agents and humans:

./scripts/dev_quick_check.sh

This quick check runs the minimum static validation flow in order: docs sync verification, format-check, and core tests.

If you want to run each step manually:

python scripts/verify_docs_repository_links.py
cmake -S . -B build
cmake --build build --target format-check
cmake --build build --target argparse_test example_completion example_manpage
ctest --test-dir build --output-on-failure -R '^argparse_test$'

Before finishing code changes, also run the project formatter:

cmake --build build --target format

Warning policy

Supported compilers and minimum versions

  • Target compilers for warning policy operation: GCC and Clang.
  • Minimum version policy (for local reproduction and CI parity):
  • GCC 11+
  • Clang 14+
  • Notes:
  • The warning gate runs both compilers in CI.
  • If a local environment uses older versions, reproduce with newer toolchains before concluding a warning policy result.

Local reproduction commands (English / 日本語)

English (configure/build/check)

# Configure (GCC)
cmake -S . -B build-warning-gcc -G Ninja \
  -DCMAKE_C_COMPILER=gcc \
  -DCMAKE_CXX_COMPILER=g++ \
  -DCMAKE_C_FLAGS='-Werror' \
  -DCMAKE_CXX_FLAGS='-Werror'

# Build (warning gate targets)
for target in argparse-c sample argparse_test; do
  cmake --build build-warning-gcc --target "${target}" --parallel
done

# Check (tests)
ctest --test-dir build-warning-gcc --output-on-failure
# Configure (Clang)
cmake -S . -B build-warning-clang -G Ninja \
  -DCMAKE_C_COMPILER=clang \
  -DCMAKE_CXX_COMPILER=clang++ \
  -DCMAKE_C_FLAGS='-Werror' \
  -DCMAKE_CXX_FLAGS='-Werror'

# Build (warning gate targets)
for target in argparse-c sample argparse_test; do
  cmake --build build-warning-clang --target "${target}" --parallel
done

# Check (tests)
ctest --test-dir build-warning-clang --output-on-failure

日本語(configure/build/check の再現)

# 設定(GCC)
cmake -S . -B build-warning-gcc -G Ninja \
  -DCMAKE_C_COMPILER=gcc \
  -DCMAKE_CXX_COMPILER=g++ \
  -DCMAKE_C_FLAGS='-Werror' \
  -DCMAKE_CXX_FLAGS='-Werror'

# ビルド(warning gate 対象)
for target in argparse-c sample argparse_test; do
  cmake --build build-warning-gcc --target "${target}" --parallel
done

# 確認(テスト)
ctest --test-dir build-warning-gcc --output-on-failure
# 設定(Clang)
cmake -S . -B build-warning-clang -G Ninja \
  -DCMAKE_C_COMPILER=clang \
  -DCMAKE_CXX_COMPILER=clang++ \
  -DCMAKE_C_FLAGS='-Werror' \
  -DCMAKE_CXX_FLAGS='-Werror'

# ビルド(warning gate 対象)
for target in argparse-c sample argparse_test; do
  cmake --build build-warning-clang --target "${target}" --parallel
done

# 確認(テスト)
ctest --test-dir build-warning-clang --output-on-failure

New code contribution criteria

  • Do not introduce new compiler warnings in GCC/Clang warning-gate configurations.
  • If warning suppression is unavoidable, keep it local (smallest scope possible: line/block/target).
  • Every suppression must include a short rationale comment (why unavoidable, and why the scoped suppression is safe).
  • Do not apply broad/global suppression flags as a first resort.

CI job mapping and failure triage

  • Warning policy related CI jobs (from .github/workflows/ci.yml):
  • warning-gateWarning gate (gcc) / Warning gate (clang) (-Werror configure and required-target build logs)
  • build-and-testBuild & Test (gcc) / Build & Test (clang) (full build and test execution)
  • clang-toolsClang format / tidy (style/static checks that often accompany warning policy changes)
  • Failure investigation path:
  • Open the failed workflow run and select the corresponding matrix job (gcc or clang).
  • For warning-gate failures, download warning-gate-logs-<compiler> artifact.
  • Re-run the same configure/build/check commands from this section locally.
  • Confirm formatter and quick checks before pushing fixes:
    • cmake --build build --target format
    • ./scripts/dev_quick_check.sh