Skip to content

API Reference

Pablo R. edited this page Oct 6, 2025 · 3 revisions

API Reference

Error Handling Functions

strap_error_t strap_last_error(void)

Gets the last error code set by STRAP operations.

Returns:

  • The last error code that occurred

Example:

char *result = strtrim(NULL);
if (!result) {
    strap_error_t err = strap_last_error();
    fprintf(stderr, "Error: %s\n", strap_error_string(err));
}

const char *strap_error_string(strap_error_t err)

Converts an error code to a human-readable string.

Parameters:

  • err - Error code to convert

Returns:

  • Human-readable error description

Example:

strap_error_t err = strap_last_error();
printf("Error: %s\n", strap_error_string(err));

void strap_clear_error(void)

Clears the current error state.

Example:

strap_clear_error(); // Reset error state

Safe Reading Functions

char *afgets(FILE *f)

Reads a complete line from the file stream, automatically handling memory allocation.

Parameters:

  • f - File stream to read from

Returns:

  • Malloc-allocated buffer containing the line (without newline)
  • NULL on error/EOF

Notes:

  • Caller is responsible for freeing the returned buffer
  • Backed by strap_line_buffer_read() so repeated calls avoid realloc churn
  • Cross-platform compatible (uses fgets internally)

Example:

FILE *fp = fopen("example.txt", "r");
char *line = afgets(fp);
if (line) {
    printf("Line: %s\n", line);
    free(line);
}
fclose(fp);

void strap_line_buffer_init(strap_line_buffer_t *buffer)

Initialises a reusable line buffer for streaming reads.

Parameters:

  • buffer - Pointer to buffer state to initialise (must be non-NULL)

Notes:

  • Sets the internal storage to empty without allocating memory yet.
  • Sets STRAP_ERR_INVALID_ARGUMENT if buffer is NULL.

char *strap_line_buffer_read(FILE *f, strap_line_buffer_t *buffer)

Reads the next line into an existing buffer, reusing allocations across calls.

Parameters:

  • f - File stream to read from (must be non-NULL)
  • buffer - Previously initialised line buffer (must be non-NULL)

Returns:

  • Pointer to the internal buffer containing the line (without trailing newline)
  • NULL on EOF or error; inspect strap_last_error() for details

Notes:

  • The returned pointer is owned by the buffer—do not free() it.
  • On EOF without data, returns NULL with STRAP_OK.
  • Automatically grows capacity for arbitrarily long lines.

Example:

strap_line_buffer_t buf;
strap_line_buffer_init(&buf);

FILE *fp = fopen("stream.log", "r");
while (true) {
    char *line = strap_line_buffer_read(fp, &buf);
    if (!line)
        break;
    puts(line);
}
strap_line_buffer_free(&buf);
fclose(fp);

void strap_line_buffer_free(strap_line_buffer_t *buffer)

Releases any heap storage held by a line buffer.

Parameters:

  • buffer - Buffer to free (must be non-NULL)

Notes:

  • Safe to call multiple times; leaves the buffer empty.
  • Sets STRAP_ERR_INVALID_ARGUMENT if buffer is NULL.

char *afread(FILE *f, size_t *out_len)

Reads the entire contents of a file into memory.

Parameters:

  • f - File stream to read from
  • out_len - Pointer to store the length of the read data (can be NULL)

Returns:

  • Malloc-allocated buffer containing file contents
  • NULL on error

Notes:

  • Caller is responsible for freeing the returned buffer
  • File position is preserved after operation

Example:

FILE *fp = fopen("data.txt", "r");
size_t len;
char *content = afread(fp, &len);
if (content) {
    printf("File size: %zu bytes\n", len);
    printf("Content: %s\n", content);
    free(content);
}
fclose(fp);

String Manipulation Functions

char *strjoin(const char **parts, size_t nparts, const char *sep)

Joins multiple strings with a separator.

Parameters:

  • parts - Array of strings to join
  • nparts - Number of strings in the array
  • sep - Separator string (can be NULL for no separator)

Returns:

  • Malloc-allocated buffer containing the joined string
  • NULL on memory allocation failure

Notes:

  • Uses SIMD-assisted copy paths on SSE2-capable x86 systems, falling back automatically when unavailable.

Example:

const char *words[] = {"Hello", "beautiful", "world"};
char *sentence = strjoin(words, 3, " ");
printf("%s\n", sentence); // "Hello beautiful world"
free(sentence);

char *strjoin_va(const char *sep, ...)

Variable argument version of strjoin.

Parameters:

  • sep - Separator string
  • ... - Variable number of string arguments, terminated by NULL

Returns:

  • Malloc-allocated buffer containing the joined string
  • NULL on memory allocation failure

Example:

char *path = strjoin_va("/", "usr", "local", "bin", NULL);
printf("%s\n", path); // "/usr/local/bin"
free(path);

bool strstartswith(const char *s, const char *prefix)

Checks if a string starts with a given prefix.

Parameters:

  • s - String to check
  • prefix - Prefix to look for

Returns:

  • true if string starts with prefix, false otherwise

Example:

if (strstartswith("hello.txt", "hello")) {
    printf("File has expected prefix\n");
}

bool strendswith(const char *s, const char *suffix)

Checks if a string ends with a given suffix.

Parameters:

  • s - String to check
  • suffix - Suffix to look for

Returns:

  • true if string ends with suffix, false otherwise

Example:

if (strendswith("document.txt", ".txt")) {
    printf("File is a text file\n");
}

char *strreplace(const char *s, const char *search, const char *replacement)

Replaces all occurrences of a substring with another string.

Parameters:

  • s - Original string
  • search - Substring to replace
  • replacement - Replacement string

Returns:

  • Malloc-allocated buffer containing the modified string
  • NULL on memory allocation failure

Example:

char *result = strreplace("Hello world", "world", "STRAP");
printf("%s\n", result); // "Hello STRAP"
free(result);

char *strtolower_locale(const char *s, const char *locale_name)

Converts a string to lowercase using locale-aware conversion.

Parameters:

  • s - String to convert
  • locale_name - Locale name (can be NULL for default locale)

Returns:

  • Malloc-allocated buffer containing the lowercase string
  • NULL on memory allocation failure

Example:

char *lower = strtolower_locale("HELLO", "en_US.UTF-8");
printf("%s\n", lower); // "hello"
free(lower);

char *strtoupper_locale(const char *s, const char *locale_name)

Converts a string to uppercase using locale-aware conversion.

Parameters:

  • s - String to convert
  • locale_name - Locale name (can be NULL for default locale)

Returns:

  • Malloc-allocated buffer containing the uppercase string
  • NULL on memory allocation failure

Example:

char *upper = strtoupper_locale("hello", "en_US.UTF-8");
printf("%s\n", upper); // "HELLO"
free(upper);

int strcoll_locale(const char *a, const char *b, const char *locale_name)

Compares two strings using locale-aware collation.

Parameters:

  • a, b - Strings to compare
  • locale_name - Locale name (can be NULL for default locale)

Returns:

  • Negative value if a < b, 0 if equal, positive value if a > b

Example:

int result = strcoll_locale("café", "cafe", "fr_FR.UTF-8");
if (result > 0) {
    printf("café comes after cafe in French collation\n");
}

int strcasecmp_locale(const char *a, const char *b, const char *locale_name)

Case-insensitive string comparison using locale-aware collation.

Parameters:

  • a, b - Strings to compare
  • locale_name - Locale name (can be NULL for default locale)

Returns:

  • Negative value if a < b, 0 if equal, positive value if a > b

Example:

int result = strcasecmp_locale("Hello", "HELLO", "en_US.UTF-8");
if (result == 0) {
    printf("Strings are equal ignoring case\n");
}

int strap_strcasecmp(const char *a, const char *b)

Performs a portable, ASCII-only case-insensitive comparison.

Parameters:

  • a, b - Strings to compare (must be non-NULL)

Returns:

  • Negative value if a < b, 0 if equal, positive value if a > b

Notes:

  • Only ASCII letters are folded; other bytes are compared verbatim.
  • Sets STRAP_ERR_INVALID_ARGUMENT if either argument is NULL.

Example:

if (strap_strcasecmp("Alpha", "alpha") == 0) {
    puts("Match!");
}

bool strcaseeq(const char *a, const char *b)

Checks two strings for equality ignoring ASCII case.

Parameters:

  • a, b - Strings to compare (must be non-NULL)

Returns:

  • true if equal ignoring case, false otherwise

Example:

if (strcaseeq("STRAP", "strap")) {
    puts("Same string");
}

char **strsplit_limit(const char *s, const char *delim, size_t max_splits, size_t *out_count)

Splits a string by a substring delimiter, with an optional cap on the number of splits.

Parameters:

  • s - Source string (must be non-NULL)
  • delim - Delimiter substring (must be non-empty)
  • max_splits - Maximum number of splits (0 for unlimited)
  • out_count - Optional pointer that receives the number of tokens

Returns:

  • NULL-terminated array of malloc-allocated tokens; free with strsplit_free
  • NULL on invalid arguments or allocation failure

Notes:

  • Consecutive delimiters yield empty tokens (similar to strsep)
  • When max_splits is reached, the final element contains the unsplit remainder

Example:

size_t count = 0;
char **parts = strsplit_limit("alpha,beta,gamma", ",", 1, &count);
// parts[0] -> "alpha", parts[1] -> "beta,gamma"
strsplit_free(parts);

char **strsplit_predicate(const char *s, strap_split_predicate_fn predicate, void *userdata, size_t max_splits, size_t *out_count)

Splits a string whenever predicate returns true for a character, coalescing consecutive matches.

Parameters:

  • s - Source string (must be non-NULL)
  • predicate - Callback of type bool (*)(unsigned char ch, void *userdata)
  • userdata - Opaque pointer passed to each predicate invocation
  • max_splits - Maximum number of splits (0 for unlimited)
  • out_count - Optional pointer that receives the number of tokens

Returns:

  • NULL-terminated array of malloc-allocated tokens; free with strsplit_free
  • NULL on invalid arguments or allocation failure

Example:

bool is_space(unsigned char ch, void *unused) {
    (void)unused;
    return ch == ' ' || ch == '\t';
}

size_t count = 0;
char **words = strsplit_predicate(" one\t two three ", is_space, NULL, 0, &count);
// Produces ["one", "two", "three"]
strsplit_free(words);

void strsplit_free(char **tokens)

Releases the array returned by strsplit_limit/strsplit_predicate.

Parameters:

  • tokens - NULL-terminated array to free (can be NULL)

Example:

char **parts = strsplit_limit("a,b", ",", 0, NULL);
/* ... use parts ... */
strsplit_free(parts);

char *strtrim(const char *s)

Trims whitespace from both ends of a string.

Parameters:

  • s - Input string

Returns:

  • Malloc-allocated buffer containing the trimmed string
  • NULL if input is NULL or memory allocation fails

Notes:

  • Trims spaces, tabs, newlines, and carriage returns
  • Original string is not modified
  • Uses SIMD acceleration on SSE2-capable x86 systems with automatic fallback for other environments

Example:

char *trimmed = strtrim("  Hello World  \n");
printf("'%s'\n", trimmed); // "Hello World"
free(trimmed);

void strtrim_inplace(char *s)

Trims whitespace from both ends of a string in-place.

Parameters:

  • s - String to modify (must be mutable)

Notes:

  • Modifies the input string directly
  • No memory allocation/deallocation
  • Safe to call with NULL (no-op)

Example:

char buffer[] = "  Hello World  \n";
strtrim_inplace(buffer);
printf("'%s'\n", buffer); // "Hello World"

Arena Allocator Functions

strap_arena_t *strap_arena_create(size_t block_size)

Creates a new arena allocator.

Parameters:

  • block_size - Initial block size for allocations

Returns:

  • Pointer to new arena allocator
  • NULL on memory allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
if (!arena) {
    fprintf(stderr, "Failed to create arena\n");
    return 1;
}
// Use arena...
strap_arena_destroy(arena);

void strap_arena_destroy(strap_arena_t *arena)

Destroys an arena allocator and frees all memory.

Parameters:

  • arena - Arena to destroy

Example:

strap_arena_t *arena = strap_arena_create(1024);
// ... use arena
strap_arena_destroy(arena);

void strap_arena_clear(strap_arena_t *arena)

Clears an arena allocator, freeing all allocated memory but keeping the arena itself.

Parameters:

  • arena - Arena to clear

Example:

strap_arena_t *arena = strap_arena_create(1024);
// ... allocate some memory
strap_arena_clear(arena); // Free all allocations, keep arena

void *strap_arena_alloc(strap_arena_t *arena, size_t size)

Allocates memory from an arena.

Parameters:

  • arena - Arena to allocate from
  • size - Size of allocation in bytes

Returns:

  • Pointer to allocated memory
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
int *numbers = strap_arena_alloc(arena, sizeof(int) * 10);
// Use numbers...
strap_arena_destroy(arena);

char *strap_arena_strdup(strap_arena_t *arena, const char *s)

Duplicates a string using arena allocation.

Parameters:

  • arena - Arena to allocate from
  • s - String to duplicate

Returns:

  • Arena-allocated duplicate of the string
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
char *copy = strap_arena_strdup(arena, "Hello World");
printf("%s\n", copy);
strap_arena_destroy(arena);

char *strap_arena_strndup(strap_arena_t *arena, const char *s, size_t n)

Duplicates up to n characters of a string using arena allocation.

Parameters:

  • arena - Arena to allocate from
  • s - String to duplicate
  • n - Maximum number of characters to copy

Returns:

  • Arena-allocated duplicate of the string
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
char *copy = strap_arena_strndup(arena, "Hello World", 5);
printf("%s\n", copy); // "Hello"
strap_arena_destroy(arena);

char *strjoin_arena(strap_arena_t *arena, const char **parts, size_t nparts, const char *sep)

Joins multiple strings with a separator using arena allocation.

Parameters:

  • arena - Arena to allocate from
  • parts - Array of strings to join
  • nparts - Number of strings in the array
  • sep - Separator string

Returns:

  • Arena-allocated buffer containing the joined string
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
const char *words[] = {"Hello", "world"};
char *result = strjoin_arena(arena, words, 2, " ");
printf("%s\n", result); // "Hello world"
strap_arena_destroy(arena);

char *strreplace_arena(strap_arena_t *arena, const char *s, const char *search, const char *replacement)

Replaces all occurrences of a substring using arena allocation.

Parameters:

  • arena - Arena to allocate from
  • s - Original string
  • search - Substring to replace
  • replacement - Replacement string

Returns:

  • Arena-allocated buffer containing the modified string
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
char *result = strreplace_arena(arena, "Hello world", "world", "STRAP");
printf("%s\n", result); // "Hello STRAP"
strap_arena_destroy(arena);

char *strtolower_locale_arena(strap_arena_t *arena, const char *s, const char *locale_name)

Converts a string to lowercase using arena allocation and locale-aware conversion.

Parameters:

  • arena - Arena to allocate from
  • s - String to convert
  • locale_name - Locale name

Returns:

  • Arena-allocated buffer containing the lowercase string
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
char *lower = strtolower_locale_arena(arena, "HELLO", "en_US.UTF-8");
printf("%s\n", lower); // "hello"
strap_arena_destroy(arena);

char *strtoupper_locale_arena(strap_arena_t *arena, const char *s, const char *locale_name)

Converts a string to uppercase using arena allocation and locale-aware conversion.

Parameters:

  • arena - Arena to allocate from
  • s - String to convert
  • locale_name - Locale name

Returns:

  • Arena-allocated buffer containing the uppercase string
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
char *upper = strtoupper_locale_arena(arena, "hello", "en_US.UTF-8");
printf("%s\n", upper); // "HELLO"
strap_arena_destroy(arena);

char *strtrim_arena(strap_arena_t *arena, const char *s)

Trims whitespace from both ends of a string using arena allocation.

Parameters:

  • arena - Arena to allocate from
  • s - Input string

Returns:

  • Arena-allocated buffer containing the trimmed string
  • NULL on allocation failure

Example:

strap_arena_t *arena = strap_arena_create(1024);
char *trimmed = strtrim_arena(arena, "  Hello World  \n");
printf("'%s'\n", trimmed); // "Hello World"
strap_arena_destroy(arena);

Time Utility Functions

struct timeval timeval_add(struct timeval a, struct timeval b)

Adds two struct timeval values.

Parameters:

  • a, b - Time values to add

Returns:

  • Result of addition with proper carry handling

Example:

struct timeval t1 = {1, 500000}; // 1.5 seconds
struct timeval t2 = {2, 600000}; // 2.6 seconds
struct timeval sum = timeval_add(t1, t2); // 4.1 seconds

struct timeval timeval_sub(struct timeval a, struct timeval b)

Subtracts two struct timeval values.

Parameters:

  • a, b - Time values (a - b)

Returns:

  • Result of subtraction with proper borrow handling

Example:

struct timeval t1 = {5, 200000}; // 5.2 seconds
struct timeval t2 = {2, 100000}; // 2.1 seconds
struct timeval diff = timeval_sub(t1, t2); // 3.1 seconds

double timeval_to_seconds(struct timeval t)

Converts a struct timeval to seconds as a double.

Parameters:

  • t - Time value to convert

Returns:

  • Time in seconds with microsecond precision

Example:

struct timeval t = {3, 500000}; // 3.5 seconds
double seconds = timeval_to_seconds(t);
printf("%.6f seconds\n", seconds); // 3.500000 seconds

struct timeval timeval_add_minutes(struct timeval t, int minutes)

Adds minutes to a struct timeval.

Parameters:

  • t - Base time value
  • minutes - Minutes to add (can be negative)

Returns:

  • Time value with minutes added

Example:

struct timeval t = {1000, 0}; // 1000 seconds
struct timeval future = timeval_add_minutes(t, 5); // 1300 seconds

int strap_time_offset_to_string(int offset_minutes, char *buf, size_t bufsize)

Converts a timezone offset in minutes to ISO 8601 string format.

Parameters:

  • offset_minutes - Offset from UTC in minutes
  • buf - Buffer to write the result to
  • bufsize - Size of the buffer

Returns:

  • 0 on success, -1 on buffer too small

Example:

char tz_str[16];
strap_time_offset_to_string(60, tz_str, sizeof(tz_str));
printf("Timezone: %s\n", tz_str); // "+01:00"

int strap_time_parse_tz_offset(const char *str, int *offset_minutes)

Parses an ISO 8601 timezone offset string.

Parameters:

  • str - Timezone offset string (e.g., "+01:00", "Z")
  • offset_minutes - Pointer to store parsed offset in minutes

Returns:

  • 0 on success, -1 on parse error

Example:

int offset;
if (strap_time_parse_tz_offset("+05:30", &offset) == 0) {
    printf("Offset: %d minutes\n", offset); // 330
}

int strap_time_format_iso8601(struct timeval t, int offset_minutes, char *buf, size_t bufsize)

Formats a struct timeval as ISO 8601 string with timezone.

Parameters:

  • t - Time value to format
  • offset_minutes - Timezone offset in minutes
  • buf - Buffer to write the result to
  • bufsize - Size of the buffer

Returns:

  • 0 on success, -1 on buffer too small

Example:

struct timeval t = {1609459200, 0}; // 2021-01-01 00:00:00 UTC
char iso_str[32];
strap_time_format_iso8601(t, 0, iso_str, sizeof(iso_str));
printf("ISO 8601: %s\n", iso_str); // "2021-01-01T00:00:00Z"

int strap_time_parse_iso8601(const char *str, struct timeval *out, int *offset_minutes)

Parses an ISO 8601 datetime string.

Parameters:

  • str - ISO 8601 string to parse
  • out - Pointer to store parsed time value
  • offset_minutes - Pointer to store timezone offset (can be NULL)

Returns:

  • 0 on success, -1 on parse error

Example:

struct timeval t;
int offset;
if (strap_time_parse_iso8601("2021-01-01T12:30:45+05:30", &t, &offset) == 0) {
    printf("Parsed time with offset %d minutes\n", offset);
}

int strap_time_local_offset(time_t when, int *offset_minutes)

Computes the local timezone offset (in minutes) for a given time_t.

Parameters:

  • when - Epoch timestamp to evaluate
  • offset_minutes - Output pointer receiving the offset in minutes

Returns:

  • 0 on success, -1 on invalid arguments or conversion failure

Notes:

  • Uses tm_gmtoff when available (BSD, macOS, musl, glibc) and falls back to portable mktime shims elsewhere.
  • Result is bounded to the ±14 hour ISO 8601 range and always minute-aligned.

Example:

time_t now = time(NULL);
int offset_minutes;
if (strap_time_local_offset(now, &offset_minutes) == 0) {
    printf("Local offset: %d minutes\n", offset_minutes);
}

int strap_time_format_iso8601_local(struct timeval t, char *buf, size_t bufsize)

Formats a timestamp using the system's current timezone offset.

Parameters:

  • t - Time value to format
  • buf - Destination buffer
  • bufsize - Size of destination buffer

Returns:

  • 0 on success, -1 on error

Example:

struct timeval now = { time(NULL), 123456 };
char iso[64];
if (strap_time_format_iso8601_local(now, iso, sizeof(iso)) == 0) {
    puts(iso);
}

Planned Additions (v0.4)

strap_perf_result_t strap_profile_strjoin(const char **parts, size_t nparts, const char *sep)

Benchmarks representative workloads to surface SIMD and allocator regressions.

  • Will integrate with make bench and emit JSON snapshots for CI diffing.
  • Pairs with new streaming tests to validate afgets buffering tweaks.
Clone this wiki locally