# HG changeset patch # User Matti Hamalainen # Date 1288359668 -10800 # Node ID fe4d5f3b486cdbb59fdef47e04e70d4d07aefb95 # Parent 0a07138e75bc636c8330594db48fa864061310b5 Sync. diff -r 0a07138e75bc -r fe4d5f3b486c th_string.c --- a/th_string.c Fri Oct 29 10:58:39 2010 +0300 +++ b/th_string.c Fri Oct 29 16:41:08 2010 +0300 @@ -30,23 +30,7 @@ } -/* Allocate memory for a string with given length - */ -char *th_stralloc(const size_t l) -{ - assert(l > 0); - return th_malloc(sizeof(char) * l); -} - - -char *th_strrealloc(char * s, const size_t l) -{ - assert(l > 0); - return th_realloc(s, sizeof(char) * l); -} - - -char *th_strncpy(char * dst, const char * src, size_t n) +char *th_strncpy(char * dst, const char * src, const size_t n) { const char *s = src; char *d = dst; @@ -56,7 +40,7 @@ /* Copy to the destination */ i = n; - while (*s && (i > 0)) { + while (*s && i > 0) { *(d++) = *(s++); i--; } @@ -74,46 +58,142 @@ } -int th_strncmp(char * str1, char * str2, size_t n) +#ifdef STRDUP_PRINTF +/* + */ +enum { + TH_PAD_RIGHT = 1, + TH_PAD_ZERO = 2 +}; + + +static size_t th_printbuf_str(char **buf, const char *str, size_t width, int flags) +{ + size_t len = strlen(str); + char *out = (buf != NULL) ? *buf : NULL; + char pad = ' '; + + if (width > 0) { + width = (len >= width) ? 0 : width - len; + if (flags & TH_PAD_ZERO) + pad = '0'; + } + + if ((flags & TH_PAD_RIGHT) == 0 && out != NULL) { + while (width-- > 0) + *out++ = pad; + } + + if (out != NULL) { + while (*str) + *out++ = *str++; + } + + if (flags & TH_PAD_RIGHT && out != NULL) { + while (width-- > 0) + *out++ = pad; + } + + if (buf != NULL) + *buf = out; + + return len + width; +} + +#define TH_INTBUF_LEN (32) + +static size_t th_printbuf_int(char **buf, int i, int b, int sg, int width, int pad, int letbase) { - char *s1, *s2; + char tmpbuf[TH_INTBUF_LEN], *s; + int t, neg = 0, pc = 0; + unsigned int u = i; + + if (i == 0) { + tmpbuf[0] = '0'; + tmpbuf[1] = 0; + return th_printbuf_str(buf, tmpbuf, width, pad); + } + + if (sg && b == 10 && i < 0) { + neg = 1; + u = -i; + } + + s = tmpbuf + TH_INTBUF_LEN - 1; + *s = 0; + + while (u) { + t = u % b; + if (t >= 10) + t += letbase - '0' - 10; + + *--s = t + '0'; + u /= b; + } + + if (neg) { + if (width && (pad & PAD_ZERO)) { + printchar (out, '-'); + ++pc; + --width; + } else { + *--s = '-'; + } + } + + return pc + th_printbuf_str(buf, s, width, pad); +} + + +char * th_strdup_vprintf(const char *fmt, va_list args) +{ + const char *s = fmt; + char *res; + size_t len = 0; + + /* 1. Determine required space for final string */ + while (*s) { + if (*s == '%') { + s++; + } else { + s++; + len++; + } + } + + /* 2. Allocate space */ + + /* 3. Create final string */ + + return res; +} + + +char * th_strdup_printf(const char *fmt, ...) +{ + char *res; + va_list ap; + + va_start(ap, fmt); + res = th_strdup_vprintf(fmt, ap); + va_end(ap); + + return res; +} +#endif + +/* Compare two strings ignoring case [strcasecmp, strncasecmp] + */ +int th_strcasecmp(const char * str1, const char * str2) +{ + const char *s1 = str1, *s2 = str2; assert(str1 != NULL); assert(str2 != NULL); - /* Check the string pointers */ if (str1 == str2) return 0; - /* Go through the string */ - s1 = str1; - s2 = str2; - while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) { - s1++; - s2++; - n--; - } - - if (n > 0) - return ((*s1) - (*s2)); - else - return 0; -} - - -/* Compare two strings ignoring case [strcasecmp, strncasecmp] - */ -int th_strcasecmp(char * str1, char * str2) -{ - char *s1 = str1, *s2 = str2; - assert(str1 != NULL); - assert(str2 != NULL); - - /* Check the string pointers */ - if (str1 == str2) - return 0; - - /* Go through the string */ - while (*s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { + while (*s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { s1++; s2++; } @@ -122,27 +202,22 @@ } -int th_strncasecmp(char * str1, char * str2, size_t n) +int th_strncasecmp(const char * str1, const char * str2, size_t n) { - char *s1 = str1, *s2 = str2; + const char *s1 = str1, *s2 = str2; assert(str1 != NULL); assert(str2 != NULL); - /* Check the string pointers */ if (str1 == str2) return 0; - /* Go through the string */ - while ((n > 0) && *s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { + while (n > 0 && *s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { s1++; s2++; n--; } - if (n > 0) - return (th_tolower(*s1) - th_tolower(*s2)); - else - return 0; + return n > 0 ? (th_tolower(*s1) - th_tolower(*s2)) : 0; } @@ -168,45 +243,39 @@ /* Copy a given string over in *result. */ -int th_pstrcpy(char ** result, char * str) +int th_pstrcpy(char ** result, const char * str) { assert(result != NULL); - /* Check the string pointers */ if (str == NULL) return -1; - /* Allocate memory for destination */ th_free(*result); - *result = th_stralloc(strlen(str) + 1); - if (!*result) + if ((*result = th_malloc(strlen(str) + 1)) == NULL) return -2; - /* Copy to the destination */ strcpy(*result, str); - return 0; } /* Concatenates a given string into string pointed by *result. */ -int th_pstrcat(char ** result, char * str) +int th_pstrcat(char ** result, const char * str) { assert(result != NULL); - /* Check the string pointers */ if (str == NULL) return -1; if (*result != NULL) { - *result = th_strrealloc(*result, strlen(*result) + strlen(str) + 1); + *result = th_realloc(*result, strlen(*result) + strlen(str) + 1); if (*result == NULL) return -1; strcat(*result, str); } else { - *result = th_stralloc(strlen(str) + 1); + *result = th_malloc(strlen(str) + 1); if (*result == NULL) return -1; @@ -221,40 +290,40 @@ * Updates iPos into the position of such character and * returns pointer to the string. */ -char *th_findnext(char * str, size_t * iPos) +const char *th_findnext(const char * str, size_t * pos) { assert(str != NULL); /* Terminating NULL-character is not whitespace! */ - while (th_isspace(str[*iPos])) - (*iPos)++; - return &str[*iPos]; + while (th_isspace(str[*pos])) + (*pos)++; + return &str[*pos]; } -/* Find next chSep-character from string +/* Find next sep-character from string */ -char *th_findsep(char * str, size_t * iPos, char chSep) +const char *th_findsep(const char * str, size_t * pos, char sep) { assert(str != NULL); - /* Terminating NULL-character is not digit! */ - while (str[*iPos] && (str[*iPos] != chSep)) - (*iPos)++; - return &str[*iPos]; + while (str[*pos] && str[*pos] != sep) + (*pos)++; + + return &str[*pos]; } -/* Find next chSep- or whitespace from string +/* Find next sep- or whitespace from string */ -char *th_findseporspace(char * str, size_t * iPos, char chSep) +const char *th_findseporspace(const char * str, size_t * pos, char sep) { assert(str != NULL); - /* Terminating NULL-character is not digit! */ - while (!th_isspace(str[*iPos]) && (str[*iPos] != chSep)) - (*iPos)++; - return &str[*iPos]; + while (!th_isspace(str[*pos]) && str[*pos] != sep) + (*pos)++; + + return &str[*pos]; } @@ -263,10 +332,10 @@ * wildcards ? and *. "?" matches any character and "*" matches * any number of characters. */ -BOOL th_strmatch(char * str, char * pattern) +BOOL th_strmatch(const char * str, const char * pattern) { BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; - char *tmpPattern = NULL; + const char *tmpPattern = NULL; /* Check given pattern and string */ if (str == NULL || pattern == NULL) @@ -352,10 +421,10 @@ /* Compare a string to a pattern. Case-INSENSITIVE version. */ -BOOL th_strcasematch(char * str, char * pattern) +BOOL th_strcasematch(const char * str, const char * pattern) { BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; - char *tmpPattern = NULL; + const char *tmpPattern = NULL; /* Check given pattern and string */ if (str == NULL || pattern == NULL) diff -r 0a07138e75bc -r fe4d5f3b486c th_string.h --- a/th_string.h Fri Oct 29 10:58:39 2010 +0300 +++ b/th_string.h Fri Oct 29 16:41:08 2010 +0300 @@ -15,6 +15,7 @@ #include "th_util.h" #include #include +#include /* Macros */ @@ -41,23 +42,26 @@ /* Normal NUL-terminated string functions */ -char *th_stralloc(size_t); -char *th_strrealloc(char *, size_t); char *th_strncpy(char *, const char *, size_t); -int th_strcasecmp(char *, char *); -int th_strncasecmp(char *, char *, size_t); +int th_strcasecmp(const char *, const char *); +int th_strncasecmp(const char *, const char *, size_t); void th_strip_ctrlchars(char *); +#ifdef STRDUP_PRINTF +char *th_strdup_vprintf(const char *, va_list); +char *th_strdup_printf(const char *, ...); +#endif + char *th_strdup(const char *); -int th_pstrcpy(char **, char *); -int th_pstrcat(char **, char *); +int th_pstrcpy(char **, const char *); +int th_pstrcat(char **, const char *); -char *th_findnext(char *, size_t *); -char *th_findsep(char *, size_t *, char); -char *th_findseporspace(char *, size_t *, char); +const char *th_findnext(const char *, size_t *); +const char *th_findsep(const char *, size_t *, char); +const char *th_findseporspace(const char *, size_t *, char); -BOOL th_strmatch(char *, char *); -BOOL th_strcasematch(char *, char *); +BOOL th_strmatch(const char *, const char *); +BOOL th_strcasematch(const char *, const char *); #ifdef __cplusplus