7 Module N_STR
gullradriel edited this page 2026-10-29 20:54:40 +01:00

STRINGS: replacement to char *strings with dynamic resizing and boundary checking

Structures

Name
struct N_STR
A box including a string and his lenght.

Types

Name
typedef size_t NSTRBYTE
N_STR base unit.

Functions

Name
int write_and_fit_ex(char ** dest, NSTRBYTE * size, NSTRBYTE * written, const char * src, NSTRBYTE src_size, NSTRBYTE additional_padding)
write and fit bytes into a dynamically sized buffer
int write_and_fit(char ** dest, NSTRBYTE * size, NSTRBYTE * written, const char * src)
write and fit into the char array
int wildmatcase(register const char * text, register const char * p)
pattern matching, case insensitive
int wildmat(register const char * text, register const char * p)
pattern matching
char * trim_nocopy(char * s)
trim and put a \0 at the end, return new begin pointer
char * trim(const char * s)
trim and put a \0 at the end, return new char *
int strup(const char * string, char * dest)
upper case a string
int strlo(const char * string, char * dest)
lower case a string
int strcpy_u(const char * from, char * to, NSTRBYTE to_size, char delim, NSTRBYTE * it)
copy from string to dest until from[iterator] == delim
int str_to_long_long_ex(const char * s, NSTRBYTE start, NSTRBYTE end, long long int * i, const int base)
string to long long integer, with error checking
int str_to_long_long(const char * s, long long int * i, const int base)
string to long long integer, shorter version
int str_to_long_ex(const char * s, NSTRBYTE start, NSTRBYTE end, long int * i, const int base)
string to long integer, with error checking
int str_to_long(const char * s, long int * i, const int base)
string to long integer, shorter version
int str_to_int_nolog(const char * s, NSTRBYTE start, NSTRBYTE end, int * i, const int base, N_STR ** infos)
string to integer, with error checking and no logging
int str_to_int_ex(const char * s, NSTRBYTE start, NSTRBYTE end, int * i, const int base)
string to integer, with error checking
int str_to_int(const char * s, int * i, const int base)
string to integer, shorter version
int str_sanitize_ex(char * string, const NSTRBYTE string_len, const char * mask, const NSTRBYTE masklen, const char replacement)
sanitize a string using a character mask
int str_sanitize(char * string, const char * mask, const char replacement)
in-place substitution of a set of chars by a single one
char * str_replace(const char * string, const char * substr, const char * replacement)
return a new string with all occurrences of substr replaced
int str_natncasecmp(const char * a, size_t alen, const char * b, size_t blen)
compare two byte runs of known length in natural order, ignoring ASCII case
int str_natcasecmp(const char * a, const char * b)
compare two strings in natural order, ignoring ASCII case
int split_count(char ** split_result)
count split elements
char ** split(const char * str, const char * delim, int empty)
return an array of char pointers to the split sections
int skipw(const char * string, char toskip, NSTRBYTE * iterator, int inc)
skip characters in string while string[iterator] == toskip
int skipu(const char * string, char toskip, NSTRBYTE * iterator, int inc)
skip characters in string until string[iterator] == toskip
int scan_dir_ex(const char * dir, const char * pattern, LIST * result, const int recurse, const int mode)
get a list of files in a directory, extended N_STR version
int scan_dir(const char * dir, LIST * result, const int recurse)
get a list of files in a directory
int resize_nstr(N_STR * nstr, size_t size)
resize a N_STR
N_STR * nstrprintf_ex(N_STR ** nstr_var, const char * format, ... )
printf on a N_STR
N_STR * nstrprintf_cat_ex(N_STR ** nstr_var, const char * format, ... )
concatenate printf on a N_STR
N_STR * nstrdup(N_STR * msg)
make a copy of a N_STR
N_STR * nstrcat_ex(N_STR ** dest, void * src, NSTRBYTE size, int resize_flag)
concatenate data inside a N_STR
N_STR * nstrcat_bytes_ex(N_STR ** dest, void * src, NSTRBYTE size)
wrapper to nstrcat_ex to concatenate void *data
int nstr_to_file(N_STR * n_str, char * filename)
write a whole N_STR into a file
int nstr_to_fd(N_STR * str, FILE * out, int lock)
write a whole N_STR into an open file descriptor
char * nfgets(char * buffer, NSTRBYTE size, FILE * stream)
N_STR wrapper around fgets.
N_STR * new_nstr(NSTRBYTE size)
create a new string
int n_str_utf8_valid(const char * s, size_t len)
Test that [s, s+len) is well-formed UTF-8 (RFC 3629).
N_STR * n_str_url_encode(const char * src)
Percent-encode a string per RFC 3986 (unreserved chars kept).
N_STR * n_str_template_expand(const char * tmpl, struct HASH_TABLE * vars)
Expand double-brace tokens in a template using a hash table.
char * join(char ** splitresult, const char * delim)
join a split result into a string
int free_split_result(char *** tab)
free a char **tab and set it to NULL
void free_nstr_ptr_nolog(void * ptr)
free a N_STR without logging or setting to NULL
void free_nstr_ptr(void * ptr)
free a N_STR without setting the pointer to NULL
int free_nstr_nolog(N_STR ** ptr)
free a N_STR and set to NULL without logging
N_STR * file_to_nstr(char * filename)
load a whole file into a N_STR
int empty_nstr(N_STR * nstr)
reinitialize a nstr
int char_to_nstr_nocopy_ex(char * from, NSTRBYTE nboct, N_STR ** to)
convert a char into a N_STR without copying
N_STR * char_to_nstr_nocopy(char * src)
convert a char into a N_STR without copying, shorter version
int char_to_nstr_ex(const char * from, NSTRBYTE nboct, N_STR ** to)
convert a char into a N_STR
N_STR * char_to_nstr(const char * src)
convert a char into a N_STR, shorter version
int _free_nstr(N_STR ** ptr)
free a N_STR and set the pointer to NULL

Defines

Name
strprintf(__n_var, ...)
Macro to quickly allocate and sprintf to a char.
nstrprintf_cat(__nstr_var, __format, ...)
Macro to quickly allocate and sprintf and cat to a N_STR.
nstrprintf(__nstr_var, __format, ...)
Macro to quickly allocate and sprintf to N_STR.
nstrcat_bytes(__nstr_dst, __void_src)
Macro to quickly concatenate a '\0' ended byte stream to a N_STR.
nstrcat(__nstr_dst, __nstr_src)
Macro to quickly concatenate two N_STR.
n_replace_cr(__nstr_var, __replacement)
Find and replace all occurences of carriage return (backslash r) in the string.
n_remove_ending_cr(__nstr_var)
Remove carriage return (backslash r) if there is one in the last position of the string.
local_strdup(_src)
Do tar(1) matching rules, which ignore a trailing slash?
free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
WILDMAT_NEGATE_CLASS
What character marks an inverted character class?
WILDMAT_ABORT
Abort code to sped up pattern matching.

Types Documentation

typedef NSTRBYTE

typedef size_t NSTRBYTE;

N_STR base unit.

Functions Documentation

function write_and_fit_ex

int write_and_fit_ex(
    char ** dest,
    NSTRBYTE * size,
    NSTRBYTE * written,
    const char * src,
    NSTRBYTE src_size,
    NSTRBYTE additional_padding
)

write and fit bytes into a dynamically sized buffer

Parameters:

  • dest pointer to the destination buffer (in/out, may be reallocated)
  • size pointer to the destination's total allocation, in bytes (in/out)
  • written pointer to the meaningful-byte count, excluding '\0' (in/out)
  • src source bytes to append (read-only, copied verbatim)
  • src_size number of bytes to copy from src
  • additional_padding extra bytes to over-allocate at realloc time

Return: TRUE on success, FALSE on allocation failure

Append src_size bytes from src to *dest, updating size/written, growing the buffer if needed.

write and fit bytes into a dynamically sized buffer

Post-call invariants (matching N_STR semantics):

  • *size = total allocation of *dest, in bytes (>= *written + 1). Includes additional_padding when a realloc happened, so subsequent appends that fit within the padding skip further reallocations.
  • *written = number of meaningful bytes in *dest, excluding the trailing '\0'. Bytes used including '\0' = *written + 1.

If *dest is NULL it is allocated from scratch (with *size, *written reset to 0 first).

function write_and_fit

int write_and_fit(
    char ** dest,
    NSTRBYTE * size,
    NSTRBYTE * written,
    const char * src
)

write and fit into the char array

Parameters:

  • dest pointer to the destination buffer (in/out, may be reallocated)
  • size pointer to the destination's total allocation, in bytes (in/out)
  • written pointer to the meaningful-byte count, excluding '\0' (in/out)
  • src null-terminated source string to append

Return: TRUE on success, FALSE on allocation failure

Append src to *dest.

write and fit into the char array

Convenience wrapper over write_and_fit_ex with src_size = strlen(src) and 8 bytes of headroom on growth (so a few short appends after a resize don't each trigger their own realloc). Same post-call invariants as write_and_fit_ex (*size = total allocation, *written = bytes excluding '\0').

function wildmatcase

int wildmatcase(
    register const char * text,
    register const char * p
)

pattern matching, case insensitive

Parameters:

  • text The source text to search
  • p The text to search, with wildcards

Return: return TRUE, FALSE, or WILDMAT_ABORT.

Written by Rich Salz rsalz at osf.org, refurbished by me.

pattern matching, case insensitive

Wildcard pattern matching case insensitive.

function wildmat

int wildmat(
    register const char * text,
    register const char * p
)

pattern matching

Parameters:

  • text The source text to search
  • p The text to search, with wildcards

Return: return TRUE, FALSE, or WILDMAT_ABORT.

Written by Rich Salz rsalz at osf.org, refurbished by me.

pattern matching

Wildcard pattern matching .

function trim_nocopy

char * trim_nocopy(
    char * s
)

trim and put a \0 at the end, return new begin pointer

Parameters:

  • s The string to trim

Return: the trimmed string or NULL

trim and zero end the string, WARNING: keep and original pointer to delete the string correctly

trim and put a \0 at the end, return new begin pointer

function trim

char * trim(
    const char * s
)

trim and put a \0 at the end, return new char *

Parameters:

  • s The string to trim

Return: the trimmed string or NULL

function strup

int strup(
    const char * string,
    char * dest
)

upper case a string

Parameters:

  • string the string to change to upper case
  • dest the string where storing result

Return: TRUE or FALSE

Warning: string must be same size as dest

Upper case a string.

upper case a string

function strlo

int strlo(
    const char * string,
    char * dest
)

lower case a string

Parameters:

  • string the string to change to lower case
  • dest the string where storing result

Return: TRUE or FALSE

Warning: string must be same size as dest

Lower case a string.

lower case a string

function strcpy_u

int strcpy_u(
    const char * from,
    char * to,
    NSTRBYTE to_size,
    char delim,
    NSTRBYTE * it
)

copy from string to dest until from[iterator] == delim

Parameters:

  • from Source string
  • to Dest string
  • to_size the maximum size to write
  • delim stopping character
  • it Save of iterator

Return: TRUE or FALSE

Copy from start to dest until from[ iterator ] == delim.

copy from string to dest until from[iterator] == delim

function str_to_long_long_ex

int str_to_long_long_ex(
    const char * s,
    NSTRBYTE start,
    NSTRBYTE end,
    long long int * i,
    const int base
)

string to long long integer, with error checking

Parameters:

  • s String to convert
  • start Start position of the chunk
  • end End position of the chunk
  • i A pointer to an integer variable which will receive the value.
  • base Base for converting values

Return: TRUE or FALSE

Helper for string[start to end] to long long integer.

string to long long integer, with error checking

Automatically add /0 for conversion. Leave values untouched if any error occur. Work on a copy of the chunk.

function str_to_long_long

int str_to_long_long(
    const char * s,
    long long int * i,
    const int base
)

string to long long integer, shorter version

Parameters:

  • s String to convert
  • i A pointer to an integer variable which will receive the value.
  • base Base for converting values

Return: TRUE or FALSE

Helper for string to integer.

string to long long integer, shorter version

function str_to_long_ex

int str_to_long_ex(
    const char * s,
    NSTRBYTE start,
    NSTRBYTE end,
    long int * i,
    const int base
)

string to long integer, with error checking

Parameters:

  • s String to convert
  • start Start position of the chunk
  • end End position of the chunk
  • i A pointer to an integer variable which will receive the value.
  • base Base for converting values

Return: TRUE or FALSE

Helper for string[start to end] to long integer.

string to long integer, with error checking

Automatically add /0 for conversion. Leave values untouched if any error occur. Work on a copy of the chunk.

function str_to_long

int str_to_long(
    const char * s,
    long int * i,
    const int base
)

string to long integer, shorter version

Parameters:

  • s String to convert
  • i A pointer to an integer variable which will receive the value.
  • base Base for converting values

Return: TRUE or FALSE

Helper for string to integer.

string to long integer, shorter version

function str_to_int_nolog

int str_to_int_nolog(
    const char * s,
    NSTRBYTE start,
    NSTRBYTE end,
    int * i,
    const int base,
    N_STR ** infos
)

string to integer, with error checking and no logging

Parameters:

  • s String to convert
  • start Start position of the chunk
  • end End position of the chunk
  • i A pointer to an integer variable which will receive the value.
  • base Base for converting values
  • infos If not NULL , contain the errors. remember to free the pointer if returned !!

Return: TRUE or FALSE

Helper for string[start to end] to integer.

string to integer, with error checking and no logging

Automatically add /0 for conversion. Leave values untouched if any error occur. Work on a copy of the chunk.

function str_to_int_ex

int str_to_int_ex(
    const char * s,
    NSTRBYTE start,
    NSTRBYTE end,
    int * i,
    const int base
)

string to integer, with error checking

Parameters:

  • s String to convert
  • start Start position of the chunk
  • end End position of the chunk
  • i A pointer to an integer variable which will receive the value.
  • base Base for converting values

Return: TRUE or FALSE

Helper for string[start to end] to integer.

string to integer, with error checking

Automatically add /0 for conversion. Leave values untouched if any error occur. Work on a copy of the chunk.

function str_to_int

int str_to_int(
    const char * s,
    int * i,
    const int base
)

string to integer, shorter version

Parameters:

  • s String to convert
  • i A pointer to an integer variable which will receive the value.
  • base Base for converting values

Return: TRUE or FALSE

Helper for string to integer.

string to integer, shorter version

function str_sanitize_ex

int str_sanitize_ex(
    char * string,
    const NSTRBYTE string_len,
    const char * mask,
    const NSTRBYTE masklen,
    const char replacement
)

sanitize a string using a character mask

Parameters:

  • string The string to change
  • string_len Size of the data to treat
  • mask The caracters to kill
  • masklen size of mask
  • replacement replacement for mask

Return: TRUE or FALSE

clean a string by replacing evil characteres

sanitize a string using a character mask

function str_sanitize

int str_sanitize(
    char * string,
    const char * mask,
    const char replacement
)

in-place substitution of a set of chars by a single one

Parameters:

  • string The string to change
  • mask The caracters to kill
  • replacement replacement for mask

Return: TRUE or FALSE

clean a string by replacing evil characteres

in-place substitution of a set of chars by a single one

function str_replace

char * str_replace(
    const char * string,
    const char * substr,
    const char * replacement
)

return a new string with all occurrences of substr replaced

Parameters:

  • string Original string, not modified
  • substr String to search; NULL or empty gives a plain copy
  • replacement Substitution string; NULL gives a plain copy

Return: A new string the caller frees, or NULL when string is NULL, on an allocation failure, or when the result's size would overflow

Replace every occurrence of substr by replacement in a copy of string.

return a new string with all occurrences of substr replaced

Occurrences are found from left to right and do not overlap: after one is replaced, the search goes on after it, never inside the replacement, so replacing "a" by "aa" ends. The occurrences are counted first and the result is allocated once, at its final size.

function str_natncasecmp

int str_natncasecmp(
    const char * a,
    size_t alen,
    const char * b,
    size_t blen
)

compare two byte runs of known length in natural order, ignoring ASCII case

Parameters:

  • a First run; NULL sorts before any run
  • alen Bytes in a
  • b Second run; NULL sorts before any run
  • blen Bytes in b

Return: -1, 0 or 1

Compare two byte runs in natural order, ignoring ASCII case.

compare two byte runs of known length in natural order, ignoring ASCII case

A run of digits compares as the number it spells, so "img2" sorts before "img10" and "2024-9" before "2024-10". Leading zeros do not change the value: "007" and "7" are the same number, and only when the strings are otherwise equal does the one with fewer leading zeros come first. Letters compare without case, through explicit A-Z range checks so the locale plays no part; any other byte, UTF-8 included, compares as unsigned. Two runs that differ only in case are finally ordered bytewise, so the result is a total order and qsort() gives the same answer every time. A number too long for any integer type still compares correctly, since digit runs are compared by length and then digit by digit.

The runs need no terminator and may hold a NUL, which compares as a byte: this is the form an SQLite collation is handed.

function str_natcasecmp

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

compare two strings in natural order, ignoring ASCII case

Parameters:

  • a First string; NULL sorts before any string
  • b Second string; NULL sorts before any string

Return: -1, 0 or 1

Compare two strings in natural order, ignoring ASCII case.

compare two strings in natural order, ignoring ASCII case

str_natncasecmp() on two NUL-terminated strings; the ordering rules are described there.

function split_count

int split_count(
    char ** split_result
)

count split elements

Parameters:

  • split_result A char **result from a split call

Return: a joined string using delimiter with The number of elements or -1 if errors

Count split elements.

count split elements

function split

char ** split(
    const char * str,
    const char * delim,
    int empty
)

return an array of char pointers to the split sections

Parameters:

  • str The char *str to split
  • delim The delimiter, one or more characters
  • empty Empty flag. If 1, then empty delimited areas will be added as NULL entries, else they will be skipped.

Return: An array of char *, ended by a NULL entry.

split the strings into a an array of char *pointer , ended by a NULL one.

return an array of char pointers to the split sections

function skipw

int skipw(
    const char * string,
    char toskip,
    NSTRBYTE * iterator,
    int inc
)

skip characters in string while string[iterator] == toskip

Parameters:

  • string a char *string to search in
  • toskip skipping while char character 'toskip' is found
  • iterator an int iteraor position on the string
  • inc an int to specify the step of skipping

Return: TRUE if success FALSE or ABORT if not

skip while 'toskip' occurence is found from 'iterator' to the next non 'toskip' position.

skip characters in string while string[iterator] == toskip

The new iterator index is automatically stored, returning to it first value if an error append.

function skipu

int skipu(
    const char * string,
    char toskip,
    NSTRBYTE * iterator,
    int inc
)

skip characters in string until string[iterator] == toskip

Parameters:

  • string a char *string to search in
  • toskip skipping while char character 'toskip' isnt found
  • iterator an int iteraor position on the string
  • inc an int to specify the step of skipping

Return: TRUE if success FALSE or ABORT if not

skip until 'toskip' occurence is found from 'iterator' to the next 'toskip' value.

skip characters in string until string[iterator] == toskip

The new iterator index is automatically stored, returning to it first value if an error append.

function scan_dir_ex

int scan_dir_ex(
    const char * dir,
    const char * pattern,
    LIST * result,
    const int recurse,
    const int mode
)

get a list of files in a directory, extended N_STR version

Parameters:

  • dir The directory to scan
  • pattern Pattern that files must follow to figure in the list
  • result A pointer to a valid LIST for the results
  • recurse Recursive search if TRUE, directory only if FALSE
  • mode 0 for a list of char* , 1 for a list of N_STR *

Return: TRUE or FALSE

Scan a list of directory and return a list of char *file.

get a list of files in a directory, extended N_STR version

function scan_dir

int scan_dir(
    const char * dir,
    LIST * result,
    const int recurse
)

get a list of files in a directory

Parameters:

  • dir The directory to scan
  • result A pointer to a valid LIST for the results
  • recurse Recursive search if TRUE, directory only if FALSE

Return: TRUE or FALSE

Scan a list of directory and return a list of char *file.

get a list of files in a directory

function resize_nstr

int resize_nstr(
    N_STR * nstr,
    size_t size
)

resize a N_STR

Parameters:

  • nstr targeted N_STR *string
  • size new internal buffer size

Return: TRUE or FALSE

reallocate a nstr internal buffer.

resize a N_STR

Warning: N_STR content will be reset if size = 0 !

function nstrprintf_ex

N_STR * nstrprintf_ex(
    N_STR ** nstr_var,
    const char * format,
    ... 
)

printf on a N_STR

Parameters:

  • nstr_var Pointer to a pointer to the N_STR object to allocate/resize.
  • format The format string (like printf).
  • ... Arguments to be formatted.

Return: The updated N_STR object.

Function to allocate and format a string into an N_STR object.

printf on a N_STR

function nstrprintf_cat_ex

N_STR * nstrprintf_cat_ex(
    N_STR ** nstr_var,
    const char * format,
    ... 
)

concatenate printf on a N_STR

Parameters:

  • nstr_var Pointer to a pointer to the N_STR object to allocate/resize and concatenate.
  • format The format string (like printf).
  • ... Variadic arguments for formatting.

Return: The updated N_STR object.

Function to allocate, format, and concatenate a string into an N_STR object.

concatenate printf on a N_STR

function nstrdup

N_STR * nstrdup(
    N_STR * msg
)

make a copy of a N_STR

Parameters:

  • str A N_STR *object to free

Return: A valid N_STR or NULL

Duplicate a N_STR.

make a copy of a N_STR

function nstrcat_ex

N_STR * nstrcat_ex(
    N_STR ** dest,
    void * src,
    NSTRBYTE size,
    int resize_flag
)

concatenate data inside a N_STR

Parameters:

  • dest The N_STR *destination (accumulator)
  • src The data to append
  • size The number of octet of data we want to append in dest
  • resize_flag Set it to a positive non zero value to allow resizing, or to zero to forbid resizing

Return: TRUE or FALSE

Append data into N_STR using internal N_STR size and cursor position.

concatenate data inside a N_STR

function nstrcat_bytes_ex

N_STR * nstrcat_bytes_ex(
    N_STR ** dest,
    void * src,
    NSTRBYTE size
)

wrapper to nstrcat_ex to concatenate void *data

Parameters:

  • dest The N_STR **destination (accumulator)
  • data The data to append
  • size The number of octet of data we want to append in dest

Return: TRUE or FALSE

Append data into N_STR using internal N_STR size and cursor position.

wrapper to nstrcat_ex to concatenate void *data

Wrapper to nstrcat_ex, with resize_flag on and a block size one byte higher than size.

function nstr_to_file

int nstr_to_file(
    N_STR * n_str,
    char * filename
)

write a whole N_STR into a file

Parameters:

  • str The N_STR *content to write down
  • filename The destination filename

Return: TRUE or FALSE

Write a N_STR content into a file.

write a whole N_STR into a file

function nstr_to_fd

int nstr_to_fd(
    N_STR * str,
    FILE * out,
    int lock
)

write a whole N_STR into an open file descriptor

Parameters:

  • str The N_STR *content to write down
  • out An opened FILE *handler
  • lock a write lock will be put if lock = 1

Return: TRUE or FALSE

Write a N_STR content into a file.

write a whole N_STR into an open file descriptor

function nfgets

char * nfgets(
    char * buffer,
    NSTRBYTE size,
    FILE * stream
)

N_STR wrapper around fgets.

Parameters:

  • buffer The string where to read the file
  • size Size of the string
  • stream The file to read

Return: NULL or the captured string

try to fgets

N_STR wrapper around fgets.

function new_nstr

N_STR * new_nstr(
    NSTRBYTE size
)

create a new string

Parameters:

  • size Size of the new string. 0 for no allocation. The maximum representable size is rejected: the allocation is size + 1 for the terminator and that sum would wrap to 0, handing back a one-element buffer for a huge string.

Return: A new allocated N_STR or NULL

create a new N_STR string

create a new string

function n_str_utf8_valid

int n_str_utf8_valid(
    const char * s,
    size_t len
)

Test that [s, s+len) is well-formed UTF-8 (RFC 3629).

Parameters:

  • s bytes to test (may be NULL only when len is 0)
  • len number of bytes
  • s bytes to test (may be NULL only when len is 0)
  • len number of bytes

Return:

  • TRUE when valid, FALSE otherwise
  • TRUE when valid, FALSE otherwise

Test that [s, s+len) is well-formed UTF-8 (RFC 3629): no overlong form, no surrogate, nothing above U+10FFFF, no truncated sequence.

Refuses overlong forms, surrogates (U+D800-U+DFFF), code points above U+10FFFF and truncated sequences, the same rules as PHP's mb_check_encoding(..., 'UTF-8'). NUL bytes are valid UTF-8 and accepted: refuse them separately when they matter. Test that [s, s+len) is well-formed UTF-8 (RFC 3629).

function n_str_url_encode

N_STR * n_str_url_encode(
    const char * src
)

Percent-encode a string per RFC 3986 (unreserved chars kept).

Parameters:

  • src NUL-terminated input string. NULL returns NULL.

Return: Newly allocated N_STR with the encoded result, or NULL on invalid input or allocation failure. The caller must free it with free_nstr().

Percent-encode a C string per RFC 3986 (unreserved set kept as-is).

Letters, digits and -_.~ are written verbatim; all other bytes become HH. Uses explicit range checks (locale-independent). n_url_encode() in n_network.h is a convenience alias that delegates to this function. See the full parameter contract on the implementation in [src/n_str.c](n__str_8c).

Percent-encode a string per RFC 3986 (unreserved chars kept).

Letters, digits and the characters '-', '_', '.', '~' are written verbatim. Every other byte is written as HH using upper-case hex. The function is binary-safe in the sense that it never assumes UTF-8 boundaries; it only stops at the terminating NUL of src.

function n_str_template_expand

N_STR * n_str_template_expand(
    const char * tmpl,
    struct HASH_TABLE * vars
)

Expand double-brace tokens in a template using a hash table.

Parameters:

  • tmpl Template string with {{key}} tokens. Must not be NULL.
  • vars Hash table mapping key to value. May be NULL.

Return: Newly allocated N_STR with expanded result, or NULL on failure.

Tokens not found in vars are left unchanged.

function join

char * join(
    char ** splitresult,
    const char * delim
)

join a split result into a string

Parameters:

  • splitresult the split result to join
  • delim The delimiter, one or more characters

Return: the joined split result or NULL

join the array into a string

join a split result into a string

function free_split_result

int free_split_result(
    char *** tab
)

free a char **tab and set it to NULL

Parameters:

  • tab A pointer to a split result to free

Return: TRUE

Free a split result allocated array.

free a char **tab and set it to NULL

function free_nstr_ptr_nolog

void free_nstr_ptr_nolog(
    void * ptr
)

free a N_STR without logging or setting to NULL

Parameters:

  • ptr A N_STR *object to free

Free a N_STR pointer structure.

free a N_STR without logging or setting to NULL

function free_nstr_ptr

void free_nstr_ptr(
    void * ptr
)

free a N_STR without setting the pointer to NULL

Parameters:

  • ptr A N_STR *object to free

Free a N_STR pointer structure.

free a N_STR without setting the pointer to NULL

function free_nstr_nolog

int free_nstr_nolog(
    N_STR ** ptr
)

free a N_STR and set to NULL without logging

Parameters:

  • ptr A N_STR *object to free

Return: TRUE or FALSE

Free a N_STR structure and set the pointer to NULL.

free a N_STR and set to NULL without logging

function file_to_nstr

N_STR * file_to_nstr(
    char * filename
)

load a whole file into a N_STR

Parameters:

  • filename The filename to load inside a N_STR

Return: A valid N_STR (an empty one for a 0-byte file) or NULL on error. An empty file is not an error: the returned N_STR has a valid NUL-terminated data buffer and written == 0.

Load a whole file into a N_STR.

load a whole file into a N_STR

Be aware of the NSTRBYTE addressing limit (2GB commonly)

function empty_nstr

int empty_nstr(
    N_STR * nstr
)

reinitialize a nstr

Parameters:

  • nstr the N_STR *str string to empty

Return: TRUE or FALSE

empty a N_STR string

reinitialize a nstr

function char_to_nstr_nocopy_ex

int char_to_nstr_nocopy_ex(
    char * from,
    NSTRBYTE nboct,
    N_STR ** to
)

convert a char into a N_STR without copying

function char_to_nstr_nocopy

N_STR * char_to_nstr_nocopy(
    char * src
)

convert a char into a N_STR without copying, shorter version

Parameters:

  • src A char *string to use

Return: A N_STR using src or NULL

Convert a char into a N_STR, direct use of linked source pointer.

convert a char into a N_STR without copying, shorter version

function char_to_nstr_ex

int char_to_nstr_ex(
    const char * from,
    NSTRBYTE nboct,
    N_STR ** to
)

convert a char into a N_STR

Parameters:

  • from A char *string to convert
  • nboct The size to copy, from 1 octet to nboctet (ustrsizez( from ) )
  • to A N_STR pointer who will be Malloced

Return: True on success, FALSE on failure ( to will be set to NULL )

Convert a char into a N_STR, extended version.

convert a char into a N_STR

function char_to_nstr

N_STR * char_to_nstr(
    const char * src
)

convert a char into a N_STR, shorter version

Parameters:

  • src A char *string to convert

Return: A N_STR copy of src or NULL

Convert a char into a N_STR, short version.

convert a char into a N_STR, shorter version

function _free_nstr

int _free_nstr(
    N_STR ** ptr
)

free a N_STR and set the pointer to NULL

Parameters:

  • ptr A N_STR *object to free

Return: TRUE or FALSE

Free a N_STR structure and set the pointer to NULL.

free a N_STR and set the pointer to NULL

Macros Documentation

define strprintf

#define strprintf(
    __n_var,
    ...
)
({                                                                    \
    char* __strprintf_ptr = NULL;                                     \
    if (!(__n_var)) {                                                 \
        int __needed = snprintf(NULL, 0, __VA_ARGS__);                \
        if (__needed > 0) {                                           \
            Malloc(__n_var, char, (size_t)__needed + 1);              \
            if (__n_var) {                                            \
                snprintf(__n_var, (size_t)__needed + 1, __VA_ARGS__); \
                __strprintf_ptr = __n_var;                            \
            } else {                                                  \
                n_log(LOG_ERR, "couldn't allocate %s with %d bytes",  \
                      #__n_var, __needed + 1);                        \
            }                                                         \
        }                                                             \
    } else {                                                          \
        n_log(LOG_ERR, "%s is already allocated.", #__n_var);         \
    }                                                                 \
    __strprintf_ptr;                                                  \
})

Macro to quickly allocate and sprintf to a char.

define nstrprintf_cat

#define nstrprintf_cat(
    __nstr_var,
    __format,
    ...
)
nstrprintf_cat_ex(&(__nstr_var), (__format), ##__VA_ARGS__)

Macro to quickly allocate and sprintf and cat to a N_STR.

define nstrprintf

#define nstrprintf(
    __nstr_var,
    __format,
    ...
)
nstrprintf_ex(&(__nstr_var), (__format), ##__VA_ARGS__)

Macro to quickly allocate and sprintf to N_STR.

define nstrcat_bytes

#define nstrcat_bytes(
    __nstr_dst,
    __void_src
)
nstrcat_bytes_ex(&(__nstr_dst), __void_src, strlen(__void_src))

Macro to quickly concatenate a '\0' ended byte stream to a N_STR.

define nstrcat

#define nstrcat(
    __nstr_dst,
    __nstr_src
)
({                                                                                           \
    N_STR* __nstrcat_ret = NULL;                                                             \
    if (__nstr_src && __nstr_src->data) {                                                    \
        __nstrcat_ret = nstrcat_ex(&(__nstr_dst), __nstr_src->data, __nstr_src->written, 1); \
    }                                                                                        \
    __nstrcat_ret;                                                                           \
})

Macro to quickly concatenate two N_STR.

define n_replace_cr

#define n_replace_cr(
    __nstr_var,
    __replacement
)
do {                                                                           \
    if (__nstr_var && __nstr_var->data && __nstr_var->written > 0) {           \
        char* __replaced = str_replace(__nstr_var->data, "\r", __replacement); \
        if (__replaced) {                                                      \
            Free(__nstr_var->data);                                            \
            __nstr_var->data = __replaced;                                     \
            __nstr_var->written = strlen(__nstr_var->data);                    \
            __nstr_var->length = __nstr_var->written + 1;                      \
        }                                                                      \
    }                                                                          \
} while (0)

Find and replace all occurences of carriage return (backslash r) in the string.

define n_remove_ending_cr

#define n_remove_ending_cr(
    __nstr_var
)
do {                                                                                                                      \
    if (__nstr_var && __nstr_var->data && __nstr_var->written > 0 && __nstr_var->data[__nstr_var->written - 1] == '\r') { \
        __nstr_var->data[__nstr_var->written - 1] = '\0';                                                                 \
        __nstr_var->written--;                                                                                            \
    }                                                                                                                     \
} while (0)

Remove carriage return (backslash r) if there is one in the last position of the string.

define local_strdup

#define local_strdup(
    __src_
)
({                                                                                                               \
    char* __local_strdup_str = NULL;                                                                             \
    size_t __local_strdup_len = strlen((__src_));                                                                \
    Malloc(__local_strdup_str, char, __local_strdup_len + 1);                                                    \
    if (!__local_strdup_str) {                                                                                   \
        n_log(LOG_ERR, "Couldn't allocate %d byte for duplicating \"%s\"", (int)strlen((__src_)) + 1, (__src_)); \
    } else {                                                                                                     \
        for (size_t __local_strdup_it = 0; __local_strdup_it <= __local_strdup_len; __local_strdup_it++) {       \
            __local_strdup_str[__local_strdup_it] = (__src_)[__local_strdup_it];                                 \
        }                                                                                                        \
    }                                                                                                            \
    __local_strdup_str;                                                                                          \
})

Do tar(1) matching rules, which ignore a trailing slash?

local strdup

define free_nstr

#define free_nstr(
    __ptr
)
{                                                       \
    if ((*__ptr)) {                                     \
        _free_nstr(__ptr);                              \
    } else {                                            \
        n_log(LOG_DEBUG, "%s is already NULL", #__ptr); \
    }                                                   \
}

free a N_STR structure and set the pointer to NULL

define WILDMAT_NEGATE_CLASS

#define WILDMAT_NEGATE_CLASS '^'

What character marks an inverted character class?

define WILDMAT_ABORT

#define WILDMAT_ABORT -2

Abort code to sped up pattern matching.

Special thanks to Lars Mathiesen thorinn@diku.dk for the ABORT code.