325 lines
7.6 KiB
C
325 lines
7.6 KiB
C
#include "str.h"
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "cstr.h"
|
|
|
|
#define STR_MIN_ALLOC 64 /* minimum allocation size for string data */
|
|
|
|
/**
|
|
* initialize a str_t string and allocte some memory for the data
|
|
*
|
|
* @return a new, empty str_t instance
|
|
*/
|
|
str_t
|
|
str_new (void)
|
|
{
|
|
str_t str;
|
|
|
|
str.str = smalloc (STR_MIN_ALLOC * sizeof (char));
|
|
str.str[0] = '\0';
|
|
str.len = 0;
|
|
str.cap = STR_MIN_ALLOC;
|
|
|
|
return str;
|
|
}
|
|
|
|
/**
|
|
* initialize a str_t string with a given capacity (allocation size). can be
|
|
* used in oder to reduce the amount of calls to `realloc()`.
|
|
*
|
|
* @param want_cap: the minimum wanted capacity
|
|
*
|
|
* @return a new, empty str_t instance with given capacity.
|
|
*/
|
|
str_t
|
|
str_new_cap (usize want_cap)
|
|
{
|
|
usize cap;
|
|
str_t str;
|
|
|
|
cap = max (next_pow_of_two (want_cap), STR_MIN_ALLOC);
|
|
str.str = smalloc (cap);
|
|
str.str[0] = '\0';
|
|
str.len = 0;
|
|
str.cap = cap;
|
|
|
|
return str;
|
|
}
|
|
|
|
/**
|
|
* initialize a str_t string with a given data. the data will be copied into
|
|
* the string.
|
|
*
|
|
* @param src: the data to put into the string
|
|
*
|
|
* @return a new, empty str_t with given data.
|
|
*/
|
|
inline str_t
|
|
str_new_from (const char src[static 1])
|
|
{
|
|
return str_new_from_len (strlen (src), src);
|
|
}
|
|
|
|
/**
|
|
* initialize a str_t string with a given data. the data will be copied into
|
|
* the string. the length of the data is provided as a parameter.
|
|
*
|
|
* @param src: the data to put into the string
|
|
* @param len: the length of `src`. undefined behaviour occurs if `len !=
|
|
* strlen (src)`
|
|
*
|
|
* @return a new, empty str_t with given data.
|
|
*/
|
|
str_t
|
|
str_new_from_len (usize len, const char src[restrict len])
|
|
{
|
|
usize cap;
|
|
str_t str;
|
|
|
|
cap = max (next_pow_of_two (len + 1), STR_MIN_ALLOC);
|
|
str.str = smalloc (cap * sizeof (char));
|
|
str.len = len;
|
|
str.cap = cap;
|
|
strncpy (str.str, src, len);
|
|
str.str[len] = '\0';
|
|
|
|
return str;
|
|
}
|
|
|
|
/**
|
|
* clone the contents of a str_t string into a new str_t string.
|
|
*
|
|
* @param orig: the original str_t string
|
|
*
|
|
* @return a new str_t instance with the same data as `str`
|
|
*/
|
|
inline str_t
|
|
str_clone (const str_t orig[static 1])
|
|
{
|
|
return str_new_from_len (orig->len, orig->str);
|
|
}
|
|
|
|
/**
|
|
* free the contents of a str_t string.
|
|
*
|
|
* @param str: a pointer to the string to free
|
|
*/
|
|
inline void
|
|
str_free (str_t *str)
|
|
{
|
|
if (str)
|
|
free (str->str);
|
|
}
|
|
|
|
/**
|
|
* append a string to the end of a str_t string.
|
|
*
|
|
* @param str: the str_t string to append to
|
|
* @param src: the cstring to append
|
|
*/
|
|
inline void
|
|
str_append (str_t str[static 1], const char src[static 1])
|
|
{
|
|
str_append_len (str, strlen (src), src);
|
|
}
|
|
|
|
/**
|
|
* append a string to the end of a str_t string. the length of the appended
|
|
* string is provided as a parameter.
|
|
*
|
|
* @param str: the str_t string to append to
|
|
* @param src: the cstring to append
|
|
* @param len: the length of `src`. undefined behaviour occurs if `len !=
|
|
* strlen (src)`
|
|
*/
|
|
void
|
|
str_append_len (str_t str[static 1], usize len, const char src[restrict len])
|
|
{
|
|
str_resize (str, str->len + len + 1);
|
|
strncpy (str->str + str->len, src, len);
|
|
str->len += len;
|
|
str->str[str->len] = '\0';
|
|
}
|
|
|
|
/**
|
|
* compare a str_t string with a cstring.
|
|
*
|
|
* @param str: the str_t string to compare
|
|
* @param s2: the cstring to compare
|
|
*
|
|
* @return integer less than, equal to, or greater than zero if str is found
|
|
* to be less than, to match, or to be greater than s2
|
|
*/
|
|
inline int
|
|
str_cmp (const str_t str[static 1], const char *s2)
|
|
{
|
|
return strcmp (str->str, s2);
|
|
}
|
|
|
|
/**
|
|
* check if a str_t string equals a cstring.
|
|
*
|
|
* @param str: the str_t string to compare
|
|
* @param s2: the cstring to compare
|
|
*
|
|
* @return true if str equals s2, else false
|
|
*/
|
|
inline bool
|
|
str_eq (const str_t str[static 1], const char *s2)
|
|
{
|
|
return str_cmp (str, s2) == 0;
|
|
}
|
|
|
|
/**
|
|
* check if a str_t string starts with a cstring.
|
|
*
|
|
* @param str: the str_t string to search in
|
|
* @param find: the cstring to search for
|
|
*
|
|
* @return true if `str` starts with `find`, else false
|
|
*/
|
|
inline bool
|
|
str_starts_with (const str_t str[static 1], const char find[static 1])
|
|
{
|
|
return str_starts_with_len (str, strlen (find), find);
|
|
}
|
|
|
|
/**
|
|
* check if a str_t string starts with a cstring of given length.
|
|
*
|
|
* @param str: the str_t string to search in
|
|
* @param find: the cstring to search for
|
|
* @param len: the length of `find`. undefined behaviour occurs if `len !=
|
|
* strlen (src)`
|
|
*
|
|
* @return true if `str` starts with `find`, else false
|
|
*/
|
|
inline bool
|
|
str_starts_with_len (const str_t str[static 1], usize len,
|
|
const char find[restrict len])
|
|
{
|
|
return strncmp (str->str, find, len) == 0;
|
|
}
|
|
|
|
/**
|
|
* check if a str_t string ends with a cstring.
|
|
*
|
|
* @param str: the str_t string to search in
|
|
* @param find: the cstring to search for
|
|
*
|
|
* @return true if `str` ends with `find`, else false
|
|
*/
|
|
inline bool
|
|
str_ends_with (const str_t str[static 1], const char find[static 1])
|
|
{
|
|
return str_ends_with_len (str, strlen (find), find);
|
|
}
|
|
|
|
/**
|
|
* check if a str_t string ends with a cstring of given length.
|
|
*
|
|
* @param str: the str_t string to search in
|
|
* @param find: the cstring to search for
|
|
* @param len: the length of `find`. undefined behaviour occurs if `len !=
|
|
* strlen (src)`
|
|
*
|
|
* @return true if `str` ends with `find`, else false
|
|
*/
|
|
inline bool
|
|
str_ends_with_len (const str_t str[static 1], usize len,
|
|
const char find[restrict len])
|
|
{
|
|
return strcmp (str->str + str->len - len, find) == 0;
|
|
}
|
|
|
|
/**
|
|
* find a substring in a str_t string. a pointer to the beginning of the
|
|
* substring is returned.
|
|
*
|
|
* @param str: the str_t string to search in
|
|
* @param find: the cstring to search for
|
|
*
|
|
* @return beginning of found substring as pointer, or nullptr if not found
|
|
*/
|
|
inline char *
|
|
str_find (const str_t str[static 1], const char *find)
|
|
{
|
|
return strstr (str->str, find);
|
|
}
|
|
|
|
/**
|
|
* find a substring in a str_t string. the starting index of the substring is
|
|
* returned.
|
|
*
|
|
* @param str: the str_t string to search in
|
|
* @param find: the cstring to search for
|
|
*
|
|
* @return beginning of found substring as string index, or -1 if not found
|
|
*/
|
|
isize
|
|
str_pos (const str_t str[static 1], const char *find)
|
|
{
|
|
char *pos;
|
|
|
|
pos = str_find (str, find);
|
|
if (pos)
|
|
return pos - str->str;
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* check if a string only consists of whitespace characters. whitespaces
|
|
* include the following characters: ' ', '\n', '\r', '\t', '\v', '\f'.
|
|
*
|
|
* @param str: the string to check
|
|
*
|
|
* @return true if the string only consists of whitespace characters, or false
|
|
* if other characters are present. false in case of error.
|
|
*/
|
|
inline bool
|
|
str_is_blank (const str_t str[static 1])
|
|
{
|
|
return strisblank (str->str);
|
|
}
|
|
|
|
/**
|
|
* transform all uppercase characters in a str_t string to lowercase
|
|
* characters. this will modify the string data.
|
|
*
|
|
* @param str: the string to modify
|
|
*/
|
|
inline void
|
|
str_downcase (str_t str[static 1])
|
|
{
|
|
strdowncase (str->str);
|
|
}
|
|
|
|
/**
|
|
* transform all lowercase characters in a str_t string to uppercase
|
|
* characters. this will modify the string data.
|
|
*
|
|
* @param str: the string to modify
|
|
*/
|
|
inline void
|
|
str_upcase (str_t str[static 1])
|
|
{
|
|
strupcase (str->str);
|
|
}
|
|
|
|
/**
|
|
* resize the allocated data of a str_t string.
|
|
*
|
|
* @param str: the string to expand
|
|
* @param cap: the minimum amount of capacity to resize to
|
|
*/
|
|
void
|
|
str_resize (str_t str[static 1], usize cap)
|
|
{
|
|
cap = max (next_pow_of_two (cap), STR_MIN_ALLOC);
|
|
if (cap > str->len && cap != str->cap) {
|
|
str->str = srealloc (str->str, cap * sizeof (char));
|
|
str->cap = cap;
|
|
}
|
|
}
|