Skip to content

Proposal: Change matching functions to return bool and combine Pattern_Status Pattern_Error #1

@Salvakiya

Description

@Salvakiya

Motivation

The current API has the caller write:

Pattern_State ps;
Pattern_Status status = pattern_match_cstr(&ps, subject, pattern);
if (status == PATTERN_MATCH) {
    // use captures
} else if (status == PATTERN_ERROR) {
    pattern_print_error(stderr, &ps);
} else {
    // no match
}

This is verbose, error-prone, and mixes two very different concepts in the return value:

“Did the pattern match the subject?” → boolean question
“Was there a syntax error in the pattern?” → rare exceptional case

Almost every real-world use of a matcher only cares about the boolean outcome. The error case is important but secondary.

Proposed API Change:

Change all matching functions to return boolean.

bool pattern_match(Pattern_State* ps, const void* data, size_t len, const char* pattern);
bool pattern_match_ex(Pattern_State* ps, const void* data, size_t len, const char* pattern, ptrdiff_t start);
bool pattern_match_cstr(Pattern_State* ps, const char* str, const char* pattern);
bool pattern_match_cstr_ex(Pattern_State* ps, const char* str, const char* pattern, ptrdiff_t start);

Combine Pattern_Status and Pattern_Error enum.

typedef enum {
    PATTERN_NO_MATCH = 0,          // normal "did not match" (most common failure)
    PATTERN_MATCH,                 // success

    // All detailed errors (replacing both PATTERN_ERROR and the old Pattern_Error)
    PATTERN_ERR_MAX_CAPTURES,
    PATTERN_ERR_UNEXPECTED_CAPTURE_CLOSE,
    PATTERN_ERR_UNCLOSED_CAPTURE,
    PATTERN_ERR_INVALID_CAPTURE_IDX,
    PATTERN_ERR_INCOMPLETE_ESCAPE,
    PATTERN_ERR_UNCLOSED_CLASS,
    PATTERN_ERR_INVALID_BALANCED_PATTERN,
    PATTERN_ERR_UNCLOSED_FRONTIER_PATTERN,
    // ... any future errors added here
} Pattern_Status;

typedef struct {
    Pattern_Status status; // no longer error, now called status.
    size_t error_loc;
    Pattern_Substring data;
    const char* pattern_base;
    int capture_count;
    Pattern_Substring captures[PATTERN_MAX_CAPTURES];
} Pattern_State;

The new usage becomes

Pattern_State ps = {0};
if (pattern_match_cstr(&ps, subject, pattern)) {
    // success – use captures
} else if (ps.status == PATTERN_ERROR) {
    pattern_print_error(stderr, &ps);  // real error
}

Benefits

  • Common case becomes clean and natural (if (pattern_match(...)))
  • Clear separation between “no match” and actual errors
  • API simplification (one less enum type)
  • Matches conventions used in Lua, SQLite, and many other C libraries
  • Zero performance or size impact

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions