Changeset: a5d5e4043704 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/a5d5e4043704
Modified Files:
clients/mapilib/msettings.c
common/utils/mstring.h
Branch: odbc-tls
Log Message:
Add reallocprintf and vreallocprintf to mstring.h
diffs (118 lines):
diff --git a/clients/mapilib/msettings.c b/clients/mapilib/msettings.c
--- a/clients/mapilib/msettings.c
+++ b/clients/mapilib/msettings.c
@@ -59,22 +59,19 @@ char* allocprintf(const char *fmt, ...)
char *
allocprintf(const char *fmt, ...)
{
- size_t buflen = 80;
- while (1) {
- char *buf = malloc(buflen);
- if (buf == NULL)
- return NULL;
- va_list ap;
- va_start(ap, fmt);
- int n = vsnprintf(buf, buflen, fmt, ap);
- va_end(ap);
- if (n >= 0 && (size_t)n < buflen)
- return buf;
- free(buf);
- if (n < 0)
- return NULL;
- buflen = n + 1;
- }
+ va_list ap;
+ char *buf = NULL;
+ size_t pos = 0, cap = 0;
+ int n;
+
+ va_start(ap, fmt);
+ n = vreallocprintf(&buf, &pos, &cap, fmt, ap);
+ va_end(ap);
+
+ if (n >= 0)
+ return buf;
+ free(buf);
+ return NULL;
}
diff --git a/common/utils/mstring.h b/common/utils/mstring.h
--- a/common/utils/mstring.h
+++ b/common/utils/mstring.h
@@ -155,6 +155,75 @@ checkUTF8(const char *v)
return true;
}
+static inline int vreallocprintf(char **buf, size_t *pos, size_t *size, const
char *fmt, va_list ap)
+ __attribute__((__format__(__printf__, 4, 0)));
+
+static inline int
+vreallocprintf(char **buf, size_t *pos, size_t *capacity, const char *fmt,
va_list args)
+{
+ va_list ap;
+
+ assert(*pos <= *capacity);
+ assert(*buf == NULL || *capacity > 0);
+
+ size_t need_at_least = strlen(fmt);
+ need_at_least += 1; // trailing NUL
+ need_at_least += 80; // some space for the items
+ while (1) {
+ // Common cases:
+ // 1. buf=NULL, pos=cap=0: allocate reasonable amount
+ // 2. buf=NULL, pos=0, cap=something: start with allocating cap
+ // 3. buf not NULL, cap=something: allocate larger cap
+ if (*buf == NULL || need_at_least > *capacity - *pos) {
+ size_t cap1 = *pos + need_at_least;
+ size_t cap2 = *capacity;
+ if (*buf)
+ cap2 += cap2 / 2;
+ size_t new_cap = cap1 > cap2 ? cap1 : cap2;
+ char *new_buf = realloc(*buf, new_cap);
+ if (new_buf == 0)
+ return -1;
+ *buf = new_buf;
+ *capacity = new_cap;
+ }
+ assert(*buf);
+ assert(need_at_least <= *capacity - *pos);
+ char *output = &(*buf)[*pos];
+ size_t avail = *capacity - *pos;
+ assert(avail >= 1);
+
+ va_copy(ap, args);
+ int n = vsnprintf(output, avail, fmt, ap);
+ va_end(ap);
+
+ if (n < 0)
+ return n;
+ size_t needed = (size_t)n;
+ if (needed <= avail - 1) {
+ // it wanted to print n chars and it could
+ *pos += needed;
+ return n;
+ }
+ need_at_least = needed + 1;
+ }
+}
+
+static inline int reallocprintf(char **buf, size_t *pos, size_t *size, const
char *fmt, ...)
+ __attribute__((__format__(__printf__, 4, 5)));
+
+static inline int
+reallocprintf(char **buf, size_t *pos, size_t *capacity, const char *fmt, ...)
+{
+ int n;
+ va_list ap;
+ va_start(ap, fmt);
+ n = vreallocprintf(buf, pos, capacity, fmt, ap);
+ va_end(ap);
+ return n;
+}
+
+
+
#ifndef __GNUC__
#undef __builtin_expect
#endif
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]