Skip to content

Validation

cargs offers robust validation capabilities to ensure that command-line inputs meet your application's requirements.

Overview

Validation in cargs is organized into several categories:

  • Built-in Validators - Simple validation with RANGE and CHOICES
  • Regular Expression Validation - String pattern validation with PCRE2
  • Custom Validators - Create your own validation logic

This guide covers the basics of each approach. For advanced usage, see the specialized guides linked throughout.

Built-in Validators

cargs provides several built-in validators to simplify common validation scenarios. These can be applied directly to option definitions.

Range Validation

The RANGE validator ensures numeric values fall within a specified range:

OPTION_INT('p', "port", HELP("Port number"),
           RANGE(1, 65535),  // Must be between 1 and 65535
           DEFAULT(8080))

Length Validation

The LENGTH validator ensures string values have an appropriate length:

OPTION_STRING('u', "username", HELP("Username"),
              LENGTH(3, 20),  // Must be between 3 and 20 characters
              DEFAULT("user"))

Count Validation

The COUNT validator ensures collections (arrays and maps) have an appropriate number of elements:

OPTION_ARRAY_STRING('t', "tags", HELP("Tags for the resource"),
                   COUNT(1, 5),  // Must have between 1 and 5 tags
                   FLAGS(FLAG_UNIQUE))

Choices Validation

The CHOICES validator ensures the value is one of a specific set:

OPTION_STRING('l', "level", HELP("Log level"),
              CHOICES_STRING("debug", "info", "warning", "error"),
              DEFAULT("info"))
OPTION_INT('m', "mode", HELP("Operating mode"),
           CHOICES_INT(1, 2, 3),
           DEFAULT(1))
OPTION_FLOAT('s', "scale", HELP("Scale factor"),
            CHOICES_FLOAT(0.5, 1.0, 2.0),
            DEFAULT(1.0))

Regular Expression Validation

cargs uses PCRE2 for powerful regular expression validation:

OPTION_STRING('e', "email", HELP("Email address"),
              REGEX(CARGS_RE_EMAIL))  // Must be a valid email
OPTION_STRING('i', "id", HELP("Product ID"),
              REGEX(MAKE_REGEX("^[A-Z]{2}\\d{4}$", "Format: XX0000")))

Predefined Patterns

cargs includes many predefined patterns in cargs/regex.h:

Constant Validates Example
CARGS_RE_EMAIL Email addresses user@example.com
CARGS_RE_IPV4 IPv4 addresses 192.168.1.1
CARGS_RE_URL URLs https://example.com
CARGS_RE_ISO_DATE ISO format dates 2023-01-31

For a complete list, see the Regular Expressions API reference.

For advanced regex usage, see the Regular Expressions guide.

Custom Validators

For more complex validation logic, you can create your own validators:

int even_validator(cargs_t *cargs, cargs_option_t *option, validator_data_t data)
{
    if (option->value.as_int % 2 != 0) {
        CARGS_REPORT_ERROR(cargs, CARGS_ERROR_INVALID_VALUE,
                         "Value must be an even number");
    }
    return CARGS_SUCCESS;
}

// Usage
OPTION_INT('n', "number", HELP("An even number"), 
          VALIDATOR(even_validator, NULL))
int length_pre_validator(cargs_t *cargs, const char *value, validator_data_t data)
{
    size_t min_length = *(size_t *)data.custom;

    if (strlen(value) < min_length) {
        CARGS_REPORT_ERROR(cargs, CARGS_ERROR_INVALID_VALUE,
                          "String must be at least %zu characters long", min_length);
    }
    return CARGS_SUCCESS;
}

// Usage
size_t min_length = 8;
OPTION_STRING('p', "password", HELP("Password"),
             PRE_VALIDATOR(length_pre_validator, &min_length))

Validator Types

cargs supports two types of custom validators:

  1. Validators - Validate the processed value after conversion to its final type
  2. Pre-Validators - Validate the raw string before any processing

For a detailed exploration of custom validators, including examples and best practices, see the Custom Validators guide.

Combining Validators

You can apply multiple validators to a single option for more comprehensive validation:

OPTION_INT('p', "port", HELP("Port number"), 
          RANGE(1, 65535),                   // Range validator
          VALIDATOR(even_validator, NULL),   // Custom validator
          DEFAULT(8080))

Error Reporting

Validators should use CARGS_REPORT_ERROR to provide clear error messages:

CARGS_REPORT_ERROR(cargs, error_code, format_string, ...);

Error Message Example

my_program: Value '70000' is outside the range [1, 65535] for option 'port'

Common error codes include: - CARGS_ERROR_INVALID_VALUE: Value doesn't meet requirements - CARGS_ERROR_INVALID_RANGE: Value outside allowed range - CARGS_ERROR_INVALID_FORMAT: Value has incorrect format

Complete Examples

For complete working examples of validation techniques:

Example Files

  • examples/validators.c - Demonstrates all validation techniques
  • examples/regex.c - Focused on regular expression validation

Additional Resources

For more in-depth coverage of validation topics, refer to these advanced guides: