burkey.co
index parse
~/docs/libflint/parse.md

Parse

Parse integers and consume tokens from borrowed LfStr views without temporary NUL-terminated copies. Include lfparse.h. Complements string and input. The caller owns the views and underlying text; this module never allocates or modifies the text. Successful operations advance the input view, leaving the remaining input available to the caller.

Usage

Create a view over the input, skip any leading whitespace, and parse a number. The view advances only when parsing succeeds.

LfStr input = lfstr_from("  -42,tail");
lf_parse_skip_whitespace(&input);
int64_t value;
if (lf_parse_i64(&input, 10, &value) == LF_PARSE_OK) {
    /* value == -42; input is now ",tail" */
    lf_parse_consume(&input, lfstr_from(","));
}

Types

LfParseStatus

typedef enum {
    LF_PARSE_OK = 0,
    LF_PARSE_INVALID = -1,
    LF_PARSE_OVERFLOW = -2
} LfParseStatus;

LfStr is defined in lfstring.h. An LfStr may have a NULL data pointer only when its length is zero. The LfStr *input handle itself must be non-NULL. Failed status-returning operations leave input and output unchanged. Outputs must not alias input handles or underlying text. Token views borrow the original storage, which must remain alive while they are used.

Functions

lf_parse_u64 / lf_parse_i64

Parse the longest initial digit sequence in an explicit base from 2 through 36. Digits are ASCII 09, az, or AZ. Both accept an optional +; signed parsing also accepts -. Unsigned parsing rejects any minus sign, including -0. At least one valid digit is required after a sign. No whitespace is skipped.

Return LF_PARSE_OK on success, LF_PARSE_INVALID for invalid arguments or no initial digits, and LF_PARSE_OVERFLOW when the numeric prefix exceeds the target range. Signed endpoints are INT64_MIN and INT64_MAX; unsigned values extend through UINT64_MAX. Overflow consumes nothing, including any sign.

A non-digit or digit outside the selected base ends a successful prefix. There is no automatic base detection or prefix recognition: parsing 0xff in base 16 produces zero and leaves xff. Consume 0x explicitly first if needed. Require an empty remaining view (or a known delimiter) when a complete number is needed. Embedded NUL is an ordinary non-digit, not an end-of-view marker.

LfParseStatus lf_parse_u64(LfStr *input, unsigned base, uint64_t *value);
LfParseStatus lf_parse_i64(LfStr *input, unsigned base, int64_t *value);

lf_parse_consume

Consume an exact byte prefix. Return LF_PARSE_OK for a match, LF_PARSE_INVALID for a mismatch or invalid arguments. An empty delimiter always matches a valid input and consumes nothing. Multi-byte and embedded-NUL delimiters are supported.

LfParseStatus lf_parse_consume(LfStr *input, LfStr delimiter);

lf_parse_skip_whitespace

Consume ASCII space, tab, newline, carriage return, form feed, and vertical tab. Return the number of bytes consumed. Invalid/NULL input returns zero. Independent of locale; high-bit bytes and embedded NUL are not whitespace.

size_t lf_parse_skip_whitespace(LfStr *input);

lf_parse_token

Extract a nonempty token ending at any byte from the delimiter view or the end of input. Leave the delimiter unconsumed. Leading delimiters and empty input return LF_PARSE_INVALID; they are not skipped. An empty delimiter set takes all remaining input. Return LF_PARSE_OK on success; token and input must be distinct, non-NULL pointers. Delimiters are bytes, not Unicode characters.

LfParseStatus lf_parse_token(LfStr *input, LfStr delimiters, LfStr *token);

/* Usage */
LfStr input = lfstr_from("name=value");
LfStr key;
if (lf_parse_token(&input, lfstr_from("="), &key) == LF_PARSE_OK) {
    /* key is "name", input is "=value" */
    lf_parse_consume(&input, lfstr_from("="));
}