From fcfb6ac21651e286092bcc92309e89c8fa2e87fd Mon Sep 17 00:00:00 2001 From: dacctal Date: Wed, 1 Jul 2026 05:47:28 +0000 Subject: checkpoint! --- include/str.h | 518 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 498 insertions(+), 20 deletions(-) (limited to 'include/str.h') diff --git a/include/str.h b/include/str.h index c81bcbd..f5c79dd 100644 --- a/include/str.h +++ b/include/str.h @@ -18,33 +18,511 @@ */ -#ifndef PKGIT_STRING_H -#define PKGIT_STRING_H +#ifndef PKGIT_STR_H +#define PKGIT_STR_H + +#include +#include #include +#include +#include +/** + * Heap-allocated, owned character string. + * + * All library functions assert that pointers passed in are valid and point to + * valid data. All references to "C strings" infer null-terminated pointers to + * characters. + * + * When data is NULL, it is deemed invalid. + */ typedef struct { - char* data; + char *data; + size_t cap; size_t len; -} str_slc; +} str; +/** + * A view into any character buffer that may not be + * resized, but may be heap-allocated. + * + * When data is NULL, it is deemed invalid. + */ typedef struct { - char* data; - size_t cap; + const char *data; size_t len; -} str; +} str_slc; + +#define str_is_valid(str) ((str)->data != NULL) + +// for printf formatting +#define str_fmt(s) (int)((s)->len), (s)->data + +/** + * Creates and initializes an empty, valid str. + */ +str str_new(void); + +/** + * Creates and initializes an empty str with a specified capacity. + */ +str str_new_with_capacity(size_t cap); + +/** + * Make a str from a C string. + */ +str str_from_cstr(const char *s); + +/** + * Equivalent to str_from_cstr + */ +str mstr(const char *s); + +/** + * Make a str from a string slice. + */ +str str_from_str_slc(const str_slc s); + +/** + * Return a str from the result of an sprintf-style call. + */ +str str_format(const char *format, ...); + +/** + * Saves the result of an sprintf-style call into s. + */ +void str_format_into(str *s, const char *format, ...); + +/** + * Reserves 1.5*new_cap bytes of space in the string. + */ +void str_reserve(str *s, size_t new_cap); + +/** + * Reserves EXACTLY new_cap of bytes of space in the string. + */ +void str_reserve_exact(str *s, size_t new_cap); + +/** + * Clears the entire string buffer to zeroes and resets the length. + */ +void str_clear(str *s); + +/** + * Frees the internal heap-allocated buffer. + */ +void str_free(str *s); + +/** + * Copies the entirety of src into dest, resizing it if necessary, while + * overwriting all existing data. + */ +void str_copy_into(str *dest, const str *src); + +/** + * Copies a source C string at src into an already initialized + * str, resizing the buffer if necessary, overwriting all existing data. + */ +void str_copy_cstr_into(str *dest, const char *src); + +/** + * Copies a source string slice at src into an already initialized + * str, resizing the buffer if necessary, overwriting all existing data. + */ +void str_copy_str_slc_into(str *dest, const str_slc src); + +/** + * Copies n bytes of src into an already initialized str dest, + * resizing it if necessary, while overwriting all existing data. + */ +void str_ncopy_into(str *dest, const str *src, size_t count); + +/** + * Copies n bytes of a C string src into an already initialized str dest, + * resizing it if necessary, while overwriting all existing data. + */ +void str_ncopy_cstr_into(str *dest, const char *src, size_t count); + +/** + * Copies n bytes of a string slice src into an already initialized str dest, + * resizing it if necessary, while overwriting all existing data. + */ +void str_ncopy_str_slc_into(str *dest, const str_slc src, size_t count); + +/** + * Duplicates a str exactly, retaining its original capacity. + */ +str str_dupe(const str *src); + +/** + * Appends a str into an existing str, resizing the buffer if necessary. + */ +void str_append(str *src, const str *new); + +/** + * Appends a single character new into src, resizing the buffer if necessary. + */ +void str_append_char(str *src, char new); + +/** + * Appends a C string into an existing str, resizing the buffer if necessary. + */ +void str_append_cstr(str *src, const char *new); + +/** + * Appends a string slice into an existing str, resizing the buffer if + * necessary. + */ +void str_append_str_slc(str *src, const str_slc new); + +/** + * Removes the last character from src, returning it. + */ +char str_pop_last(str *src); + +/** + * Concatenates lhs and rhs together into a new string. + */ +str str_concat(const str *lhs, const str *rhs); + +/** + * Concatenates lhs and a C string rhs together into a new string. + */ +str str_concat_cstr(const str *lhs, const char *rhs); + +/** + * Concatenates lhs and a str_slc rhs together into a new string. + */ +str str_concat_str_slc(const str *lhs, const str_slc rhs); + +/** + * Trims all whitespace characters in s away only on the left, and returns the + * result. + */ +str str_trim_left(const str *s); + +/** + * Trims all whitespace characters in s away only on the left, and returns the + * result. + */ +str str_trim_right(const str *s); + +/** + * Trims all whitespace characters in s away on the left and right, and returns + * the result. + */ +str str_trim(const str *s); + +/** + * Converts all characters in s to uppercase and returns the result. + */ +str str_to_upper(const str *s); + +/** + * Converts all characters in s to lowercase and returns the result + */ +str str_to_lower(const str *s); + +/** + * Trims all whitespace characters in s away only on the left, modifying the + * string s. + */ +void str_trim_left_in_place(str *s); + +/** + * Trims all whitespace characters in s away only on the right, modifying the + * string s. + */ +void str_trim_right_in_place(str *s); + +/** + * Trims all whitespace characters in s away on the left and right, modifying + * the string s. + */ +void str_trim_in_place(str *s); + +/** + * Converts all characters in s to uppercase, modifying the string s. + */ +void str_to_upper_in_place(str *s); + +/** + * Converts all characters in s to lowercase, modifying the string s. + */ +void str_to_lower_in_place(str *s); + +/** + * Returns if lhs and rhs are equal. + */ +bool str_equal(const str *lhs, const str *rhs); + +/** + * Returns if lhs and rhs (a C string) are equal. + */ +bool str_equal_cstr(const str *lhs, const char *rhs); + +/** + * Returns if lhs and rhs (a string slice) are equal. + */ +bool str_equal_str_slc(const str *lhs, const str_slc rhs); + +/** + * Compares the strings lhs and rhs lexicographically, similar to strcmp. + */ +int str_compare(const str *lhs, const str *rhs); + +/** + * Compares the strings lhs and rhs (a C string) lexicographically, similar to + * strcmp. + */ +int str_compare_cstr(const str *lhs, const char *rhs); + +/** + * Compares the strings lhs and rhs (a string slice) lexicographically, similar + * to strcmp. + */ +int str_compare_str_slc(const str *lhs, const str_slc rhs); + +/** + * Returns if lhs and rhs are equal, ignoring case. + */ +bool str_equal_case_insensitive(const str *lhs, const str *rhs); + +/** + * Returns if lhs and rhs (a C string) are equal, ignoring case. + */ +bool str_equal_cstr_case_insensitive(const str *lhs, const char *rhs); + +/** + * Returns if lhs and rhs (a string slice) are equal, ignoring case. + */ +bool str_equal_str_slc_case_insensitive(const str *lhs, const str_slc rhs); + +/** + * Compares the strings lhs and rhs lexicographically, ignoring case, similar to + * strcasecmp. + */ +int str_compare_case_insensitive(const str *lhs, const str *rhs); + +/** + * Compares the strings lhs and rhs (a C string) lexicographically, ignoring + * case, similar to strcasecmp. + */ +int str_compare_cstr_case_insensitive(const str *lhs, const char *rhs); + +/** + * Compares the strings lhs and rhs (a String slice) lexicographically, ignoring + * case, similar to strcasecmp. + */ +int str_compare_str_slc_case_insensitive(const str *lhs, const str_slc rhs); + +/** + * Slices a string from `begin` to `end`, clamping values to [0, src->len] if + * needed, and returning the result. + * ptrdiff_t's are used, as slicing functions may return negative values. + */ +str str_slice_to_str(const str *src, ptrdiff_t begin, ptrdiff_t end); + +/** + * Slices a C string from `begin` to `end`, clamping values to [0, src->len] if + * needed, returning the result as a str. + * ptrdiff_t's are used, as slicing functions may return negative values. + */ +str str_slice_from_cstr(const char *src, ptrdiff_t begin, ptrdiff_t end); + +/** + * Slices a string from `begin` to `end`, clamping values to [0, src->len] if + * needed, returning the result as a str_slc. + * ptrdiff_t's are used, as slicing functions may return negative values. + */ +str_slc str_slice(const str *src, ptrdiff_t begin, ptrdiff_t end); + +/** + * Slices a string slice from beginning to end, clamping values to [0, src->len] + * if needed Python, returning the result as a str. + * ptrdiff_t's are used, as slicing functions may return negative values. + */ +str str_slice_from_str_slc(const str_slc src, ptrdiff_t begin, ptrdiff_t end); + +/** + * Converts a str to a double with strtod(3), returning how many bytes of src + * were converted to a double. + */ +size_t str_to_double_pro(const str *src, double *res); + +/** + * Converts a str to a int64_t with strtoll(3), returning how many bytes of src + * were converted to a double. + */ +size_t str_to_int64_pro(const str *src, int64_t *res, int base); + +/** + * Converts a str to a double with strtod(3), returning a success or failure. + */ +bool str_to_double(const str *src, double *res); + +/** + * Converts a str to a int64_t with strtoll(3), returning a success or failure. + */ +bool str_to_int64(const str *src, int64_t *res); + +/** + * Reads a single line from f into a str, and returns it. + * Panics on failure. + */ +str str_read_line_from_file(FILE *f); + +/** + * Reads count characters from f into a str, and returns it. + * Panics on failure. + */ +str str_read_chars_from_file(FILE *f, size_t count); + +/** + * Reads the entirety of f into a str, and returns it. + * Panics on failure. + */ +str str_read_entire_file(FILE *f); + +/** + * Writes the entirety of a str to a file, returning a success or failure. + * Panics on failure. + */ +bool str_write_to_file(const str *s, FILE *f); + +/** + * Gets the nth character of a str, with bounds checking. + */ +char str_at(const str *s, size_t i); + +/** + * Gets the first character of a str, with bounds checking. + */ +char str_first(const str *s); + +/** + * Gets the last character of a str, with bounds checking. + */ +char str_last(const str *s); + +/** + * Finds a character c in s, from the left to the right. + * Returns -1 on failure + */ +size_t str_find_char(const str *s, char c); + +/** + * Finds a character c in s from the right to the left. + * Returns s->len on failure. + */ +size_t str_find_char_right(const str *s, char c); + +void str_print(const str *s); + +void str_println(const str *s); + +void str_fprint(const str *s, FILE *f); + +void str_fprintln(const str *s, FILE *f); + +/** + * Converts a str to a str_slc. + */ +str_slc str_slc_from_str(const str *s); + +/** + * Converts a C string to a str_slc. + */ +str_slc str_slc_from_cstr(const char *s); + +/** + * Equivalent to str_slc_from_cstr. + */ +str_slc mstrslc(const char *s); + +str str_slc_concat(const str_slc lhs, const str_slc rhs); + +str str_slc_concat_cstr(const str_slc lhs, const char *rhs); + +bool str_slc_equal(const str_slc lhs, const str_slc rhs); + +bool str_slc_equal_cstr(const str_slc lhs, const char *rhs); + +bool str_slc_equal_case_insensitive(const str_slc lhs, const str_slc rhs); + +bool str_slc_equal_cstr_case_insensitive(const str_slc lhs, const char *rhs); + +int str_slc_compare(const str_slc lhs, const str_slc rhs); + +int str_slc_compare_cstr(const str_slc lhs, const char *rhs); + +int str_slc_compare_case_insensitive(const str_slc lhs, const str_slc rhs); + +int str_slc_compare_cstr_case_insensitive(const str_slc lhs, const char *rhs); + +/** + * Slices a string slice from `begin` to `end`, clamping values to [0, src->len] + * if needed, and returning the result. + * ptrdiff_t's are used, as slicing functions may return negative values. + */ +str_slc str_slc_slice(const str_slc s, ptrdiff_t begin, ptrdiff_t end); + +/** + * Slices a string slice from `begin` to `end`, clamping values to [0, src->len] + * if needed, and returning the result. + * ptrdiff_t's are used, as slicing functions may return negative values. + */ +str str_slc_slice_to_str(const str_slc s, ptrdiff_t begin, ptrdiff_t end); + +str str_slc_to_lower(const str_slc s); + +str str_slc_to_upper(const str_slc s); + +str_slc str_slc_trim_left(const str_slc s); + +str_slc str_slc_trim_right(const str_slc s); + +str_slc str_slc_trim(const str_slc s); + +size_t str_slc_to_double_pro(const str_slc src, double *res); + +size_t str_slc_to_int64_pro(const str_slc src, int64_t *res, int base); + +bool str_slc_to_double(const str_slc src, double *res); + +bool str_slc_to_int64(const str_slc src, int64_t *res); + +bool str_slc_write_to_file(const str_slc src, FILE *f); + +char str_slc_first(const str_slc s); + +char str_slc_last(const str_slc s); + +char str_slc_at(const str_slc s, size_t i); + +void str_slc_print(const str_slc s); + +void str_slc_println(const str_slc s); + +void str_slc_fprint(const str_slc s, FILE *f); + +void str_slc_fprintln(const str_slc s, FILE *f); + +/** + * Finds a character c in s, from the left to the right. + * Returns -1 on failure + */ +ptrdiff_t str_slc_find_char(const str_slc s, char c); + +/** + * Finds a character c in s from the right to the left. + * Returns s->len on failure. + */ +ptrdiff_t str_slc_find_char_right(const str_slc s, char c); -#define str_fmt(slice) (int)((slice).len), (slice).data -// Usage: printf("%.*s", format_string(slice)); - -void print_slice(str_slc s); -str_slc slc_from_cstr(char* cstr); -#define slc_from_cstr(cstr) slc_from_cstr(cstr) -int slc_eq(str_slc a, str_slc b); -int slc_starts_with(str_slc slice, str_slc prefix); -str_slc slc_take(str_slc slice, size_t n); -str_slc slc_drop(str_slc slice, size_t n); -str_slc slc_trim(str_slc slice); -void slc_cat(str_slc first, str_slc second, str_slc *new_slc); -//#define slc_cat(first, second, new_slc) slc_cat(first, second, *new_slc) +str str_from_after_delim(str *arg, char delimiter); +str str_from_before_delim(str *arg, char delimiter); +str_slc str_slc_from_after_delim(str_slc arg, char delimiter); +str_slc str_slc_from_before_delim(str_slc arg, char delimiter); #endif -- cgit v1.2.3