andre@3: /* Copyright (C) 2015 by ETH Zürich andre@3: * Software engineering by Intevation GmbH andre@3: * andre@3: * This file is Free Software under the GNU GPL (v>=2) andre@3: * and comes with ABSOLUTELY NO WARRANTY! andre@3: * See LICENSE.txt for details. andre@3: */ andre@3: /* Needed to get asprintf */ andre@3: #define _GNU_SOURCE 1 andre@3: andre@3: /** @file See strhelp.h for documentation. */ andre@3: andre@3: #include andre@3: #include andre@3: #include andre@3: #include andre@3: #include andre@3: #include andre@3: #include andre@3: andre@3: #ifdef WIN32 andre@3: #include andre@3: #endif andre@3: andre@3: static void andre@3: out_of_core(void) andre@3: { andre@3: fputs("\nfatal: out of memory\n", stderr); andre@3: exit(2); andre@3: } andre@3: andre@3: void * andre@3: xmalloc( size_t n ) andre@3: { andre@3: void *p = malloc( n ); andre@3: if( !p ) andre@3: out_of_core(); andre@3: return p; andre@3: } andre@3: andre@3: void * andre@3: xmalloc0( size_t n ) andre@3: { andre@3: void *p = malloc( n ); andre@3: if( !p ) andre@3: out_of_core(); andre@3: memset (p, 0, n); andre@3: return p; andre@3: } andre@3: andre@3: void * andre@3: xrealloc( void *a, size_t n ) andre@3: { andre@3: void *p = realloc( a, n ); andre@3: if( !p ) andre@3: out_of_core(); andre@3: return p; andre@3: } andre@3: andre@3: char * andre@3: xstrndup( const char *string, const size_t len ) andre@3: { andre@3: char *p = xmalloc( len + 1 ); andre@3: memcpy( p, string, len ); andre@3: p[len] = '\0'; andre@3: return p; andre@3: } andre@3: andre@3: unsigned int andre@3: strv_length (char **str_array) andre@3: { andre@3: unsigned int i = 0; andre@3: andre@3: if (!str_array) andre@3: return 0; andre@3: andre@3: while (str_array[i]) andre@3: ++i; andre@3: andre@3: return i; andre@3: } andre@3: andre@3: void strv_append (char ***pArray, const char *string, const size_t len) andre@3: { andre@3: unsigned int old_len = 0; andre@3: andre@3: if (!*pArray) andre@3: { andre@3: *pArray = xmalloc(2 * sizeof(char*)); andre@3: (*pArray)[0] = xstrndup(string, len); andre@3: (*pArray)[1] = NULL; andre@3: return; andre@3: } andre@3: old_len = strv_length(*pArray); andre@3: *pArray = xrealloc(*pArray, sizeof(char**) * (old_len + 2)); andre@3: andre@3: (*pArray)[old_len] = xstrndup(string, len); andre@3: (*pArray)[old_len + 1] = NULL; andre@3: } andre@3: andre@3: void andre@3: str_append_str(char **pDst, size_t *dst_len, const char *appendage, const size_t len) andre@3: { andre@3: if (!appendage) andre@3: return; andre@3: andre@3: if (!(*pDst)) andre@3: { andre@3: *pDst = xstrndup(appendage, len); andre@3: *dst_len = len; andre@3: } andre@3: else andre@3: { andre@3: size_t new_size = (*dst_len) + len + 1; andre@3: char *p_old = *pDst; andre@3: *pDst = xmalloc(new_size); andre@3: strncpy(*pDst, p_old, *dst_len); andre@3: strncpy(*pDst + *dst_len, appendage, len); andre@3: *dst_len = new_size - 1; andre@3: (*pDst)[*dst_len] = '\0'; andre@3: free (p_old); andre@3: } andre@3: } andre@3: andre@3: void andre@3: strv_free (char **str_array) andre@3: { andre@3: if (str_array) andre@3: { andre@3: int i; andre@3: andre@3: for (i = 0; str_array[i] != NULL; i++) andre@3: free (str_array[i]); andre@3: andre@3: free (str_array); andre@3: } andre@3: } andre@3: andre@3: bool andre@3: str_equal (char *s1, char *s2) andre@3: { andre@3: size_t l1 = strlen(s1); andre@3: size_t l2 = strlen(s2); andre@3: if ((l1 == l2) && andre@3: (strcmp(s1, s2) == 0)) andre@3: return true; andre@3: else andre@3: return false; andre@3: } andre@3: andre@3: bool andre@3: str_starts_with (char *s1, char *s2) andre@3: { andre@3: size_t l2 = strlen(s2); andre@3: if (strncmp(s1, s2, l2) == 0) andre@3: return true; andre@3: else andre@3: return false; andre@3: } andre@3: andre@3: void andre@3: str_trim (char **s) andre@3: { andre@3: size_t i; andre@3: if (*s != NULL) andre@3: { andre@3: while (isspace(**s)) andre@3: (*s)++; andre@3: i = strlen(*s); andre@3: while (isspace((*s)[--i])) andre@3: (*s)[i] = '\0'; andre@3: } andre@3: } andre@3: andre@3: void andre@3: xfree (void *p) andre@3: { andre@3: if (p) andre@3: free (p); andre@3: } andre@3: andre@3: int andre@3: xasprintf (char **strp, const char *fmt, ...) andre@3: { andre@3: int ret; andre@3: va_list ap; andre@3: va_start(ap, fmt); andre@3: ret = vasprintf(strp, fmt, ap); andre@3: va_end(ap); andre@3: andre@3: if (ret == -1) andre@3: out_of_core(); andre@3: andre@3: return ret; andre@3: } andre@3: andre@3: #ifdef WIN32 andre@3: /* Adapted from GPGOL rev. e512053 */ andre@3: char * andre@3: wchar_to_utf8 (const wchar_t *string, size_t len) andre@3: { andre@3: int n, ilen; andre@3: char *result; andre@3: andre@3: ilen = (int) len; andre@3: if (ilen < 0) andre@3: return NULL; andre@3: andre@3: /* Note, that CP_UTF8 is not defined in Windows versions earlier andre@3: than NT.*/ andre@3: n = WideCharToMultiByte (CP_UTF8, 0, string, ilen, NULL, 0, NULL, NULL); andre@3: if (n < 0) andre@3: return NULL; andre@3: andre@3: result = xmalloc ((size_t)n+1); andre@3: n = WideCharToMultiByte (CP_UTF8, 0, string, ilen, result, n, NULL, NULL); andre@3: if (n < 0) andre@3: { andre@3: xfree (result); andre@3: return NULL; andre@3: } andre@3: result[n] = 0; andre@3: return result; andre@3: } andre@3: andre@3: /* Adapted from GPGOL rev. e512053 */ andre@3: wchar_t * andre@3: utf8_to_wchar (const char *string, size_t len) andre@3: { andre@3: int n, ilen; andre@3: wchar_t *result; andre@3: andre@3: ilen = (int) len; andre@3: if (ilen < 0) andre@3: return NULL; andre@3: andre@3: n = MultiByteToWideChar (CP_UTF8, 0, string, ilen, NULL, 0); andre@3: if (n < 0 || n + 1 < 0) andre@3: return NULL; andre@3: andre@3: result = xmalloc ((size_t)(n+1) * sizeof *result); andre@3: n = MultiByteToWideChar (CP_UTF8, 0, string, ilen, result, n); andre@3: if (n < 0) andre@3: { andre@3: xfree (result); andre@3: return NULL; andre@3: } andre@3: result[n] = 0; andre@3: return result; andre@3: } andre@3: andre@3: wchar_t andre@3: *acp_to_wchar (const char *string, size_t len) andre@3: { andre@3: int n, ilen; andre@3: wchar_t *result; andre@3: andre@3: ilen = (int) len; andre@3: if (ilen < 0) andre@3: return NULL; andre@3: andre@3: n = MultiByteToWideChar (CP_ACP, 0, string, ilen, NULL, 0); andre@3: if (n < 0 || n + 1 < 0) andre@3: return NULL; andre@3: andre@3: result = xmalloc ((size_t)(n+1) * sizeof *result); andre@3: n = MultiByteToWideChar (CP_ACP, 0, string, ilen, result, n); andre@3: if (n < 0) andre@3: { andre@3: xfree (result); andre@3: return NULL; andre@3: } andre@3: result[n] = 0; andre@3: return result; andre@3: } andre@3: #endif andre@3: