Skip to content

A lightweight, portable CLI argument parsing library for C programs. A reusable and lightweight CLI argument parsing library for C programs. C (C99/C11), portable ANSI C, no external dependencies.

License

Notifications You must be signed in to change notification settings

BaseMax/c-argparse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

c-argparse

A lightweight, portable CLI argument parsing library for C programs.

License: MIT C Standard Platform

Features

  • Simple API - Easy to use with minimal boilerplate
  • Flags - Boolean options (e.g., -v, --verbose)
  • Options with values - String, integer, and float options (e.g., -o file, --output=file)
  • Positional arguments - Support for non-option arguments
  • Default values - Set default values for options
  • Automatic help generation - Built-in --help support
  • Error reporting - Clear error messages for invalid input
  • Portable - Works on Linux, macOS, and Windows
  • No dependencies - Pure C99, no external libraries required
  • Well tested - Comprehensive unit test suite

Quick Start

Building

make all        # Build library, examples, and tests
make test       # Run unit tests
make clean      # Clean build artifacts

Basic Example

#include <stdio.h>
#include "argparse.h"

int main(int argc, const char **argv)
{
    int verbose = 0;
    const char *output = NULL;
    int count = 10;  // Default value
    
    const argparse_option options[] = {
        ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Enable verbose output"),
        ARGPARSE_STRING("o", "output", &output, "Output file path"),
        ARGPARSE_INTEGER("n", "count", &count, "Number of iterations"),
        ARGPARSE_OPT_END_ENTRY
    };
    
    argparse parser;
    argparse_init(&parser, options, "A simple example program.", NULL);
    
    int result = argparse_parse(&parser, argc, argv);
    
    if (result < 0) {
        if (parser.error) {
            argparse_error(&parser);
        }
        argparse_cleanup(&parser);
        return 1;
    }
    
    printf("Verbose: %s\n", verbose ? "ON" : "OFF");
    printf("Output: %s\n", output ? output : "(none)");
    printf("Count: %d\n", count);
    
    argparse_cleanup(&parser);
    return 0;
}

API Reference

Data Types

argparse_option_type

Defines the type of a command-line option:

  • ARGPARSE_OPT_BOOLEAN - Boolean flag
  • ARGPARSE_OPT_STRING - String option
  • ARGPARSE_OPT_INTEGER - Integer option
  • ARGPARSE_OPT_FLOAT - Float option
  • ARGPARSE_OPT_POSITIONAL - Positional argument
  • ARGPARSE_OPT_GROUP - Group header for help text
  • ARGPARSE_OPT_END - Sentinel to mark end of options

argparse_option

Structure defining a single command-line option:

typedef struct argparse_option {
    argparse_option_type type;  // Type of option
    const char *short_name;     // Short option (e.g., "v" for -v)
    const char *long_name;      // Long option (e.g., "verbose" for --verbose)
    void *value;                // Pointer to variable to store value
    const char *help;           // Help text
    int flags;                  // Option flags
    void *default_value;        // Default value (optional)
} argparse_option;

argparse

Main parser context structure:

typedef struct argparse {
    const char *program_name;
    const char *description;
    const char *epilog;
    const argparse_option *options;
    int argc;
    const char **argv;
    int error;
    char error_msg[256];
    int positional_count;
    const char **positional_args;
    // ... internal fields
} argparse;

Functions

argparse_init()

Initialize the argument parser.

void argparse_init(argparse *parser, const argparse_option *options,
                   const char *description, const char *epilog);

Parameters:

  • parser - Pointer to parser context
  • options - Array of option definitions (must end with ARGPARSE_OPT_END_ENTRY)
  • description - Optional program description for help text
  • epilog - Optional epilog text for help

argparse_parse()

Parse command-line arguments.

int argparse_parse(argparse *parser, int argc, const char **argv);

Parameters:

  • parser - Pointer to initialized parser
  • argc - Argument count from main()
  • argv - Argument vector from main()

Returns:

  • Number of positional arguments parsed
  • -1 on error

argparse_help()

Print help message to stdout.

void argparse_help(const argparse *parser);

argparse_error()

Print error message to stderr.

void argparse_error(const argparse *parser);

argparse_cleanup()

Free resources allocated by the parser.

void argparse_cleanup(argparse *parser);

argparse_get_error()

Get the error message if parsing failed.

const char *argparse_get_error(const argparse *parser);

Returns:

  • Error message string, or NULL if no error

Helper Macros

ARGPARSE_BOOLEAN()

Define a boolean flag option.

ARGPARSE_BOOLEAN(short_opt, long_opt, var, help_text)

Example:

ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Enable verbose output")

ARGPARSE_STRING()

Define a string option.

ARGPARSE_STRING(short_opt, long_opt, var, help_text)

Example:

ARGPARSE_STRING("o", "output", &output, "Output file path")

ARGPARSE_INTEGER()

Define an integer option.

ARGPARSE_INTEGER(short_opt, long_opt, var, help_text)

Example:

ARGPARSE_INTEGER("n", "count", &count, "Number of iterations")

ARGPARSE_GROUP()

Define a group header for organizing help text.

ARGPARSE_GROUP(help_text)

Example:

ARGPARSE_GROUP("File Options")

ARGPARSE_OPT_END_ENTRY

Sentinel to mark the end of the options array.

const argparse_option options[] = {
    ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Verbose output"),
    ARGPARSE_OPT_END_ENTRY
};

Usage Examples

Flags

int verbose = 0;
int debug = 0;

const argparse_option options[] = {
    ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Enable verbose output"),
    ARGPARSE_BOOLEAN("d", "debug", &debug, "Enable debug mode"),
    ARGPARSE_OPT_END_ENTRY
};

Usage:

./program -v -d
./program --verbose --debug
./program -vd              # Combined short flags

Options with Values

const char *output = NULL;
int threads = 4;           // Default value
float rate = 1.0f;

const argparse_option options[] = {
    ARGPARSE_STRING("o", "output", &output, "Output file"),
    ARGPARSE_INTEGER("j", "threads", &threads, "Number of threads"),
    {ARGPARSE_OPT_FLOAT, "r", "rate", &rate, "Processing rate", ARGPARSE_OPT_NONE, NULL},
    ARGPARSE_OPT_END_ENTRY
};

Usage:

./program -o output.txt -j 8 -r 2.5
./program --output=output.txt --threads=8 --rate=2.5
./program -ooutput.txt -j8         # Immediate value for short options

Positional Arguments

argparse parser;
argparse_init(&parser, options, NULL, NULL);

int result = argparse_parse(&parser, argc, argv);

if (result > 0) {
    printf("Positional arguments:\n");
    for (int i = 0; i < result; i++) {
        printf("  %s\n", parser.positional_args[i]);
    }
}

Usage:

./program file1.txt file2.txt file3.txt
./program -v --output=out.txt input1.txt input2.txt

Default Values

int count = 10;           // Will be used if not specified
const char *format = "json";

int default_count = 10;
const char *default_format = "json";

const argparse_option options[] = {
    {ARGPARSE_OPT_INTEGER, "n", "count", &count, "Count", ARGPARSE_OPT_NONE, &default_count},
    {ARGPARSE_OPT_STRING, "f", "format", &format, "Format", ARGPARSE_OPT_NONE, &default_format},
    ARGPARSE_OPT_END_ENTRY
};

Grouped Options (Help Organization)

const argparse_option options[] = {
    ARGPARSE_GROUP("General Options"),
    ARGPARSE_BOOLEAN("v", "verbose", &verbose, "Verbose output"),
    ARGPARSE_BOOLEAN("q", "quiet", &quiet, "Quiet mode"),
    
    ARGPARSE_GROUP("File Options"),
    ARGPARSE_STRING("i", "input", &input, "Input file"),
    ARGPARSE_STRING("o", "output", &output, "Output file"),
    
    ARGPARSE_OPT_END_ENTRY
};

Error Handling

argparse parser;
argparse_init(&parser, options, "My program", NULL);

int result = argparse_parse(&parser, argc, argv);

if (result < 0) {
    if (parser.error) {
        argparse_error(&parser);  // Prints error to stderr
    }
    argparse_cleanup(&parser);
    return 1;
}

// Use parsed values...

argparse_cleanup(&parser);

Examples

The repository includes two complete example programs:

Basic Example (examples/basic.c)

Demonstrates all core features:

  • Boolean flags
  • String, integer, and float options
  • Positional arguments
  • Help generation

Build and run:

make examples
./build/basic --help
./build/basic -v -d -o output.txt -i input.txt -n 20 file1.txt file2.txt

Advanced Example (examples/advanced.c)

Shows more complex usage:

  • Grouped options
  • Default values
  • Input validation
  • File processing simulation

Build and run:

make examples
./build/advanced --help
./build/advanced -v --format=xml -j 8 input1.txt input2.txt

Testing

The library includes a comprehensive test suite:

make test

Tests cover:

  • Flag parsing (short and long)
  • Combined short flags
  • String, integer, and float options
  • Positional arguments
  • Mixed options and positional args
  • Error handling
  • Default values
  • Edge cases

Platform Support

This library is designed to be portable and works on:

  • Linux - Tested with GCC
  • macOS - Compatible with Clang
  • Windows - Works with MinGW/MSYS2

The library uses only standard C99 features and has no external dependencies.

Design Philosophy

  • Simplicity - Minimal API surface, easy to learn
  • Portability - Standard C99, works everywhere
  • Zero dependencies - No external libraries required
  • Type safety - Type-safe option definitions
  • Memory safety - Proper cleanup and error handling
  • User-friendly - Clear error messages and automatic help

Building and Installation

Prerequisites

  • C compiler supporting C99 (GCC, Clang, MSVC, MinGW)
  • Make (optional, for using the Makefile)

Building

# Build everything
make all

# Build only examples
make examples

# Build only tests
make tests

# Clean build artifacts
make clean

Manual Building

You can also build manually without Make:

# Compile the library
gcc -c -std=c99 -I./include src/argparse.c -o argparse.o

# Compile your program
gcc -std=c99 -I./include your_program.c argparse.o -o your_program

Integration

To use in your project:

  1. Copy include/argparse.h and src/argparse.c to your project
  2. Include argparse.h in your source files
  3. Compile argparse.c with your project

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

Author

Max Base - GitHub

Links

About

A lightweight, portable CLI argument parsing library for C programs. A reusable and lightweight CLI argument parsing library for C programs. C (C99/C11), portable ANSI C, no external dependencies.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published