AxlStr – String Utilities

String utilities operating on UTF-8 char * strings. Includes length, copy, compare, search, split, join, and case-insensitive operations (ASCII fold only). UCS-2 helpers at the bottom are for UEFI internal use.

All allocated results are freed with axl_free().

Header: <axl/axl-str.h>

Overview

AXL uses UTF-8 (char *) throughout its public API. UEFI firmware uses UCS-2 (unsigned short *) internally, but AXL handles the conversion transparently – you never need to deal with UCS-2 unless making direct UEFI protocol calls.

UTF-8 vs UCS-2

  • Use UTF-8 (char *) for all application code. All axl_str* functions operate on UTF-8.

  • UCS-2 functions (axl_wcslen, axl_wcscmp, axl_str_to_w, axl_str_from_w) exist only for UEFI interop. Consumer code should not need them.

Case-Insensitive Operations

axl_strcasecmp, axl_strcasestr, and axl_strncasecmp fold ASCII letters only (A-Z → a-z). They do not handle full Unicode case mapping. This is sufficient for UEFI identifiers, HTTP headers, and file extensions.

Common Patterns

#include <axl.h>

// Split a string
char **parts = axl_strsplit("a,b,c", ',');
for (int i = 0; parts[i] != NULL; i++) {
    axl_printf("  %s\n", parts[i]);
}
axl_strfreev(parts);  // frees the array AND each string

// Join strings
const char *items[] = {"one", "two", "three", NULL};
char *joined = axl_strjoin(", ", items);
axl_printf("%s\n", joined);  // "one, two, three"
axl_free(joined);

// Search
if (axl_str_has_prefix(path, "fs0:")) { ... }
if (axl_str_has_suffix(name, ".efi")) { ... }
const char *found = axl_strcasestr(header, "content-type");

Memory Ownership

Functions that return char * allocate new memory. The caller must free with axl_free():

  • axl_strdup, axl_strndup

  • axl_strsplit (free with axl_strfreev)

  • axl_strjoin, axl_strstrip

  • axl_str_to_w, axl_str_from_w

Functions that return const char * or char * pointing into the input string do NOT allocate:

  • axl_strstr_len, axl_strrstr (return pointer into haystack)

  • axl_strchr (return pointer into string)

API Reference

Functions

size_t axl_strlen(const char *s)

Get string length. NULL returns 0.

Parameters:
  • s – NUL-terminated string, or NULL

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

Compare two strings.

Parameters:
  • a – first string

  • b – second string

Returns:

<0, 0, or >0.

static inline bool axl_streql(const char *a, const char *b)

Test if two strings are equal. NULL-safe.

Shorthand for axl_strcmp(a, b) == 0.

Returns:

true if equal.

int axl_strncmp(const char *a, const char *b, size_t n)

Compare at most

bytes of two strings.

Parameters:
  • a – first string

  • b – second string

  • n – max bytes to compare

Returns:

<0, 0, or >0.

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

Case-insensitive string comparison (ASCII case folding only).

Parameters:
  • a – first string

  • b – second string

Returns:

<0, 0, or >0.

void *axl_memcpy(void *dst, const void *src, size_t n)

Copy

bytes from @src to @dst.

Regions must not overlap. NULL-safe: returns @dst if either is NULL.

Parameters:
  • dst – destination

  • src – source

  • n – byte count

Returns:

@dst.

void *axl_memset(void *dst, int c, size_t n)

Fill

bytes of @dst with

.

Parameters:
  • dst – destination

  • c – fill byte

  • n – byte count

Returns:

@dst.

void *axl_memmove(void *dst, const void *src, size_t n)

Copy n bytes, handling overlapping regions. Like memmove().

Parameters:
  • dst – destination

  • src – source

  • n – byte count

Returns:

dst.

int axl_memcmp(const void *a, const void *b, size_t n)

Compare n bytes of memory. Like memcmp().

Parameters:
  • a – first buffer

  • b – second buffer

  • n – byte count

Returns:

<0, 0, or >0.

int axl_snprintf(char *buf, size_t size, const char *fmt, ...)

Format into a fixed buffer. Like snprintf().

Uses AXL’s own printf engine (standard C format specifiers). Always NUL-terminates if size > 0.

Parameters:
  • buf – output buffer

  • size – buffer size

  • fmt – printf-style format string

Returns:

number of bytes that would have been written (excluding NUL), regardless of buffer size (allows truncation detection).

size_t axl_strlcpy(char *dst, const char *src, size_t dst_size)

Copy @src into @dst, guaranteeing NUL-termination.

At most dst_size-1 characters are copied. Like BSD strlcpy / g_strlcpy.

Parameters:
  • dst – destination buffer

  • src – source string

  • dst_size – total size of @dst (including NUL)

Returns:

length of @src (allows truncation detection: if return >= dst_size, output was truncated).

size_t axl_strlcat(char *dst, const char *src, size_t dst_size)

Append @src to @dst, guaranteeing NUL-termination.

Like BSD strlcat / g_strlcat.

Parameters:
  • dst – destination buffer (must be NUL-terminated)

  • src – string to append

  • dst_size – total size of @dst (including NUL)

Returns:

attempted total length (dst_len + src_len). If return >= dst_size, output was truncated.

char *axl_strndup(const char *s, size_t n)

Duplicate at most

bytes of @s into a new NUL-terminated string.

Caller frees with axl_free(). NULL-safe: returns NULL if @s is NULL.

Parameters:
  • s – source string

  • n – maximum bytes to copy

Returns:

new string, or NULL on failure.

char **axl_strsplit(const char *str, char delimiter)

Split a string by a delimiter character.

Returns a NULL-terminated array of newly allocated strings. Free the result with axl_strfreev().

Parameters:
  • str – string to split

  • delimiter – delimiter character

Returns:

array of strings, or NULL on failure.

void axl_strfreev(char **arr)

Free a NULL-terminated string array from axl_strsplit.

Parameters:
  • arr – array to free (NULL-safe)

char *axl_strjoin(const char *separator, const char **arr)

Join a NULL-terminated string array with a separator.

Caller frees the result with axl_free().

Parameters:
  • separator – separator between elements

  • arr – NULL-terminated array of strings

Returns:

new string, or NULL on failure.

char *axl_strstrip(char *str)

Trim leading and trailing ASCII whitespace in place.

Modifies the string by shifting content and NUL-terminating. Returns the input pointer for convenience.

Parameters:
  • str – string to trim (modified in place)

Returns:

@str (same pointer).

char *axl_strchr(const char *s, int c)

Find first occurrence of character c in s.

Like strchr(). Returns pointer to matching character, or NULL.

Parameters:
  • s – string to search

  • c – character to find

Returns:

pointer to first c in s, or NULL if not found.

char *axl_strstr(const char *haystack, const char *needle)

Find first occurrence of needle in haystack.

Like strstr(). Searches the entire NUL-terminated string.

Parameters:
  • haystack – string to search

  • needle – substring to find

Returns:

pointer to match, or NULL if not found.

char *axl_strncpy(char *dst, const char *src, size_t n)

Copy src to dst, NUL-padding to n bytes.

Like strncpy(). If src is shorter than n, the remainder is filled with NUL bytes. Does NOT guarantee NUL-termination if src is longer than n. Prefer axl_strlcpy() for safe copying with guaranteed NUL-termination.

Parameters:
  • dst – destination buffer

  • src – source string

  • n – max bytes to write

Returns:

dst.

char *axl_strstr_len(const char *haystack, long long haystack_len, const char *needle)

Find first occurrence of needle in haystack.

Searches at most haystack_len bytes. Pass -1 to search the entire NUL-terminated string.

Parameters:
  • haystack – string to search

  • haystack_len – max bytes to search (-1 for all)

  • needle – substring to find

Returns:

pointer to match, or NULL if not found.

char *axl_strrstr(const char *haystack, const char *needle)

Find last occurrence of needle in haystack.

Parameters:
  • haystack – string to search

  • needle – substring to find

Returns:

pointer to match, or NULL if not found.

char *axl_strrstr_len(const char *haystack, long long haystack_len, const char *needle)

Find last occurrence of needle in first haystack_len bytes.

Parameters:
  • haystack – string to search

  • haystack_len – max bytes to search (-1 for all)

  • needle – substring to find

Returns:

pointer to match, or NULL if not found.

char *axl_strcasestr(const char *haystack, const char *needle)

Case-insensitive substring search (ASCII case folding only).

Finds the first occurrence of needle in haystack, ignoring ASCII letter case. NULL-safe: returns NULL if either argument is NULL.

Parameters:
  • haystack – string to search

  • needle – substring to find (case-insensitive)

Returns:

pointer to match, or NULL if not found.

bool axl_fnmatch(const char *pattern, const char *string)

Glob-style pattern matching.

Matches string against pattern using shell glob rules: * matches zero or more characters, ? matches exactly one, [abc] matches a character class, [a-z] matches a range. Matching is case-sensitive. NULL-safe: returns false if either argument is NULL.

Parameters:
  • pattern – glob pattern

  • string – string to match against

Returns:

true if string matches pattern.

bool axl_str_has_prefix(const char *str, const char *prefix)

Test if str starts with prefix.

Parameters:
  • str – string to test

  • prefix – prefix to check for

Returns:

true if str begins with prefix.

bool axl_str_has_suffix(const char *str, const char *suffix)

Test if str ends with suffix.

Parameters:
  • str – string to test

  • suffix – suffix to check for

Returns:

true if str ends with suffix.

bool axl_str_is_ascii(const char *str)

Test if string is pure ASCII (all bytes 0x00-0x7F).

Parameters:
  • str – string to test

Returns:

true if all bytes are ASCII.

int axl_strcmp0(const char *str1, const char *str2)

NULL-safe string comparison.

Two NULLs are equal. NULL sorts before non-NULL.

Parameters:
  • str1 – first string (may be NULL)

  • str2 – second string (may be NULL)

Returns:

negative, zero, or positive (like strcmp).

bool axl_str_equal(const void *v1, const void *v2)

Byte-by-byte string equality test.

Parameters are void* so this can be used directly as a hash table equality function. Both strings must be non-NULL.

Parameters:
  • v1 – first string (cast to const char *)

  • v2 – second string (cast to const char *)

Returns:

true if strings are equal.

int axl_strncasecmp(const char *s1, const char *s2, size_t n)

Case-insensitive comparison, length-bounded (ASCII only).

Compares at most n bytes. ASCII letters only (A-Z, a-z).

Parameters:
  • s1 – first string

  • s2 – second string

  • n – max bytes to compare

Returns:

negative, zero, or positive (like strncmp).

bool axl_strv_contains(const char *const *strv, const char *str)

Check if a NULL-terminated string array contains str.

Parameters:
  • strv – NULL-terminated string array

  • str – string to search for

Returns:

true if str is found in strv.

bool axl_strv_equal(const char *const *strv1, const char *const *strv2)

Check if two NULL-terminated string arrays are identical.

Both arrays must be non-NULL. Compares element-by-element.

Parameters:
  • strv1 – first array

  • strv2 – second array

Returns:

true if arrays have the same elements in the same order.

unsigned short *axl_utf8_to_ucs2(const char *s)

Convert a UTF-8 string to UCS-2.

Handles BMP characters (U+0000..U+FFFF). Caller frees with axl_free(). The returned type (unsigned short *) matches UEFI’s CHAR16.

Parameters:
  • s – UTF-8 string, or NULL

Returns:

newly allocated UCS-2 string, or NULL if @s is NULL or allocation fails.

char *axl_ucs2_to_utf8(const unsigned short *s)

Convert a UCS-2 string to UTF-8.

Caller frees with axl_free().

Parameters:
  • s – UCS-2 (unsigned short *) string, or NULL

Returns:

newly allocated UTF-8 string, or NULL if @s is NULL or allocation fails.

char *axl_base64_encode(const void *data, size_t len)

Base64-encode binary data.

Caller frees with axl_free().

Parameters:
  • data – input bytes

  • len – input length

Returns:

NUL-terminated base64 string, or NULL on failure.

int axl_base64_decode(const char *b64, void **out, size_t *out_len)

Decode a base64 string.

Parameters:
  • b64 – base64 string

  • out – (out): pointer to decoded data (caller frees with axl_free)

  • out_len – (out): decoded data length

Returns:

0 on success, -1 on invalid input.

uint64_t axl_strtou64(const char *s)

Parse an unsigned 64-bit integer.

Handles “0x” prefix for hex. Returns 0 on NULL or invalid input.

Parameters:
  • s – number string (decimal or “0x” hex)

size_t axl_wcslen(const unsigned short *s)

Get UCS-2 string length. NULL returns 0.

Parameters:
  • s – UCS-2 string, or NULL

Returns:

number of characters (not including NUL).

int axl_wcscmp(const unsigned short *a, const unsigned short *b)

Compare two UCS-2 strings.

NULL-safe: NULL sorts before non-NULL. Two NULLs are equal.

Parameters:
  • a – first string

  • b – second string

Returns:

<0, 0, or >0.

static inline bool axl_wcseql(const unsigned short *a, const unsigned short *b)

Test if two UCS-2 strings are equal. NULL-safe.

Shorthand for axl_wcscmp(a, b) == 0.

Returns:

true if equal.

void axl_wcscpy(unsigned short *dst, const unsigned short *src, size_t dst_count)

Copy UCS-2 string with size limit. Guarantees NUL-termination.

Parameters:
  • dst – destination buffer

  • src – source string

  • dst_count – destination buffer size in characters

unsigned short *axl_str_dup_w(const unsigned short *s)

Duplicate a UCS-2 string.

Caller frees with FreePool().

Parameters:
  • s – UCS-2 string, or NULL

Returns:

newly allocated copy, or NULL if @s is NULL or allocation fails.

unsigned short *axl_str_format_w(const unsigned short *fmt, ...)

Format a UCS-2 string.

Caller frees with FreePool().

Parameters:
  • fmt – UCS-2 format string (PrintLib format)

Returns:

newly allocated string, or NULL on failure.

unsigned short *axl_str_trim_w(unsigned short *s)

Trim leading and trailing whitespace in place.

Parameters:
  • s – UCS-2 string (modified in place)

Returns:

@s.

unsigned short **axl_str_split_w(const unsigned short *s, unsigned short delim)

Split on @delim.

Free with axl_str_freev_w().

Parameters:
  • s – UCS-2 string to split

  • delim – delimiter character

Returns:

NULL-terminated array, or NULL on failure.

void axl_str_freev_w(unsigned short **arr)

Free a UCS-2 string array. NULL-safe.

Parameters:
  • arr – array from axl_str_split_w()

unsigned short *axl_str_join_w(const unsigned short *sep, unsigned short **arr)

Join strings with @sep.

Caller frees with FreePool().

Parameters:
  • sep – separator string

  • arr – NULL-terminated UCS-2 string array

Returns:

newly allocated string, or NULL on failure.

int axl_str_cmp_nocase_w(const unsigned short *a, const unsigned short *b)

Case-insensitive comparison. NULL-safe.

Parameters:
  • a – first UCS-2 string

  • b – second UCS-2 string

Returns:

<0, 0, or >0.

bool axl_str_contains_w(const unsigned short *haystack, const unsigned short *needle)

Case-sensitive substring search. NULL-safe.

Parameters:
  • haystack – string to search

  • needle – substring to find

Returns:

true if @needle is found in @haystack.