Changeset: 02caa94c9823 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=02caa94c9823
Modified Files:
        monetdb5/modules/atoms/str.c
        monetdb5/modules/atoms/str.h
        monetdb5/modules/kernel/batstr.c
Branch: alloc-less-str
Log Message:

Cleaned strip2, ltrim2 and rtrim2 functions


diffs (truncated from 593 to 300 lines):

diff --git a/monetdb5/modules/atoms/str.c b/monetdb5/modules/atoms/str.c
--- a/monetdb5/modules/atoms/str.c
+++ b/monetdb5/modules/atoms/str.c
@@ -3211,16 +3211,29 @@ UTF8_offset(char *restrict s, int n)
 
 /* The batstr module functions use a single buffer to avoid malloc/free 
overhead.
    Note the buffer should be always large enough to hold null strings, so less 
testing will be required */
-#define CHECK_STR_BUFFER_LENGTH(buf, buflen, nextlen, op) \
+#define CHECK_STR_BUFFER_LENGTH(BUFFER, BUFFER_LEN, NEXT_LEN, OP) \
        do {  \
-               if (nextlen > *buflen) { \
-                       size_t newlen = nextlen + 1024; \
+               if (NEXT_LEN > *BUFFER_LEN) { \
+                       size_t newlen = NEXT_LEN + 1024; \
                        str newbuf = GDKmalloc(newlen); \
                        if (!newbuf) \
-                               throw(MAL, op, SQLSTATE(HY013) 
MAL_MALLOC_FAIL); \
-                       GDKfree(*buf); \
-                       *buf = newbuf; \
-                       *buflen = newlen; \
+                               throw(MAL, OP, SQLSTATE(HY013) 
MAL_MALLOC_FAIL); \
+                       GDKfree(*BUFFER); \
+                       *BUFFER = newbuf; \
+                       *BUFFER_LEN = newlen; \
+               } \
+       } while (0)
+
+#define CHECK_INT_BUFFER_LENGTH(BUFFER, BUFFER_LEN, NEXT_LEN, OP) \
+       do {  \
+               if (NEXT_LEN > *BUFFER_LEN) { \
+                       size_t newlen = NEXT_LEN + (1024 * sizeof(int)); \
+                       int *newbuf = GDKmalloc(newlen); \
+                       if (!newbuf) \
+                               throw(MAL, OP, SQLSTATE(HY013) 
MAL_MALLOC_FAIL); \
+                       GDKfree(*BUFFER); \
+                       *BUFFER = newbuf; \
+                       *BUFFER_LEN = newlen; \
                } \
        } while (0)
 
@@ -3942,110 +3955,183 @@ STRRtrim(str *res, const str *arg1)
 }
 
 /* return a list of codepoints in s */
-static int *
-trimchars(const char *s, size_t *n, size_t len_s)
+static str
+trimchars(int **chars, size_t *nchars, size_t *n, const char *s, size_t len_s, 
const char *malfunc)
 {
-       size_t len = 0;
-       int *chars = GDKmalloc(len_s * sizeof(int));
-       int c;
+       size_t len = 0, nlen = len_s * sizeof(int);
+       int c, *cbuf;
 
-       if (chars == NULL)
-               return NULL;
+       CHECK_INT_BUFFER_LENGTH(chars, nchars, nlen, malfunc);
+       cbuf = *chars;
 
        while (*s) {
                UTF8_GETCHAR(c, s);
                assert(!is_int_nil(c));
-               chars[len++] = c;
+               cbuf[len++] = c;
        }
        *n = len;
-       return chars;
-  illegal:
-       GDKfree(chars);
-       return NULL;
+       return MAL_SUCCEED;
+illegal:
+       throw(MAL, malfunc, SQLSTATE(42000) "Illegal Unicode code point");
+}
+
+str
+str_strip2(str *buf, size_t *buflen, int **chars, size_t *nchars, const char 
*s, const char *s2)
+{
+       str msg = MAL_SUCCEED;
+       size_t len, n, n2, n3;
+
+       if (strNil(s) || strNil(s2)) {
+               strcpy(*buf, str_nil);
+               return MAL_SUCCEED;
+       } else if ((n2 = strlen(s2)) == 0) {
+               len = strlen(s) + 1;
+               CHECK_STR_BUFFER_LENGTH(buf, buflen, len, "str.strip2");
+               strcpy(*buf, s);
+               return MAL_SUCCEED;
+       } else {
+               if ((msg = trimchars(chars, nchars, &n3, s2, n2, "str.strip2")) 
!= MAL_SUCCEED)
+                       return msg;
+               len = strlen(s);
+               n = lstrip(s, len, *chars, n3);
+               s += n;
+               len -= n;
+               n = rstrip(s, len, *chars, n3);
+
+               n++;
+               CHECK_STR_BUFFER_LENGTH(buf, buflen, n, "str.strip2");
+               strcpy_len(*buf, s, n);
+               return MAL_SUCCEED;
+       }
 }
 
 /* remove the longest string containing only characters from arg2 from
  * either side of arg1 */
-str
+static str
 STRStrip2(str *res, const str *arg1, const str *arg2)
 {
-       const char *s = *arg1;
-       size_t len, n, nchars, n2;
-       int *chars;
+       size_t buflen = INITIAL_STR_BUFFER_LENGTH, nchars = buflen * 
sizeof(int);
+       str buf = GDKmalloc(buflen), msg;
+       int *chars = GDKmalloc(nchars);
+
+       *res = NULL;
+       if (!buf || !chars) {
+               GDKfree(buf);
+               GDKfree(chars);
+               throw(SQL, "str.strip2", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+       }
+       msg = str_strip2(&buf, &buflen, &chars, &nchars, *arg1, *arg2);
+       if (!msg && !(*res = GDKstrdup(buf))) {
+               msg = createException(MAL, "str.strip2", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+       }
 
-       if (strNil(s) || strNil(*arg2)) {
-               *res = GDKstrdup(str_nil);
-       } else if ((n2 = strlen(*arg2)) == 0) {
-               *res = GDKstrdup(*arg1);
+       GDKfree(chars);
+       GDKfree(buf);
+       return msg;
+}
+
+str
+str_ltrim2(str *buf, size_t *buflen, int **chars, size_t *nchars, const char 
*s, const char *s2)
+{
+       str msg = MAL_SUCCEED;
+       size_t len, n, n2, n3, nallocate;
+
+       if (strNil(s) || strNil(s2)) {
+               strcpy(*buf, str_nil);
+               return MAL_SUCCEED;
+       } else if ((n2 = strlen(s2)) == 0) {
+               len = strlen(s) + 1;
+               CHECK_STR_BUFFER_LENGTH(buf, buflen, len, "str.ltrim2");
+               strcpy(*buf, s);
+               return MAL_SUCCEED;
        } else {
-               chars = trimchars(*arg2, &nchars, n2);
-               if (chars == NULL)
-                       throw(MAL, "str.trim", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+               if ((msg = trimchars(chars, nchars, &n3, s2, n2, "str.ltrim2")) 
!= MAL_SUCCEED)
+                       return msg;
                len = strlen(s);
-               n = lstrip(s, len, chars, nchars);
-               s += n;
-               len -= n;
-               n = rstrip(s, len, chars, nchars);
-               GDKfree(chars);
-               *res = GDKstrndup(s, n);
+               n = lstrip(s, len, *chars, n3);
+               nallocate = len - n + 1;
+
+               CHECK_STR_BUFFER_LENGTH(buf, buflen, nallocate, "str.ltrim2");
+               strcpy_len(*buf, s + n, nallocate);
+               return MAL_SUCCEED;
        }
-       if (*res == NULL)
-               throw(MAL, "str.trim", SQLSTATE(HY013) MAL_MALLOC_FAIL);
-       return MAL_SUCCEED;
 }
 
 /* remove the longest string containing only characters from arg2 from
  * the start (left) of arg1 */
-str
+static str
 STRLtrim2(str *res, const str *arg1, const str *arg2)
 {
-       const char *s = *arg1;
-       size_t len, n, nchars, n2;
-       int *chars;
+       size_t buflen = INITIAL_STR_BUFFER_LENGTH, nchars = buflen * 
sizeof(int);
+       str buf = GDKmalloc(buflen), msg;
+       int *chars = GDKmalloc(nchars);
+
+       *res = NULL;
+       if (!buf || !chars) {
+               GDKfree(buf);
+               GDKfree(chars);
+               throw(SQL, "str.ltrim2", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+       }
+       msg = str_ltrim2(&buf, &buflen, &chars, &nchars, *arg1, *arg2);
+       if (!msg && !(*res = GDKstrdup(buf))) {
+               msg = createException(MAL, "str.ltrim2", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+       }
 
-       if (strNil(s) || strNil(*arg2)) {
-               *res = GDKstrdup(str_nil);
-       } else if ((n2 = strlen(*arg2)) == 0) {
-               *res = GDKstrdup(*arg1);
+       GDKfree(chars);
+       GDKfree(buf);
+       return msg;
+}
+
+str
+str_rtrim2(str *buf, size_t *buflen, int **chars, size_t *nchars, const char 
*s, const char *s2)
+{
+       str msg = MAL_SUCCEED;
+       size_t len, n, n2, n3;
+
+       if (strNil(s) || strNil(s2)) {
+               strcpy(*buf, str_nil);
+               return MAL_SUCCEED;
+       } else if ((n2 = strlen(s2)) == 0) {
+               len = strlen(s) + 1;
+               CHECK_STR_BUFFER_LENGTH(buf, buflen, len, "str.rtrim2");
+               strcpy(*buf, s);
+               return MAL_SUCCEED;
        } else {
-               chars = trimchars(*arg2, &nchars, n2);
-               if (chars == NULL)
-                       throw(MAL, "str.trim", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+               if ((msg = trimchars(chars, nchars, &n3, s2, n2, "str.rtrim2")) 
!= MAL_SUCCEED)
+                       return msg;
                len = strlen(s);
-               n = lstrip(s, len, chars, nchars);
-               GDKfree(chars);
-               *res = GDKstrndup(s + n, len - n);
+               n = rstrip(s, len, *chars, n3);
+               n++;
+
+               CHECK_STR_BUFFER_LENGTH(buf, buflen, n, "str.rtrim2");
+               strcpy_len(*buf, s, n);
+               return MAL_SUCCEED;
        }
-       if (*res == NULL)
-               throw(MAL, "str.ltrim", SQLSTATE(HY013) MAL_MALLOC_FAIL);
-       return MAL_SUCCEED;
 }
 
 /* remove the longest string containing only characters from arg2 from
  * the end (right) of arg1 */
-str
+static str
 STRRtrim2(str *res, const str *arg1, const str *arg2)
 {
-       const char *s = *arg1;
-       size_t len, n, nchars, n2;
-       int *chars;
+       size_t buflen = INITIAL_STR_BUFFER_LENGTH, nchars = buflen * 
sizeof(int);
+       str buf = GDKmalloc(buflen), msg;
+       int *chars = GDKmalloc(nchars);
 
-       if (strNil(s) || strNil(*arg2)) {
-               *res = GDKstrdup(str_nil);
-       } else if ((n2 = strlen(*arg2)) == 0) {
-               *res = GDKstrdup(*arg1);
-       } else {
-               chars = trimchars(*arg2, &nchars, n2);
-               if (chars == NULL)
-                       throw(MAL, "str.trim", SQLSTATE(HY013) MAL_MALLOC_FAIL);
-               len = strlen(s);
-               n = rstrip(s, len, chars, nchars);
+       *res = NULL;
+       if (!buf || !chars) {
+               GDKfree(buf);
                GDKfree(chars);
-               *res = GDKstrndup(s, n);
+               throw(SQL, "str.rtrim2", SQLSTATE(HY013) MAL_MALLOC_FAIL);
        }
-       if (*res == NULL)
-               throw(MAL, "str.rtrim", SQLSTATE(HY013) MAL_MALLOC_FAIL);
-       return MAL_SUCCEED;
+       msg = str_rtrim2(&buf, &buflen, &chars, &nchars, *arg1, *arg2);
+       if (!msg && !(*res = GDKstrdup(buf))) {
+               msg = createException(MAL, "str.rtrim2", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+       }
+
+       GDKfree(chars);
+       GDKfree(buf);
+       return msg;
 }
 
 static char *
@@ -4179,7 +4265,7 @@ str_substitute(str *buf, size_t *buflen,
                strcpy(*buf, str_nil);
                return MAL_SUCCEED;
        } else {
-               size_t lsrc = strlen(src), ldst = strlen(dst), n, l = strLen(s);
+               size_t lsrc = strlen(src), ldst = strlen(dst), n, l = strlen(s);
                char *b, *fnd;
                const char *pfnd;
 
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to