Mercurial > libanimone
view src/util.cc @ 31:668f4f31ddda
strategist: outward APIs are now in C
author | Paper <paper@tflc.us> |
---|---|
date | Mon, 10 Feb 2025 00:07:21 -0500 |
parents | a76e55e098d1 |
children |
line wrap: on
line source
#include "animone/util.h" #include <string.h> #include <regex> // FIXME use a C library for this int animone_internal_util_ReadFile(const char *path, char **data, size_t *size) { // whatever size_t sz_local; if (!size) size = &sz_local; FILE *f = fopen(path, "r"); if (!f) return 0; fseek(f, 0, SEEK_END); long end = ftell(f); if (end < 0) return 0; fseek(f, 0, SEEK_SET); *size = end; if (data) { // add a NUL terminator anyway *data = (char *)malloc(end + 1); if (!*data) { *size = 0; return 0; } *size = fread(*data, 1, *size, f); (*data)[*size] = '\0'; } return 1; } static inline unsigned char _animone_internal_tolower(unsigned char c) { return (c >= 'A' && c <= 'Z') ? (c | 0x20) : c; } /* this is, in essence, strcasecmp. */ int animone_internal_util_EqualStrings(const char *str1, const char *str2) { unsigned char c1, c2; do { c1 = _animone_internal_tolower(*str1++); c2 = _animone_internal_tolower(*str2++); } while (c1 == c2 && c1); return !!(c1 - c2); } char *animone_internal_Stem(const char *filename) { const char *ptr = strrchr(filename, '.'); if (!ptr) return NULL; size_t len = ptr - filename; char *stem = (char *)malloc(len + 1); if (!stem) return NULL; memcpy(stem, filename, len); stem[len] = '\0'; return stem; } int animone_internal_util_CheckPattern(const char *pattern, const char *str) { switch (*pattern) { case '\0': return 0; case '^': // FIXME: Convert to C if (std::regex_match(std::string(str), std::regex(pattern))) return 1; default: break; } return animone_internal_util_EqualStrings(pattern, str); } /* Modifies `str` inplace */ int animone_internal_util_TrimLeft(char *str, const char* chars) { if (!str || !*str) return 0; const size_t found = strcspn(str, chars); const size_t len = strlen(str); if (found == len) return 1; // nothing to do memmove(str, str + found, len - found); str[len - found] = '\0'; return 1; } // reverse version of strcspn static inline size_t _animone_internal_strrcspn(const char *str1, const char *str2) { const size_t str1len = strlen(str1); ptrdiff_t i; /* FIXME: this should be using size_t */ for (i = str1len - 1; i >= 0; i--) { size_t found = strcspn(str1 + i, str2); if (found != str1len - i) return i; } return str1len; } int animone_internal_util_TrimRight(char *str, const char* chars) { if (!str || !*str) return 0; // We can get away without really moving memory around here. // The old version simply used std::string::find_last_not_of, // which I'm fairly sure isn't the intention of this function // (for example find_last_not_of("gb ") returns "gb "). const size_t found = _animone_internal_strrcspn(str, chars); str[found] = '\0'; return 1; }