Changeset: 408ffc04da87 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=408ffc04da87
Modified Files:
monetdb5/modules/atoms/str.c
monetdb5/modules/atoms/str.h
monetdb5/modules/kernel/batstr.c
Branch: alloc-less-str
Log Message:
Cleaned lpad, rpad, lpad2 and rpad2
diffs (truncated from 971 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
@@ -4134,30 +4134,38 @@ STRRtrim2(str *res, const str *arg1, con
return msg;
}
-static char *
-pad(const char *s, const char *pad, int len, int left)
+static str
+pad(str *buf, size_t *buflen, const char *s, const char *pad, int len, int
left, const char *malfunc)
{
- size_t slen, padlen, repeats, residual, i;
+ size_t slen, padlen, repeats, residual, i, nlen;
char *res;
- if (strNil(s) || strNil(pad) || is_int_nil(len))
- return GDKstrdup(str_nil);
+ if (strNil(s) || strNil(pad) || is_int_nil(len)) {
+ strcpy(*buf, str_nil);
+ return MAL_SUCCEED;
+ }
if (len < 0)
len = 0;
slen = UTF8_strlen(s);
-
if (slen > (size_t) len) {
/* truncate */
pad = UTF8_strtail(s, len);
- return GDKstrndup(s, pad - s);
+ slen = pad - s + 1;
+
+ CHECK_STR_BUFFER_LENGTH(buf, buflen, slen, malfunc);
+ strcpy_len(*buf, s, slen);
+ return MAL_SUCCEED;
}
padlen = UTF8_strlen(pad);
if (slen == (size_t) len || padlen == 0) {
/* nothing to do (no padding if there is no pad string) */
- return GDKstrdup(s);
+ slen = strlen(s) + 1;
+ CHECK_STR_BUFFER_LENGTH(buf, buflen, slen, malfunc);
+ strcpy(*buf, s);
+ return MAL_SUCCEED;
}
repeats = ((size_t) len - slen) / padlen;
@@ -4166,9 +4174,10 @@ pad(const char *s, const char *pad, int
residual = (size_t) (UTF8_strtail(pad, (int) residual) - pad);
padlen = strlen(pad);
slen = strlen(s);
- res = GDKmalloc(slen + repeats * padlen + residual + 1);
- if (res == NULL)
- return NULL;
+
+ nlen = slen + repeats * padlen + residual + 1;
+ CHECK_STR_BUFFER_LENGTH(buf, buflen, nlen, malfunc);
+ res = *buf;
if (left) {
for (i = 0; i < repeats; i++)
memcpy(res + i * padlen, pad, padlen);
@@ -4185,7 +4194,13 @@ pad(const char *s, const char *pad, int
memcpy(res + slen + repeats * padlen, pad, residual);
}
res[repeats * padlen + residual + slen] = 0;
- return res;
+ return MAL_SUCCEED;
+}
+
+str
+str_lpad(str *buf, size_t *buflen, const char *s, int len)
+{
+ return pad(buf, buflen, s, " ", len, 1, "str.lpad");
}
/* Fill up 'arg1' to length 'len' by prepending whitespaces.
@@ -4195,13 +4210,28 @@ pad(const char *s, const char *pad, int
* Example: lpad('hi', 5)
* Result: ' hi'
*/
-str
+static str
STRLpad(str *res, const str *arg1, const int *len)
{
- *res = pad(*arg1, " ", *len, 1);
- if (*res == NULL)
- throw(MAL, "str.lpad", SQLSTATE(HY013) MAL_MALLOC_FAIL);
- return MAL_SUCCEED;
+ size_t buflen = INITIAL_STR_BUFFER_LENGTH;
+ str buf = GDKmalloc(buflen), msg;
+
+ *res = NULL;
+ if (!buf)
+ throw(SQL, "str.lpad", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ msg = str_lpad(&buf, &buflen, *arg1, *len);
+ if (!msg && !(*res = GDKstrdup(buf))) {
+ msg = createException(MAL, "str.lpad", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+
+ GDKfree(buf);
+ return msg;
+}
+
+str
+str_rpad(str *buf, size_t *buflen, const char *s, int len)
+{
+ return pad(buf, buflen, s, " ", len, 0, "str.lpad");
}
/* Fill up 'arg1' to length 'len' by appending whitespaces.
@@ -4211,13 +4241,28 @@ STRLpad(str *res, const str *arg1, const
* Example: rpad('hi', 5)
* Result: 'hi '
*/
-str
+static str
STRRpad(str *res, const str *arg1, const int *len)
{
- *res = pad(*arg1, " ", *len, 0);
- if (*res == NULL)
- throw(MAL, "str.rpad", SQLSTATE(HY013) MAL_MALLOC_FAIL);
- return MAL_SUCCEED;
+ size_t buflen = INITIAL_STR_BUFFER_LENGTH;
+ str buf = GDKmalloc(buflen), msg;
+
+ *res = NULL;
+ if (!buf)
+ throw(SQL, "str.rpad", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ msg = str_rpad(&buf, &buflen, *arg1, *len);
+ if (!msg && !(*res = GDKstrdup(buf))) {
+ msg = createException(MAL, "str.rpad", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+
+ GDKfree(buf);
+ return msg;
+}
+
+str
+str_lpad2(str *buf, size_t *buflen, const char *s, int len, const char *s2)
+{
+ return pad(buf, buflen, s, s2, len, 1, "str.lpad2");
}
/* Fill up 'arg1' to length 'len' by prepending characters from 'arg2'
@@ -4227,16 +4272,28 @@ STRRpad(str *res, const str *arg1, const
* Example: lpad('hi', 5, 'xy')
* Result: xyxhi
*/
-str
+static str
STRLpad2(str *res, const str *arg1, const int *len, const str *arg2)
{
- if (**arg2 == 0)
- throw(MAL, "str.lpad", SQLSTATE(42000) ILLEGAL_ARGUMENT ": pad
string is empty");
+ size_t buflen = INITIAL_STR_BUFFER_LENGTH;
+ str buf = GDKmalloc(buflen), msg;
- *res = pad(*arg1, *arg2, *len, 1);
- if (*res == NULL)
- throw(MAL, "str.lpad", SQLSTATE(HY013) MAL_MALLOC_FAIL);
- return MAL_SUCCEED;
+ *res = NULL;
+ if (!buf)
+ throw(SQL, "str.lpad2", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ msg = str_lpad2(&buf, &buflen, *arg1, *len, *arg2);
+ if (!msg && !(*res = GDKstrdup(buf))) {
+ msg = createException(MAL, "str.lpad2", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+
+ GDKfree(buf);
+ return msg;
+}
+
+str
+str_rpad2(str *buf, size_t *buflen, const char *s, int len, const char *s2)
+{
+ return pad(buf, buflen, s, s2, len, 0, "str.rpad2");
}
/* Fill up 'arg1' to length 'len' by appending characters from 'arg2'
@@ -4246,16 +4303,22 @@ STRLpad2(str *res, const str *arg1, cons
* Example: rpad('hi', 5, 'xy')
* Result: hixyx
*/
-str
+static str
STRRpad2(str *res, const str *arg1, const int *len, const str *arg2)
{
- if (**arg2 == 0)
- throw(MAL, "str.rpad", SQLSTATE(42000) ILLEGAL_ARGUMENT ": pad
string is empty");
+ size_t buflen = INITIAL_STR_BUFFER_LENGTH;
+ str buf = GDKmalloc(buflen), msg;
- *res = pad(*arg1, *arg2, *len, 0);
- if (*res == NULL)
- throw(MAL, "str.rpad", SQLSTATE(HY013) MAL_MALLOC_FAIL);
- return MAL_SUCCEED;
+ *res = NULL;
+ if (!buf)
+ throw(SQL, "str.rpad2", SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ msg = str_rpad2(&buf, &buflen, *arg1, *len, *arg2);
+ if (!msg && !(*res = GDKstrdup(buf))) {
+ msg = createException(MAL, "str.rpad2", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ }
+
+ GDKfree(buf);
+ return msg;
}
str
diff --git a/monetdb5/modules/atoms/str.h b/monetdb5/modules/atoms/str.h
--- a/monetdb5/modules/atoms/str.h
+++ b/monetdb5/modules/atoms/str.h
@@ -42,6 +42,10 @@ extern str str_rtrim(str *buf, size_t *b
extern str str_strip2(str *buf, size_t *buflen, int **chars, size_t *nchars,
const char *s, const char *s2);
extern str str_ltrim2(str *buf, size_t *buflen, int **chars, size_t *nchars,
const char *s, const char *s2);
extern str str_rtrim2(str *buf, size_t *buflen, int **chars, size_t *nchars,
const char *s, const char *s2);
+extern str str_lpad(str *buf, size_t *buflen, const char *s, int len);
+extern str str_rpad(str *buf, size_t *buflen, const char *s, int len);
+extern str str_lpad2(str *buf, size_t *buflen, const char *s, int len, const
char *s2);
+extern str str_rpad2(str *buf, size_t *buflen, const char *s, int len, const
char *s2);
extern int str_search(const char *s, const char *s2);
extern int str_reverse_str_search(const char *s, const char *s2);
@@ -51,9 +55,4 @@ extern str str_splitpart(str *buf, size_
extern str str_insert(str *buf, size_t *buflen, const char *s, int strt, int
l, const char *s2);
extern str str_substitute(str *buf, size_t *buflen, const char *s, const char
*src, const char *dst, bit repeat);
-mal_export str STRLpad(str *res, const str *arg1, const int *len);
-mal_export str STRRpad(str *res, const str *arg1, const int *len);
-mal_export str STRLpad2(str *res, const str *arg1, const int *len, const str
*arg2);
-mal_export str STRRpad2(str *res, const str *arg1, const int *len, const str
*arg2);
-
#endif /* __string_H__ */
diff --git a/monetdb5/modules/kernel/batstr.c b/monetdb5/modules/kernel/batstr.c
--- a/monetdb5/modules/kernel/batstr.c
+++ b/monetdb5/modules/kernel/batstr.c
@@ -346,7 +346,7 @@ do_batstr_conststr_str(bat *res, const b
BATiter bi;
BAT *bn = NULL, *b = NULL;
BUN p, q;
- size_t buflen = INITIAL_STR_BUFFER_LENGTH, nchars = buflen *
sizeof(int);;
+ size_t buflen = INITIAL_STR_BUFFER_LENGTH, nchars = buflen *
sizeof(int);
str x, y = *s2, buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
int *chars = GDKmalloc(nchars);
bool nils = false;
@@ -405,7 +405,7 @@ do_batstr_batstr_str(bat *res, const bat
BATiter lefti, righti;
BAT *bn = NULL, *left = NULL, *right = NULL;
BUN p, q;
- size_t buflen = INITIAL_STR_BUFFER_LENGTH, nchars = buflen *
sizeof(int);;
+ size_t buflen = INITIAL_STR_BUFFER_LENGTH, nchars = buflen *
sizeof(int);
str x, y, buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
int *chars = GDKmalloc(nchars);
bool nils = false;
@@ -418,6 +418,10 @@ do_batstr_batstr_str(bat *res, const bat
msg = createException(MAL, name, SQLSTATE(HY005)
RUNTIME_OBJECT_MISSING);
goto bailout;
}
+ if (BATcount(left) != BATcount(right)) {
+ msg = createException(MAL, name, ILLEGAL_ARGUMENT " Requires
bats of identical size");
+ goto bailout;
+ }
q = BATcount(left);
if (!(bn = COLnew(left->hseqbase, TYPE_str, q, TRANSIENT))) {
msg = createException(MAL, name, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
@@ -463,332 +467,383 @@ bailout:
* Output type: str (a BAT of strings)
*/
static str
-do_batstr_constint_str(bat *ret, const bat *l, const int *n, const char *name,
str (*func)(str *, const str *, const int *))
+do_batstr_constint_str(bat *res, const bat *l, const int *n, const char *name,
str (*func)(str*, size_t*, const char*, int))
{
BATiter bi;
- BAT *bn, *b;
+ BAT *bn = NULL, *b = NULL;
BUN p, q;
- str x, y;
- str msg = MAL_SUCCEED;
+ size_t buflen = INITIAL_STR_BUFFER_LENGTH;
+ str x, buf = GDKmalloc(buflen), msg = MAL_SUCCEED;
+ int nn = *n;
+ bool nils = false;
- prepareOperand(b, l, name);
- prepareResult(bn, b, TYPE_str, name);
+ if (!buf) {
+ msg = createException(MAL, name, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ goto bailout;
+ }
+ if (!(b = BATdescriptor(*l))) {
+ msg = createException(MAL, name, SQLSTATE(HY005)
RUNTIME_OBJECT_MISSING);
+ goto bailout;
+ }
+ q = BATcount(b);
+ if (!(bn = COLnew(b->hseqbase, TYPE_str, q, TRANSIENT))) {
+ msg = createException(MAL, name, SQLSTATE(HY013)
MAL_MALLOC_FAIL);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list