Mercurial > hg > dmlib
view src/dmstring.c @ 2208:90ec1ec89c56
Revamp the palette handling in lib64gfx somewhat, add helper functions to
lib64util for handling external palette file options and add support for
specifying one of the "internal" palettes or external (.act) palette file to
gfxconv and 64vw.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 14 Jun 2019 05:01:12 +0300 |
parents | 9b6027d51f76 |
children | 63dd0a611586 |
line wrap: on
line source
#include "dmlib.h" #include <stdarg.h> /* Compare two strings ignoring case [strcasecmp, strncasecmp] */ int dm_strcasecmp(const char *haystack, const char *needle) { const char *s1 = haystack, *s2 = needle; assert(haystack != NULL); assert(needle != NULL); if (haystack == needle) return 0; while (*s1 && *s2) { int k = tolower(*s1) - tolower(*s2); if (k != 0) return k; s1++; s2++; } return 0; } int dm_strncasecmp(const char *haystack, const char *needle, size_t n) { const char *s1 = haystack, *s2 = needle; assert(haystack != NULL); assert(needle != NULL); if (haystack == needle) return 0; while (n > 0 && *s1 && *s2) { int k = tolower(*s1) - tolower(*s2); if (k != 0) return k; s1++; s2++; n--; } return 0; } /* Check if end of the given string str matches needle * case-insensitively, return pointer to start of the match, * if found, NULL otherwise. */ char *dm_strrcasecmp(char *str, const char *needle) { if (str == NULL || needle == NULL) return NULL; const size_t slen = strlen(str), nlen = strlen(needle); if (slen < nlen) return NULL; if (dm_strcasecmp(str + slen - nlen, needle) == 0) return str + slen - nlen; else return NULL; } /* Implementation of strdup() with a NULL check */ char *dm_strdup(const char *s) { char *res; if (s == NULL) return NULL; if ((res = dmMalloc(strlen(s) + 1)) == NULL) return NULL; strcpy(res, s); return res; } /* Implementation of strndup() with NULL check */ char *dm_strndup(const char *str, const size_t n) { char *res; if (str == NULL) return NULL; size_t len = strlen(str); if (len > n) len = n; if ((res = dmMalloc(len + 1)) == NULL) return NULL; memcpy(res, str, len); res[len] = 0; return res; } /* Like strdup, but trims whitespace from the string according to specified flags. * See DM_TRIM_* in dmlib.h. If the resulting string would be empty (length 0), * NULL is returned. */ static char * dm_strdup_trim_do(const char *src, size_t len, const int flags) { char *res; size_t start, end; if (len == 0) return NULL; // Trim start: find first non-whitespace character if (flags & DM_TRIM_START) for (start = 0; start < len && isspace(src[start]); start++); else start = 0; // Trim end: find last non-whitespace character if (flags & DM_TRIM_END) for (end = len - 1; end > start && isspace(src[end]); end--); else end = len; // Allocate memory for result if (src[end] == 0 || isspace(src[end])) return NULL; len = end - start + 1; if ((res = dmMalloc(len + 1)) == NULL) return NULL; memcpy(res, src + start, len); res[len] = 0; return res; } char *dm_strdup_trim(const char *src, const int flags) { if (src == NULL) return NULL; return dm_strdup_trim_do(src, strlen(src), flags); } char *dm_strndup_trim(const char *src, const size_t n, const int flags) { size_t len; if (src == NULL || n == 0) return NULL; for (len = 0; len < n && src[len]; len++); return dm_strdup_trim_do(src, len, flags); } /* Simulate a sprintf() that allocates memory */ char *dm_strdup_vprintf_len(const char *fmt, va_list args, int *len) { int size = 64; char *buf, *tmp; if ((buf = dmMalloc(size)) == NULL) return NULL; while (1) { va_list ap; va_copy(ap, args); *len = vsnprintf(buf, size, fmt, ap); va_end(ap); if (*len > -1 && *len < size) return buf; if (*len > -1) size = *len + 1; else size *= 2; if ((tmp = dmRealloc(buf, size)) == NULL) { dmFree(buf); return NULL; } else buf = tmp; } } char *dm_strdup_vprintf(const char *fmt, va_list args) { int len; return dm_strdup_vprintf_len(fmt, args, &len); } char *dm_strdup_printf(const char *fmt, ...) { int len; char *res; va_list ap; va_start(ap, fmt); res = dm_strdup_vprintf_len(fmt, ap, &len); va_end(ap); return res; }