String

#import "std/string"

Builtin UTF-8 encoded dynamic string container.

string :: struct {
    len: s64;
    ptr: *u8;
}


// Compile-time string literal
my_string :: "This is my string!";


// Dynamic string allocated on heap.
// New dynamic string can be created from string literal.
my_string :: std.str_new("This is my string!");
defer std.str_delete(&my_string);

BL strings are zero terminated except of sub-string view function (terminator cannot be added because we cannot modify original string).

Note: String manipulation functions are related only to dynamic strings and cannot be used with string literals since those are constants allocated on stack.

std.str_new

str_new :: fn { 
    fn (allocator : *Allocator: null) string; 
    fn (size: s64, allocator : *Allocator: null) string; 
    fn (v: string_view, allocator : *Allocator: null) string; 
    fn (cstr: *u8, allocator : *Allocator: null) string; 
}

Overloaded function creating new dynamic string instance. Created string is guaranteed to be zero terminated.

Overloads:

fn (allocator: *Allocator = null) string
fn (size: s64, allocator: *Allocator = null) string
fn (v: string_view, allocator: *Allocator = null) string
fn (cstr: *u8, allocator: *Allocator = null) string

File: string.bl

std.str_delete

str_delete :: fn (v: *string) 

Delete dynamic string.

File: string.bl

std.str_reserve

str_reserve :: fn (v: *string, count: s64) 

Ensure that string's underlying buffer is capable to hold count of characters and eventually do preallocation if buffer is too small. The reserve does not take in account if the string's buffer is full or not. The function does nothing if buffer size is enough.

File: string.bl

std.str_get_allocated_bytes

str_get_allocated_bytes :: fn (v: string) usize #inline

Get currently allocated memory used by the string in bytes.

File: string.bl

std.str_clear

str_clear :: fn (v: *string) 

Clear dynamic string but keep allocated storage.

File: string.bl

std.str_append

str_append :: fn { 
    _str_append_str; 
    _str_append_any; 
}

Append dynamic string with any value. Allocation is done in case there is not enough space reminding in string. The v string is supposed to be allocated on heap.

Returns count of characters appended to the string excluding zero terminator.

File: string.bl

std.str_concat

str_concat :: fn (v: *string, args: ...) string

Append string with multiple values passed as args and return @v. New allocation is done in case there is space no left in currently allocated string's memory to append args.

File: string.bl

std.str_clear_concat

str_clear_concat :: fn (v: *string, args: ...) string

Clear the v string and append multiple values passed as args. Returned value is dereference of the original v string after new values are appended. New allocation is done in case there is space no left in currently allocated string's memory to append args.

hint: Use this function in case you need create only temporary string i.e. file path.

VERSION :: "1.0.0";

path := std.str_new();
defer std.str_delete(path);
std.set_cwd(std.str_clear_concat(&path, "my-dir/project-", VERSION));

File: string.bl

std.str_match

str_match :: fn (first: string_view, second: string_view, n :: -1) bool

Compare first and second strings in specified range n and return true if they are the same otherwise return false.

Range value n is optional and ignored when it's less than 0.

File: string.bl

std.str_compare

str_compare :: fn (first: string_view, second: string_view) s32

File: string.bl

std.str_match_one_of

str_match_one_of :: fn (str: string_view, list: []string_view) bool

Returns true in case the input string str is matching exactly one of strings in the list.

File: string.bl

std.str_first_match

str_first_match :: fn (str: string_view, list: []string_view) s32

Returns index of the first matching string in the input list or -1 if there is no match.

File: string.bl

std.strtos64

strtos64 :: fn (str: string_view, base :: FmtIntBase.DEC, count :: -1) (_0: s64, _1: Error)

Converts the first count of characters from str to s64 number and return OK on success. Whole string will be used in case the count is less than zero. The base of expected number can be specified as base argument. Note that in case of binary, octal and hex encoding, we do not expect any prefixes as 0b, 0 and 0x.

Negative values can be converted too.

Returns error when:

- The input string is empty and `count` greater than zero.
- Converted number cause overflow of s64.
- The input string contains invalid characters.

File: string.bl

std.strtof64

strtof64 :: fn (str: string_view, count :: -1) (_0: f64, _1: Error)

Converts the first count of characters from str to f64 and return OK on success. Use the whole string in case the count is not specified.

Returns error when:

- The input string is empty and `count` greater than zero.
- The input string contains invalid characters.

File: string.bl

std.str_split_by_last

str_split_by_last :: fn (str: string_view, delimiter: u8, lhs: *string_view, rhs : *string_view: null, di : *s32: null) bool

Split input string str into two tokens based on the last occurrence of delimiter. Delimiter is not included in resulting tokens. Result tokens only points into original memory of the str, they are not supposed to be freed.

When delimiter is not present in the input string function return false, lhs is set to the original str string, rhs value is unchanged.

Token destination pointers lhs and rhs are optional. The di output variable is set to index of the split position when it's not null.

Warning: lhs and rhs sub strings are not guaranteed to be zero terminated.

Example

main :: fn () s32 {
    lhs: string_view;
    rhs: string_view;
    if std.str_split_by_last("this/is/my/epic/path", '/', &lhs, &rhs) {
        print("lhs = %\n", lhs);
        print("rhs = %\n", rhs);
    }

    return 0;
}

File: string.bl

std.str_split_at_index

str_split_at_index :: fn (str: string_view, index: s32, lhs : *string_view: null, rhs : *string_view: null) bool

Split input string str at index position and return true when split was done. Result tokens only points into original memory of the str, they are not supposed to be freed. When index is out of str range function return false, lhs and rhs buffers are not modified.

Token destination pointers lhs and rhs are optional.

Warning: lhs and rhs sub strings are not guaranteed to be zero terminated.

Example

main :: fn () s32 {
    lhs: string_view;
    rhs: string_view;
    if std.str_split_at_index("foobar", 3, &lhs, &rhs) {
        print("lhs = %\n", lhs);
        print("rhs = %\n", rhs);
    }

    return 0;
}

File: string.bl

std.str_split_by_first

str_split_by_first :: fn (str: string_view, delimiter: u8, lhs: *string_view, rhs : *string_view: null, di : *s32: null) bool

Split input string str into two tokens based on the first occurrence of delimiter. Delimiter is not included in resulting tokens. Result tokens only points into original memory of the str, they are not supposed to be freed.

When delimiter is not present in the input string function return false, lhs is set to the original str string, rhs value is unchanged.

Token destination pointers lhs and rhs are optional.

Warning: lhs and rhs sub strings are not guaranteed to be zero terminated.

Example

main :: fn () s32 {
    lhs: string_view;
    rhs: string_view;
    if std.str_split_by_first("this/is/my/epic/path", '/', &lhs, &rhs) {
        print("lhs = %\n", lhs);
        print("rhs = %\n", rhs);
    }

    return 0;
}

File: string.bl

std.str_insert

str_insert :: fn { 
    _string_insert; 
    _char_insert; 
}

Overloaded function inserting one character or other string at desired position.

Overloads:

fn (str: *string, index: s32, v: u8) bool #inline
fn (str: *string, index: s32, v: string_view) bool

Note: Function does nothing (return false) when v string is empty.

File: string.bl

std.str_erase

str_erase :: fn (str: *string, index: s32) bool

Erase one character at index position and return true when character was erased. The 'index value is checked to fit in string bounds.

File: string.bl

std.str_split_by

str_split_by :: fn (str: string_view, delimiter: u8, allocator : *Allocator: null) [..]string_view

Split the str input string by delimiter and return new slice containing all found sub-strings. In case input string is empty, returs empty slice.

Warning: String array should be terminated by array_terminate call.

Warning: Slice elements are not guaranteed to be zero terminated.

File: string.bl

std.str_tokenize

str_tokenize :: fn { 
    fn (str: string_view, delimiter: u8, ctx: *?T, visitor: *fn (token: string_view, ctx: *T) bool) ; 
    fn (str: string_view, delimiter: u8, visitor: *fn (token: string_view) bool) ; 
}

Call the visitor callback for each token in the str input split by delimiter. When the visitor callback returns false parsing is stopped.

Overloads:

fn (str: string_view, delimiter: u8, ctx: *?T, visitor: *fn(token: string_view, ctx: *T) bool)
fn (str: string_view, delimiter: u8, visitor: *fn(token: string_view) bool)

Example

main :: fn () s32 {
    using std;
    path := "/home/travis/develop/foo";
    str_tokenize(path, '/', &fn (token: string_view) bool {
        print("TOKEN: %\n", token);
        return true;
    });

    return 0;
}

Note: Callback is not called for empty tokens.

File: string.bl

std.str_count_of

str_count_of :: fn (str: string_view, c: u8) s32 #inline

Counts desired character occurrence in the input string.

File: string.bl

std.str_lower

str_lower :: fn (str: *string) s32 #inline

Converts ascii input string to lower case and returns count of changed characters.

File: string.bl

std.str_lower_single_character

str_lower_single_character :: fn (str: *string, index: s64)  #inline

Converts single character from the str at index index to lower case. String str must be valid string pointer and index must be in range <0, str.len).

File: string.bl

std.str_upper

str_upper :: fn (str: *string) s32 #inline

Converts ascii input string to upper case and returns count of changed characters.

File: string.bl

std.str_upper_single_character

str_upper_single_character :: fn (str: *string, index: s64)  #inline

Converts single character from the str at index index to upper case. String str must be valid string pointer and index must be in range <0, str.len).

File: string.bl

std.str_replace_all

str_replace_all :: fn (str: *string, c: u8, with :: ) s32

Replace all found occurrences of character c in the input string with with character and return count of replacements made. This function cannot be used with constant string literals as input.

If with replacement is 0 character, all c occurrences will be erased from the string.

Function return count of replaced characters or zero.

File: string.bl

std.str_hash

str_hash :: fn (str: string_view) u32

Calculates string u32 hash.

File: string.bl

std.str_is_null

str_is_null :: fn (s: string_view) bool #inline

Helper inline function returning true when string is null. In such case string len could be any value.

File: string.bl

std.str_is_empty

str_is_empty :: fn (s: string_view) bool #inline

Helper inline function returning true when string is empty. In such case string ptr could be any pointer.

File: string.bl

std.str_empty

str_empty :: 

File: string.bl

std.str_view_empty

str_view_empty :: 

File: string.bl

std.str_is_null_or_empty

str_is_null_or_empty :: fn (s: string_view) bool #inline

Helper inline function returning true when string is empty and null.

File: string.bl

std.str_sub

str_sub :: fn (str: string_view, start: s64, len : s64: -1) string_view #inline

Creates substring from passed string starting at start index of input string and ending at start + len index.

Starting index start must be greater than 0 and less than str.len. len specifies optional length of substring. When not specified, length from start to the end of the str is used.

Warning: Result sub-string is not guaranteed to be zero terminated.

File: string.bl

std.str_is_zero_terminated

str_is_zero_terminated :: fn (str: string_view) bool #inline

Checks whether string is zero terminated.

File: string.bl

std.strtoc

strtoc :: fn (str: string_view) *C.char #inline

Converts string view into C string representation. The original string str must be zero-terminated (checked by assert).

File: string.bl

std.ctostr

ctostr :: fn (cstr: *C.char, len : s64: -1) string_view #inline

Converts C string into string view. The len argument is optional and is used as string length if it's greater than -1, otherwise the strlen is used.

Empty string view is returned when the input C string is null.

File: string.bl

std.is_alpha

is_alpha :: fn (c: u8) bool #inline

Check whether the input ascii character is an alphabet.

File: string.bl

std.is_digit

is_digit :: fn (c: u8, base :: FmtIntBase.DEC) bool #inline

Check wheter the input character represents a digit of number of base.

File: string.bl