138 lines
3.5 KiB
C
138 lines
3.5 KiB
C
/**
|
|
* Copyright (c) 2025 Dominic Masters
|
|
*
|
|
* This software is released under the MIT License.
|
|
* https://opensource.org/licenses/MIT
|
|
*/
|
|
|
|
#include "string.h"
|
|
#include "assert/assert.h"
|
|
#include "util/memory.h"
|
|
|
|
bool_t stringIsWhitespace(const char_t c) {
|
|
return isspace(c);
|
|
}
|
|
|
|
void stringCopy(char_t *dest, const char_t *src, const size_t destSize) {
|
|
assertNotNull(dest, "dest must not be NULL");
|
|
assertNotNull(src, "src must not be NULL");
|
|
assertTrue(destSize > 0, "destSize must be greater than 0");
|
|
assertStrLenMax(src, destSize, "src is too long");
|
|
memoryCopy(dest, src, strlen(src) + 1);
|
|
}
|
|
|
|
int stringCompare(const char_t *str1, const char_t *str2) {
|
|
assertNotNull(str1, "str1 must not be NULL");
|
|
assertNotNull(str2, "str2 must not be NULL");
|
|
return strcmp(str1, str2);
|
|
}
|
|
|
|
void stringTrim(char_t *str) {
|
|
assertNotNull(str, "str must not be NULL");
|
|
|
|
// Trim leading whitespace
|
|
char_t *start = str;
|
|
while(stringIsWhitespace(*start)) start++;
|
|
|
|
// Trim trailing whitespace
|
|
char_t *end = start + strlen(start) - 1;
|
|
while (end >= start && stringIsWhitespace(*end)) end--;
|
|
|
|
// Null-terminate the string
|
|
*(end + 1) = '\0';
|
|
|
|
// Move trimmed string to the original buffer
|
|
if (start != str) memmove(str, start, end - start + 2);
|
|
}
|
|
|
|
char_t * stringToken(char_t *str, const char_t *delim) {
|
|
assertNotNull(str, "str must not be NULL");
|
|
assertNotNull(delim, "delim must not be NULL");
|
|
return strtok(str, delim);
|
|
}
|
|
|
|
int32_t stringFormat(
|
|
char_t *dest,
|
|
const size_t destSize,
|
|
const char_t *format,
|
|
...
|
|
) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
int32_t len = stringFormatVA(dest, destSize, format, args);
|
|
va_end(args);
|
|
return len;
|
|
}
|
|
|
|
int32_t stringFormatVA(
|
|
char_t *dest,
|
|
const size_t destSize,
|
|
const char_t *format,
|
|
const va_list args
|
|
) {
|
|
assertNotNull(format, "format must not be NULL");
|
|
|
|
if(dest == NULL) {
|
|
int32_t ret = vsnprintf(NULL, 0, format, args);
|
|
assertTrue(ret >= 0, "Failed to format string.");
|
|
return ret;
|
|
}
|
|
|
|
assertTrue(destSize > 0, "destSize must be greater than 0");
|
|
int32_t ret = vsnprintf(dest, destSize, format, args);
|
|
assertTrue(ret >= 0, "Failed to format string.");
|
|
assertTrue(ret < destSize, "Formatted string is too long.");
|
|
return ret;
|
|
}
|
|
|
|
bool_t stringToI32(const char_t *str, int32_t *out) {
|
|
assertNotNull(str, "str must not be NULL");
|
|
assertNotNull(out, "out must not be NULL");
|
|
|
|
char_t *endptr;
|
|
errno = 0;
|
|
long int result = strtol(str, &endptr, 10);
|
|
if (errno != 0 || *endptr != '\0') {
|
|
return false;
|
|
}
|
|
*out = (int32_t)result;
|
|
return true;
|
|
}
|
|
|
|
bool_t stringToI64(const char_t *str, int64_t *out) {
|
|
assertNotNull(str, "str must not be NULL");
|
|
assertNotNull(out, "out must not be NULL");
|
|
|
|
char_t *endptr;
|
|
errno = 0;
|
|
long long int result = strtoll(str, &endptr, 10);
|
|
if (errno != 0 || *endptr != '\0') {
|
|
return false;
|
|
}
|
|
*out = (int64_t)result;
|
|
return true;
|
|
}
|
|
|
|
bool_t stringToU16(const char_t *str, uint16_t *out) {
|
|
assertNotNull(str, "str must not be NULL");
|
|
assertNotNull(out, "out must not be NULL");
|
|
|
|
char_t *endptr;
|
|
errno = 0;
|
|
unsigned long int result = strtoul(str, &endptr, 10);
|
|
if (errno != 0 || *endptr != '\0' || result > UINT16_MAX) {
|
|
return false;
|
|
}
|
|
*out = (uint16_t)result;
|
|
return true;
|
|
}
|
|
|
|
bool_t stringEndsWith(const char_t *str, const char_t *suffix) {
|
|
assertNotNull(str, "str must not be NULL");
|
|
assertNotNull(suffix, "suffix must not be NULL");
|
|
|
|
size_t strLen = strlen(str);
|
|
size_t suffixLen = strlen(suffix);
|
|
if(suffixLen > strLen) return false;
|
|
return strcmp(str + strLen - suffixLen, suffix) == 0;
|
|
} |