/* -*-c-*-
*
- * $Id: dstr.c,v 1.7 1999/05/21 22:14:30 mdw Exp $
+ * $Id: dstr.c,v 1.9 1999/07/06 19:16:06 mdw Exp $
*
* Handle dynamically growing strings
*
/*----- Revision history --------------------------------------------------*
*
* $Log: dstr.c,v $
+ * Revision 1.9 1999/07/06 19:16:06 mdw
+ * Simplify buffer-growing algorithm. Just double it each time.
+ *
+ * Revision 1.8 1999/06/01 09:47:52 mdw
+ * Fix nasty bugs in `dstr_vputf'.
+ *
* Revision 1.7 1999/05/21 22:14:30 mdw
* Take advantage of the new dynamic string macros.
*
/*----- Tunable constants -------------------------------------------------*/
+/* --- Buffer expansion parameters --- *
+ *
+ * If the buffer is empty, it is set to @DSTR_INITSZ@ bytes in size.
+ * Otherwise, it's set to the next power of two that's large enough. This is
+ * memory-hungry, but efficient.
+ */
+
#define DSTR_INITSZ 256 /* Initial buffer size */
-#define DSTR_INCSZ 4096 /* Threshhold for doubling */
+
+/* --- Parameters for @dstr_putf@ --- *
+ *
+ * For each format specifier, at least @DSTR_PUTFSTEP@ bytes are ensured
+ * before writing the formatted result.
+ */
+
#define DSTR_PUTFSTEP 64 /* Buffer size for @putf@ */
/*----- Main code ---------------------------------------------------------*/
if (rq <= d->sz)
return;
- /* --- Grow the buffer --- *
- *
- * For small buffers, just double the size. For big buffers, make them
- * a multiple of some suitably large chunk size.
- */
+ /* --- Grow the buffer --- */
nsz = d->sz;
- do {
- if (nsz == 0)
- nsz = DSTR_INITSZ;
- else if (d->sz < 0x1000)
- nsz <<= 1;
- else
- nsz = (rq + 0x0fff) & ~0x0fff;
- } while (rq > nsz);
+ if (nsz == 0 && rq < DSTR_INITSZ)
+ nsz = DSTR_INITSZ;
+ else
+ do nsz <<= 1; while (nsz < rq);
if (d->buf)
d->buf = xrealloc(d->buf, nsz);
goto getnum;
default:
if (isdigit((unsigned char)*p)) {
- f |= f_prec;
+ f |= f_wd;
ip = &wd;
goto getnum;
}
DENSURE(&dd, DSTR_PUTFSTEP);
dd.len += sprintf(dd.buf + dd.len, "%i", *ip);
} else {
- *ip = *p + '0';
+ *ip = *p - '0';
DPUTC(&dd, *p);
p++;
while (isdigit((unsigned char)*p)) {
DPUTC(&dd, *p);
- *ip = 10 * *ip + *p++ + '0';
+ *ip = 10 * *ip + *p++ - '0';
}
}
break;