/** * 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; }