chiark / gitweb /
@@@ timeout wip
[mLib] / struct / buf.h
index 6193cd3fb4dbead04807bed9d92db138828ccae4..7dd555541257a3d48fdf8aec32293787206ae432 100644 (file)
@@ -93,14 +93,8 @@ extern const struct gprintf_ops buf_printops;
 #define BBAD(b) ((b)->f & BF_BROKEN)
 #define BOK(b) (!BBAD(b))
 
-#if GCC_VERSION_P(8, 0)
-#  define BENSURE(b, sz)                                               \
-     MUFFLE_WARNINGS_EXPR(GCC_WARNING("-Wint-in-bool-context"),                \
-       (BBAD(b) ? -1 : (sz) > BLEFT(b) ? buf_tryextend(b, sz) : 0))
-#else
-#  define BENSURE(b, sz)                                               \
+#define BENSURE(b, sz)                                         \
      (BBAD(b) ? -1 : (sz) > BLEFT(b) ? buf_tryextend(b, sz) : 0)
-#endif
 
 #define DBBASE(db) BBASE(DBUF_BUF(db))
 #define DBLIM(db) BLIM(DBUF_BUF(db))
@@ -160,6 +154,11 @@ extern void dbuf_create(dbuf */*db*/);
 
 extern void dbuf_reset(dbuf */*db*/);
 
+#define DBRESET(db) do {                                               \
+  (db)->_b.p = (db)->_b.base; (db)->_b.limit = (db)->_b.base + (db)->sz; \
+  (db)->_b.f = ((db)->_b.f&~BF_BROKEN) | BF_WRITE;                     \
+} while (0)
+
 /* --- @dbuf_destroy@ --- *
  *
  * Arguments:  @dbuf *db@ = pointer to a buffer block
@@ -171,9 +170,9 @@ extern void dbuf_reset(dbuf */*db*/);
 
 extern void dbuf_destroy(dbuf */*db*/);
 
-/* --- @buf_break@ --- *
+/* --- @{,d}buf_break@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *
  * Returns:    Some negative value.
  *
@@ -181,10 +180,12 @@ extern void dbuf_destroy(dbuf */*db*/);
  */
 
 extern int buf_break(buf */*b*/);
+extern int dbuf_break(dbuf */*db*/);
+#define dbuf_break(db) (buf_break(DBUF_BUF(db)))
 
-/* --- @buf_flip@ --- *
+/* --- @{,d}buf_flip@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *
  * Returns:    ---
  *
@@ -193,10 +194,18 @@ extern int buf_break(buf */*b*/);
  */
 
 extern void buf_flip(buf */*b*/);
+extern void dbuf_flip(dbuf */*db*/);
+#define dbuf_flip(db) (buf_flip(DBUF_BUF(db)))
+
+#define BFLIP(b) do {                                                  \
+  (b)->limit = (b)->p; (b)->p = (b)->base;                             \
+  (b)->f &= ~BF_WRITE;                                                 \
+} while (0)
+#define DBFLIP(db) BFLIP(DBUF_BUF(db))
 
-/* --- @buf_ensure@ --- *
+/* --- @{,d}buf_ensure@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @size_t sz@ = size of data wanted
  *
  * Returns:    Zero if it worked, nonzero if there wasn't enough space.
@@ -205,10 +214,12 @@ extern void buf_flip(buf */*b*/);
  */
 
 extern int buf_ensure(buf */*b*/, size_t /*sz*/);
+extern int dbuf_ensure(dbuf */*db*/, size_t /*sz*/);
+#define dbuf_ensure(db, sz) (buf_ensure(DBUF_BUF(db), (sz)))
 
-/* --- @buf_tryextend@ --- *
+/* --- @{,d}buf_tryextend@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @size_t sz@ = size of data wanted
  *
  * Returns:    Zero if it worked, nonzero if the buffer won't grow.
@@ -218,10 +229,12 @@ extern int buf_ensure(buf */*b*/, size_t /*sz*/);
  */
 
 extern int buf_tryextend(buf */*b*/, size_t /*sz*/);
+extern int dbuf_tryextend(dbuf */*db*/, size_t /*sz*/);
+#define dbuf_tryextend(db, sz) (buf_tryextend(DBUF_BUF(db), (sz)))
 
-/* --- @buf_get@ --- *
+/* --- @{,d}buf_get@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @size_t sz@ = size of the buffer
  *
  * Returns:    Pointer to the place in the buffer.
@@ -231,10 +244,12 @@ extern int buf_tryextend(buf */*b*/, size_t /*sz*/);
  */
 
 extern void *buf_get(buf */*b*/, size_t /*sz*/);
+extern void *dbuf_get(dbuf */*db*/, size_t /*sz*/);
+#define dbuf_get(db, sz) (buf_get(DBUF_BUF(db), (sz)))
 
-/* --- @buf_put@ --- *
+/* --- @{,d}buf_put@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @const void *p@ = pointer to a buffer
  *             @size_t sz@ = size of the buffer
  *
@@ -244,10 +259,12 @@ extern void *buf_get(buf */*b*/, size_t /*sz*/);
  */
 
 extern int buf_put(buf */*b*/, const void */*p*/, size_t /*sz*/);
+extern int dbuf_put(dbuf */*db*/, const void */*p*/, size_t /*sz*/);
+#define dbuf_put(db, p, sz) (buf_put(DBUF_BUF(db), (p), (sz)))
 
-/* --- @buf_getbyte@ --- *
+/* --- @{,d}buf_getbyte@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *
  * Returns:    A byte, or less than zero if there wasn't a byte there.
  *
@@ -255,10 +272,12 @@ extern int buf_put(buf */*b*/, const void */*p*/, size_t /*sz*/);
  */
 
 extern int buf_getbyte(buf */*b*/);
+extern int dbuf_getbyte(dbuf */*db*/);
+#define dbuf_getbyte(db) (buf_getbyte(DBUF_BUF(db)))
 
-/* --- @buf_putbyte@ --- *
+/* --- @{,d}buf_putbyte@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @int ch@ = byte to write
  *
  * Returns:    Zero if OK, nonzero if there wasn't enough space.
@@ -267,10 +286,12 @@ extern int buf_getbyte(buf */*b*/);
  */
 
 extern int buf_putbyte(buf */*b*/, int /*ch*/);
+extern int dbuf_putbyte(dbuf */*db*/, int /*ch*/);
+#define dbuf_putbyte(db, ch) (buf_putbyte(DBUF_BUF(db), (ch)))
 
-/* --- @buf_getu{8,{16,24,32,64}{,l,b}}@ --- *
+/* --- @{,d}buf_getu{8,{16,24,32,64}{,l,b}}@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @uintSZ *w@ = where to put the word
  *
  * Returns:    Zero if OK, or nonzero if there wasn't a word there.
@@ -279,12 +300,28 @@ extern int buf_putbyte(buf */*b*/, int /*ch*/);
  */
 
 #define BUF_DECL_GETU_(n, W, w)                                                \
-  extern int buf_getu##w(buf */*b*/, uint##n */*w*/);
+  extern int buf_getu##w(buf */*b*/, uint##n */*w*/);                  \
+  extern int dbuf_getu##w(dbuf */*db*/, uint##n */*w*/);
 DOUINTCONV(BUF_DECL_GETU_)
+#define dbuf_getu8(db, w) (buf_getu8(DBUF_BUF(db), (w)))
+#define dbuf_getu16(db, w) (buf_getu16(DBUF_BUF(db), (w)))
+#define dbuf_getu16l(db, w) (buf_getu16l(DBUF_BUF(db), (w)))
+#define dbuf_getu16b(db, w) (buf_getu16b(DBUF_BUF(db), (w)))
+#define dbuf_getu24(db, w) (buf_getu24(DBUF_BUF(db), (w)))
+#define dbuf_getu24l(db, w) (buf_getu24l(DBUF_BUF(db), (w)))
+#define dbuf_getu24b(db, w) (buf_getu24b(DBUF_BUF(db), (w)))
+#define dbuf_getu32(db, w) (buf_getu32(DBUF_BUF(db), (w)))
+#define dbuf_getu32l(db, w) (buf_getu32l(DBUF_BUF(db), (w)))
+#define dbuf_getu32b(db, w) (buf_getu32b(DBUF_BUF(db), (w)))
+#ifdef HAVE_UINT64
+#  define dbuf_getu64(db, w) (buf_getu64(DBUF_BUF(db), (w)))
+#  define dbuf_getu64l(db, w) (buf_getu64l(DBUF_BUF(db), (w)))
+#  define dbuf_getu64b(db, w) (buf_getu64b(DBUF_BUF(db), (w)))
+#endif
 
-/* --- @buf_getk64{,l,b}@ --- *
+/* --- @{,d}buf_getk64{,l,b}@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @kludge64 *w@ = where to put the word
  *
  * Returns:    Zero if OK, or nonzero if there wasn't a word there.
@@ -295,10 +332,16 @@ DOUINTCONV(BUF_DECL_GETU_)
 extern int buf_getk64(buf */*b*/, kludge64 */*w*/);
 extern int buf_getk64l(buf */*b*/, kludge64 */*w*/);
 extern int buf_getk64b(buf */*b*/, kludge64 */*w*/);
+extern int dbuf_getk64(dbuf */*db*/, kludge64 */*w*/);
+extern int dbuf_getk64l(dbuf */*db*/, kludge64 */*w*/);
+extern int dbuf_getk64b(dbuf */*db*/, kludge64 */*w*/);
+#define dbuf_getk64(db, w) (buf_getk64(DBUF_BUF(db), (w)))
+#define dbuf_getk64l(db, w) (buf_getk64l(DBUF_BUF(db), (w)))
+#define dbuf_getk64b(db, w) (buf_getk64b(DBUF_BUF(db), (w)))
 
-/* --- @buf_putu{8,{16,24,32,64}{,l,b}}@ --- *
+/* --- @{,d}buf_putu{8,{16,24,32,64}{,l,b}}@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @uintSZ w@ = word to write
  *
  * Returns:    Zero if OK, or nonzero if there wasn't enough space
@@ -307,12 +350,28 @@ extern int buf_getk64b(buf */*b*/, kludge64 */*w*/);
  */
 
 #define BUF_DECL_PUTU_(n, W, w)                                                \
-  extern int buf_putu##w(buf */*b*/, uint##n /*w*/);
+  extern int buf_putu##w(buf */*b*/, uint##n /*w*/);                   \
+  extern int dbuf_putu##w(dbuf */*db*/, uint##n /*w*/);
 DOUINTCONV(BUF_DECL_PUTU_)
+#define dbuf_putu8(db, w) (buf_putu8(DBUF_BUF(db), (w)))
+#define dbuf_putu16(db, w) (buf_putu16(DBUF_BUF(db), (w)))
+#define dbuf_putu16l(db, w) (buf_putu16l(DBUF_BUF(db), (w)))
+#define dbuf_putu16b(db, w) (buf_putu16b(DBUF_BUF(db), (w)))
+#define dbuf_putu24(db, w) (buf_putu24(DBUF_BUF(db), (w)))
+#define dbuf_putu24l(db, w) (buf_putu24l(DBUF_BUF(db), (w)))
+#define dbuf_putu24b(db, w) (buf_putu24b(DBUF_BUF(db), (w)))
+#define dbuf_putu32(db, w) (buf_putu32(DBUF_BUF(db), (w)))
+#define dbuf_putu32l(db, w) (buf_putu32l(DBUF_BUF(db), (w)))
+#define dbuf_putu32b(db, w) (buf_putu32b(DBUF_BUF(db), (w)))
+#ifdef HAVE_UINT64
+#  define dbuf_putu64(db, w) (buf_putu64(DBUF_BUF(db), (w)))
+#  define dbuf_putu64l(db, w) (buf_putu64l(DBUF_BUF(db), (w)))
+#  define dbuf_putu64b(db, w) (buf_putu64b(DBUF_BUF(db), (w)))
+#endif
 
-/* --- @buf_putk64{,l,b}@ --- *
+/* --- @{,d}buf_putk64{,l,b}@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @kludge64 w@ = word to write
  *
  * Returns:    Zero if OK, or nonzero if there wasn't enough space
@@ -323,10 +382,16 @@ DOUINTCONV(BUF_DECL_PUTU_)
 extern int buf_putk64(buf */*b*/, kludge64 /*w*/);
 extern int buf_putk64l(buf */*b*/, kludge64 /*w*/);
 extern int buf_putk64b(buf */*b*/, kludge64 /*w*/);
+extern int dbuf_putk64(dbuf */*db*/, kludge64 /*w*/);
+extern int dbuf_putk64l(dbuf */*db*/, kludge64 /*w*/);
+extern int dbuf_putk64b(dbuf */*db*/, kludge64 /*w*/);
+#define dbuf_putk64(db, w) (buf_putk64(DBUF_BUF(db), (w)))
+#define dbuf_putk64l(db, w) (buf_putk64l(DBUF_BUF(db), (w)))
+#define dbuf_putk64b(db, w) (buf_putk64b(DBUF_BUF(db), (w)))
 
-/* --- @buf_getmem{8,{16,24,32,64}{,l,b},z} --- *
+/* --- @{,d}buf_getmem{8,{16,24,32,64}{,l,b},z} --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer block
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @size_t *nn@ = where to put the length
  *
  * Returns:    Pointer to the buffer data, or null.
@@ -337,12 +402,27 @@ extern int buf_putk64b(buf */*b*/, kludge64 /*w*/);
  */
 
 #define BUF_DECL_GETMEM_(n, W, w)                                      \
-  extern void *buf_getmem##w(buf */*b*/, size_t */*nn*/);
+  extern void *buf_getmem##w(buf */*b*/, size_t */*nn*/);              \
+  extern void *dbuf_getmem##w(dbuf */*db*/, size_t */*nn*/);
 BUF_DOSUFFIXES(BUF_DECL_GETMEM_)
-
-/* --- @buf_putmem{8,{16,24,32,64}{,l,b},z} --- *
- *
- * Arguments:  @buf *b@ = pointer to a buffer block
+#define dbuf_getmem8(db, nn) (buf_getmem8(DBUF_BUF(db), (nn)))
+#define dbuf_getmem16(db, nn) (buf_getmem16(DBUF_BUF(db), (nn)))
+#define dbuf_getmem16l(db, nn) (buf_getmem16l(DBUF_BUF(db), (nn)))
+#define dbuf_getmem16b(db, nn) (buf_getmem16b(DBUF_BUF(db), (nn)))
+#define dbuf_getmem24(db, nn) (buf_getmem24(DBUF_BUF(db), (nn)))
+#define dbuf_getmem24l(db, nn) (buf_getmem24l(DBUF_BUF(db), (nn)))
+#define dbuf_getmem24b(db, nn) (buf_getmem24b(DBUF_BUF(db), (nn)))
+#define dbuf_getmem32(db, nn) (buf_getmem32(DBUF_BUF(db), (nn)))
+#define dbuf_getmem32l(db, nn) (buf_getmem32l(DBUF_BUF(db), (nn)))
+#define dbuf_getmem32b(db, nn) (buf_getmem32b(DBUF_BUF(db), (nn)))
+#define dbuf_getmem64(db, nn) (buf_getmem64(DBUF_BUF(db), (nn)))
+#define dbuf_getmem64l(db, nn) (buf_getmem64l(DBUF_BUF(db), (nn)))
+#define dbuf_getmem64b(db, nn) (buf_getmem64b(DBUF_BUF(db), (nn)))
+#define dbuf_getmemz(db, nn) (buf_getmemz(DBUF_BUF(db), (nn)))
+
+/* --- @{,d}buf_putmem{8,{16,24,32,64}{,l,b},z} --- *
+ *
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @const void *p@ = pointer to data to write
  *             @size_t n@ = length to write
  *
@@ -354,12 +434,27 @@ BUF_DOSUFFIXES(BUF_DECL_GETMEM_)
  */
 
 #define BUF_DECL_PUTMEM_(n, W, w)                                      \
-  extern int buf_putmem##w(buf */*b*/, const void */*p*/, size_t /*nn*/);
+  extern int buf_putmem##w(buf */*b*/, const void */*p*/, size_t /*nn*/); \
+  extern int dbuf_putmem##w(dbuf */*db*/, const void */*p*/, size_t /*nn*/);
 BUF_DOSUFFIXES(BUF_DECL_PUTMEM_)
-
-/* --- @buf_getbuf{8,{16,24,32,64}{,l,b},z} --- *
- *
- * Arguments:  @buf *b@ = pointer to a buffer block
+#define dbuf_putmem8(db, p, nn) (buf_putmem8(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem16(db, p, nn) (buf_putmem16(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem16l(db, p, nn) (buf_putmem16l(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem16b(db, p, nn) (buf_putmem16b(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem24(db, p, nn) (buf_putmem24(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem24l(db, p, nn) (buf_putmem24l(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem24b(db, p, nn) (buf_putmem24b(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem32(db, p, nn) (buf_putmem32(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem32l(db, p, nn) (buf_putmem32l(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem32b(db, p, nn) (buf_putmem32b(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem64(db, p, nn) (buf_putmem64(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem64l(db, p, nn) (buf_putmem64l(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmem64b(db, p, nn) (buf_putmem64b(DBUF_BUF(db), (p), (nn)))
+#define dbuf_putmemz(db, p, nn) (buf_putmemz(DBUF_BUF(db), (p), (nn)))
+
+/* --- @{,d}buf_getbuf{8,{16,24,32,64}{,l,b},z} --- *
+ *
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @buf *bb@ = where to put the result
  *
  * Returns:    Zero if it worked, nonzero if there wasn't enough space.
@@ -369,12 +464,27 @@ BUF_DOSUFFIXES(BUF_DECL_PUTMEM_)
  */
 
 #define BUF_DECL_GETBUF_(n, W, w)                                      \
-  extern int buf_getbuf##w(buf */*b*/, buf */*bb*/);
+  extern int buf_getbuf##w(buf */*b*/, buf */*bb*/);                   \
+  extern int dbuf_getbuf##w(dbuf */*db*/, buf */*bb*/);
 BUF_DOSUFFIXES(BUF_DECL_GETBUF_)
-
-/* --- @buf_putbuf{8,{16,24,32,64}{,l,b},z} --- *
- *
- * Arguments:  @buf *b@ = pointer to a buffer block
+#define dbuf_getbuf8(db, bb) (buf_getbuf8(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf16(db, bb) (buf_getbuf16(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf16l(db, bb) (buf_getbuf16l(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf16b(db, bb) (buf_getbuf16b(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf24(db, bb) (buf_getbuf24(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf24l(db, bb) (buf_getbuf24l(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf24b(db, bb) (buf_getbuf24b(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf32(db, bb) (buf_getbuf32(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf32l(db, bb) (buf_getbuf32l(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf32b(db, bb) (buf_getbuf32b(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf64(db, bb) (buf_getbuf64(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf64l(db, bb) (buf_getbuf64l(DBUF_BUF(db), (bb)))
+#define dbuf_getbuf64b(db, bb) (buf_getbuf64b(DBUF_BUF(db), (bb)))
+#define dbuf_getbufz(db, bb) (buf_getbufz(DBUF_BUF(db), (bb)))
+
+/* --- @{,d}buf_putbuf{8,{16,24,32,64}{,l,b},z} --- *
+ *
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @buf *bb@ = buffer to write
  *
  * Returns:    Zero if it worked, nonzero if there wasn't enough space.
@@ -383,12 +493,27 @@ BUF_DOSUFFIXES(BUF_DECL_GETBUF_)
  */
 
 #define BUF_DECL_PUTBUF_(n, W, w)                                      \
-  extern int buf_putbuf##w(buf */*b*/, buf */*bb*/);
+  extern int buf_putbuf##w(buf */*b*/, buf */*bb*/);                   \
+  extern int dbuf_putbuf##w(dbuf */*db*/, buf */*bb*/);
 BUF_DOSUFFIXES(BUF_DECL_PUTBUF_)
-
-/* --- @buf_getdstr{8,{16,24,32,64}{,l,b},z} --- *
- *
- * Arguments:  @buf *b@ = pointer to a buffer block
+#define dbuf_putbuf8(db, bb) (buf_putbuf8(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf16(db, bb) (buf_putbuf16(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf16l(db, bb) (buf_putbuf16l(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf16b(db, bb) (buf_putbuf16b(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf24(db, bb) (buf_putbuf24(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf24l(db, bb) (buf_putbuf24l(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf24b(db, bb) (buf_putbuf24b(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf32(db, bb) (buf_putbuf32(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf32l(db, bb) (buf_putbuf32l(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf32b(db, bb) (buf_putbuf32b(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf64(db, bb) (buf_putbuf64(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf64l(db, bb) (buf_putbuf64l(DBUF_BUF(db), (bb)))
+#define dbuf_putbuf64b(db, bb) (buf_putbuf64b(DBUF_BUF(db), (bb)))
+#define dbuf_putbufz(db, bb) (buf_putbufz(DBUF_BUF(db), (bb)))
+
+/* --- @{,d}buf_getdstr{8,{16,24,32,64}{,l,b},z} --- *
+ *
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @dstr *d@ = where to put the result
  *
  * Returns:    Zero if it worked, nonzero if there wasn't enough space.
@@ -398,12 +523,27 @@ BUF_DOSUFFIXES(BUF_DECL_PUTBUF_)
  */
 
 #define BUF_DECL_GETDSTR_(n, W, w)                                     \
-  extern int buf_getdstr##w(buf */*b*/, dstr */*d*/);
+  extern int buf_getdstr##w(buf */*b*/, dstr */*d*/);                  \
+  extern int dbuf_getdstr##w(dbuf */*db*/, dstr */*d*/);
 BUF_DOSUFFIXES(BUF_DECL_GETDSTR_)
-
-/* --- @buf_putdstr{8,{16,24,32,64}{,l,b},z} --- *
- *
- * Arguments:  @buf *b@ = pointer to a buffer block
+#define dbuf_getdstr8(db, d) (buf_getdstr8(DBUF_BUF(db), (d)))
+#define dbuf_getdstr16(db, d) (buf_getdstr16(DBUF_BUF(db), (d)))
+#define dbuf_getdstr16l(db, d) (buf_getdstr16l(DBUF_BUF(db), (d)))
+#define dbuf_getdstr16b(db, d) (buf_getdstr16b(DBUF_BUF(db), (d)))
+#define dbuf_getdstr24(db, d) (buf_getdstr24(DBUF_BUF(db), (d)))
+#define dbuf_getdstr24l(db, d) (buf_getdstr24l(DBUF_BUF(db), (d)))
+#define dbuf_getdstr24b(db, d) (buf_getdstr24b(DBUF_BUF(db), (d)))
+#define dbuf_getdstr32(db, d) (buf_getdstr32(DBUF_BUF(db), (d)))
+#define dbuf_getdstr32l(db, d) (buf_getdstr32l(DBUF_BUF(db), (d)))
+#define dbuf_getdstr32b(db, d) (buf_getdstr32b(DBUF_BUF(db), (d)))
+#define dbuf_getdstr64(db, d) (buf_getdstr64(DBUF_BUF(db), (d)))
+#define dbuf_getdstr64l(db, d) (buf_getdstr64l(DBUF_BUF(db), (d)))
+#define dbuf_getdstr64b(db, d) (buf_getdstr64b(DBUF_BUF(db), (d)))
+#define dbuf_getdstrz(db, d) (buf_getdstrz(DBUF_BUF(db), (d)))
+
+/* --- @{,d}buf_putdstr{8,{16,24,32,64}{,l,b},z} --- *
+ *
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @dstr *d@ = string to write
  *
  * Returns:    Zero if it worked, nonzero if there wasn't enough space.
@@ -412,12 +552,27 @@ BUF_DOSUFFIXES(BUF_DECL_GETDSTR_)
  */
 
 #define BUF_DECL_PUTDSTR_(n, W, w)                                     \
-  extern int buf_putdstr##w(buf */*b*/, dstr */*d*/);
+  extern int buf_putdstr##w(buf */*b*/, dstr */*d*/);                  \
+  extern int dbuf_putdstr##w(dbuf */*db*/, dstr */*d*/);
 BUF_DOSUFFIXES(BUF_DECL_PUTDSTR_)
-
-/* --- @buf_putstr{8,{16,24,32,64}{,l,b},z} --- *
- *
- * Arguments:  @buf *b@ = pointer to a buffer block
+#define dbuf_putdstr8(db, d) (buf_putdstr8(DBUF_BUF(db), (d)))
+#define dbuf_putdstr16(db, d) (buf_putdstr16(DBUF_BUF(db), (d)))
+#define dbuf_putdstr16l(db, d) (buf_putdstr16l(DBUF_BUF(db), (d)))
+#define dbuf_putdstr16b(db, d) (buf_putdstr16b(DBUF_BUF(db), (d)))
+#define dbuf_putdstr24(db, d) (buf_putdstr24(DBUF_BUF(db), (d)))
+#define dbuf_putdstr24l(db, d) (buf_putdstr24l(DBUF_BUF(db), (d)))
+#define dbuf_putdstr24b(db, d) (buf_putdstr24b(DBUF_BUF(db), (d)))
+#define dbuf_putdstr32(db, d) (buf_putdstr32(DBUF_BUF(db), (d)))
+#define dbuf_putdstr32l(db, d) (buf_putdstr32l(DBUF_BUF(db), (d)))
+#define dbuf_putdstr32b(db, d) (buf_putdstr32b(DBUF_BUF(db), (d)))
+#define dbuf_putdstr64(db, d) (buf_putdstr64(DBUF_BUF(db), (d)))
+#define dbuf_putdstr64l(db, d) (buf_putdstr64l(DBUF_BUF(db), (d)))
+#define dbuf_putdstr64b(db, d) (buf_putdstr64b(DBUF_BUF(db), (d)))
+#define dbuf_putdstrz(db, d) (buf_putdstrz(DBUF_BUF(db), (d)))
+
+/* --- @{,d}buf_putstr{8,{16,24,32,64}{,l,b},z} --- *
+ *
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @const char *p@ = string to write
  *
  * Returns:    Zero if it worked, nonzero if there wasn't enough space.
@@ -426,12 +581,55 @@ BUF_DOSUFFIXES(BUF_DECL_PUTDSTR_)
  */
 
 #define BUF_DECL_PUTSTR_(n, W, w)                                      \
-  extern int buf_putstr##w(buf */*b*/, const char */*p*/);
+  extern int buf_putstr##w(buf */*b*/, const char */*p*/);             \
+  extern int dbuf_putstr##w(dbuf */*db*/, const char */*p*/);
 BUF_DOSUFFIXES(BUF_DECL_PUTSTR_)
+#define dbuf_putstr8(db, p) (buf_putstr8(DBUF_BUF(db), (p)))
+#define dbuf_putstr16(db, p) (buf_putstr16(DBUF_BUF(db), (p)))
+#define dbuf_putstr16l(db, p) (buf_putstr16l(DBUF_BUF(db), (p)))
+#define dbuf_putstr16b(db, p) (buf_putstr16b(DBUF_BUF(db), (p)))
+#define dbuf_putstr24(db, p) (buf_putstr24(DBUF_BUF(db), (p)))
+#define dbuf_putstr24l(db, p) (buf_putstr24l(DBUF_BUF(db), (p)))
+#define dbuf_putstr24b(db, p) (buf_putstr24b(DBUF_BUF(db), (p)))
+#define dbuf_putstr32(db, p) (buf_putstr32(DBUF_BUF(db), (p)))
+#define dbuf_putstr32l(db, p) (buf_putstr32l(DBUF_BUF(db), (p)))
+#define dbuf_putstr32b(db, p) (buf_putstr32b(DBUF_BUF(db), (p)))
+#define dbuf_putstr64(db, p) (buf_putstr64(DBUF_BUF(db), (p)))
+#define dbuf_putstr64l(db, p) (buf_putstr64l(DBUF_BUF(db), (p)))
+#define dbuf_putstr64b(db, p) (buf_putstr64b(DBUF_BUF(db), (p)))
+#define dbuf_putstrz(db, p) (buf_putstrz(DBUF_BUF(db), (p)))
+
+/* --- @{,d}buf_getf64{,l,b} --- *
+ *
+ * Arguments:  @buf *b@ = pointer to a bfufer block
+ *             @double *x_out@ = where to put the result
+ *
+ * Returns:    Zero on success, @-1@ on failure (and the buffer is broken).
+ *
+ *             If the system supports NaNs, then any encoded NaN is returned
+ *             as the value of @NAN@ in @<math.h>@; otherwise, this function
+ *             reports failure.
+ *
+ *             In general, values are rounded to the nearest available
+ *             value, in the way that the system usually rounds.  If the
+ *             system doesn't support infinities, then any encoded infinity
+ *             is reported as the largest-possible-magnitude finite value
+ *             instead.
+ */
+
+extern int buf_getf64(buf */*b*/, double */*x_out*/);
+extern int buf_getf64l(buf */*b*/, double */*x_out*/);
+extern int buf_getf64b(buf */*b*/, double */*x_out*/);
+extern int dbuf_getf64(dbuf */*db*/, double */*x_out*/);
+extern int dbuf_getf64l(dbuf */*db*/, double */*x_out*/);
+extern int dbuf_getf64b(dbuf */*db*/, double */*x_out*/);
+#define dbuf_getf64(db, x_out) (buf_getf64(DBUF_BUF(db), (x_out)))
+#define dbuf_getf64l(db, x_out) (buf_getf64l(DBUF_BUF(db), (x_out)))
+#define dbuf_getf64b(db, x_out) (buf_getf64b(DBUF_BUF(db), (x_out)))
 
-/* --- @buf_putf64{,b,l} --- *
+/* --- @{,d}buf_putf64{,l,b} --- *
  *
- * Arguments:  @buf *b@ = a buffer to write to
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @double x@ = a number to write
  *
  * Returns:    Zero on success, @-1@ on failure (and the buffer is broken).
@@ -449,45 +647,63 @@ BUF_DOSUFFIXES(BUF_DECL_PUTSTR_)
  */
 
 extern int buf_putf64(buf */*b*/, double /*x*/);
-extern int buf_putf64b(buf */*b*/, double /*x*/);
 extern int buf_putf64l(buf */*b*/, double /*x*/);
-
-/* --- @buf_getf64{,b,l} --- *
- *
- * Arguments:  @buf *b@ = a buffer to read from
- *             @double *x_out@ = where to put the result
- *
- * Returns:    Zero on success, @-1@ on failure (and the buffer is broken).
- *
- *             If the system supports NaNs, then any encoded NaN is returned
- *             as the value of @NAN@ in @<math.h>@; otherwise, this function
- *             reports failure.
- *
- *             In general, values are rounded to the nearest available
- *             value, in the way that the system usually rounds.  If the
- *             system doesn't support infinities, then any encoded infinity
- *             is reported as the largest-possible-magnitude finite value
- *             instead.
+extern int buf_putf64b(buf */*b*/, double /*x*/);
+extern int dbuf_putf64(dbuf */*db*/, double /*x*/);
+extern int dbuf_putf64l(dbuf */*db*/, double /*x*/);
+extern int dbuf_putf64b(dbuf */*db*/, double /*x*/);
+#define dbuf_putf64(db, x) (buf_putf64(DBUF_BUF(db), (x)))
+#define dbuf_putf64l(db, x) (buf_putf64l(DBUF_BUF(db), (x)))
+#define dbuf_putf64b(db, x) (buf_putf64b(DBUF_BUF(db), (x)))
+
+/* --- @{,D}BUF_ENCLOSETAG@ --- *
+ *
+ * Arguments:  @tag@ = a control-structure macro tag
+ *             @buf *b@ or @dbuf *db@ = pointer to a buffer block
+ *             @size_t mk@ = temporary, used to stash starting offset
+ *             @check@ = expression which is true if the length @_delta@
+ *                     is representable
+ *             @poke@ = function or macro called as @poke(octet *, size_t)@
+ *                     to store the final size at the given address
+ *             @size_t lensz@ = space to leave for the length
+ *
+ * Use:                This is a statement head.  It ensures that there is enough
+ *             space in the buffer, saves the current output offset in @mk,
+ *             and reserves @lensz@ bytes for a length prefix.  It then
+ *             executes the @body@, which should contribute zero or more
+ *             further bytes to the buffer.  Finally, it invokes @poke@ to
+ *             store the length of the material written by @body@ in the
+ *             space reserved.
  */
 
-extern int buf_getf64(buf */*b*/, double *x_/*out*/);
-extern int buf_getf64b(buf */*b*/, double *x_/*out*/);
-extern int buf_getf64l(buf */*b*/, double *x_/*out*/);
-
-#define BUF_ENCLOSETAG(tag, buf, mk, check, poke, lensz)               \
-  MC_BEFORE(tag##__save,                                               \
-    { (mk) = BLEN(buf);                                                        \
-      if (!BENSURE(buf, lensz)) (buf)->p += (lensz); })                        \
-  MC_AFTER(tag##__poke,                                                        \
-    { size_t _delta = BLEN(buf) - (mk) + (lensz);                      \
-      assert(check);                                                   \
-      if (BOK(buf)) poke((buf)->base + (mk), _delta);  })
-
-#define BUF_ENCLOSEZTAG(tag, buf)                                      \
-  MC_AFTER(tag##__zero, { buf_putbyte(buf, 0); })
-
-#define BUF_ENCLOSENATIVETAG(tag, buf, mk, W)                          \
-  BUF_ENCLOSETAG(tag, buf, mk, (_delta <= MASK##W), STORE##W, SZ_##W)
+#define BUF_ENCLOSETAG(tag, b, mk, check, poke, lensz)                 \
+  MC_BEFORE(tag##__save, {                                             \
+    (mk) = BLEN(b);                                                    \
+    if (!BENSURE(b, lensz)) BSTEP(b, (lensz));                         \
+  })                                                                   \
+  MC_AFTER(tag##__poke, {                                              \
+    size_t _delta = BLEN(b) - (mk) - (lensz);                          \
+    assert(check);                                                     \
+    if (BOK(b)) poke(BBASE(b) + (mk), _delta);                         \
+  })
+
+#define DBUF_ENCLOSETAG(tag, b, mk, check, poke, lensz)                        \
+  BUF_ENCLOSETAG(tag, DBUF_BUF(b), (mk), (check), poke, (lensz))
+
+/* --- @{,D}BUF_ENCLOSE{I,K,Z}TAG@ --- *
+ *
+ * Arguments:  @tag@ = a control-structure macro tag
+ *             @buf *b@ or @dbuf *db@ = pointer to a buffer block
+ *             @size_t mk@ = temporary, used to stash starting offset
+ *             @W@ = word-size and -order suffix
+ *
+ * Use:                Specialized versions of @BUF_ENCLOSETAG@ above.
+ *
+ *             @BUF_ENCLOSEZTAG@ just writes a terminating zero byte.
+ *             @BUF_ENCLOSEITAG@ writes a word with the given size and
+ *             byte ordering.  @BUF_ENCLOSEKTAG@ does the same using the
+ *             @kludge64@ machinery.
+ */
 
 #define BUF_STORESZK64(p, sz)                                          \
   do { kludge64 _k; ASSIGN64(_k, (sz)); STORE64_((p), _k); } while (0)
@@ -495,63 +711,105 @@ extern int buf_getf64l(buf */*b*/, double *x_/*out*/);
   do { kludge64 _k; ASSIGN64(_k, (sz)); STORE64_B_((p), _k); } while (0)
 #define BUF_STORESZK64_L(p, sz)                                                \
   do { kludge64 _k; ASSIGN64(_k, (sz)); STORE64_L_((p), _k); } while (0)
-#define BUF_ENCLOSEK64TAG(tag, buf, mk, W)                             \
-  BUF_ENCLOSE(tag, buf, mk, 1, BUF_STORESZK##W, 8)
-
-#define BUF_ENCLOSE8(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 8)
-#define BUF_ENCLOSE16(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 16)
-#define BUF_ENCLOSE16_B(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 16_B)
-#define BUF_ENCLOSE16_L(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 16_L)
-#define BUF_ENCLOSE24(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 24)
-#define BUF_ENCLOSE24_B(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 24_B)
-#define BUF_ENCLOSE24_L(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 24_L)
-#define BUF_ENCLOSE32(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 32)
-#define BUF_ENCLOSE32_B(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 32_B)
-#define BUF_ENCLOSE32_L(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 32_L)
+
+#define BUF_ENCLOSEITAG(tag, b, mk, W)                                 \
+  BUF_ENCLOSETAG(tag, (b), (mk), (_delta <= MASK##W), STORE##W, SZ_##W)
+#define BUF_ENCLOSEKTAG(tag, b, mk, W)                         \
+  BUF_ENCLOSE(tag, (b), (mk), 1, BUF_STORESZK##W, 8)
+#define BUF_ENCLOSEZTAG(tag, b)                                                \
+  MC_AFTER(tag##__zero, { buf_putbyte((b), 0); })
+
+#define DBUF_ENCLOSEITAG(tag, b, mk, W)                                        \
+  BUF_ENCLOSEITAG(tag, DBUF_BUF(b), (mk), W)
+#define DBUF_ENCLOSEKTAG(tag, b, mk, W)                                        \
+  BUF_ENCLOSEKTAG(tag, DBUF_BUF(b), (mk), W)
+#define DBUF_ENCLOSEZTAG(tag, b)                                       \
+  BUF_ENCLOSEZTAG(tag, DBUF_BUF(b))
+
+/* --- @{,D}BUF_ENCLOSE{8,{16,24,32,64}{,_L,_B},Z}@ --- *
+ *
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
+ *             @size_t mk@ = temporary, used to stash starting offset
+ *             @W@ = word-size and -order suffix
+ *
+ * Use:                User versions of @BUF_ENCLOSETAG@; see that macro for
+ *             details.
+ *
+ *             These are statement heads.  They reserve space for a length
+ *             prefix and execute the statement.  When the statement
+ *             completes, they patch the length of material written by the
+ *             statement into the reserved space.
+ */
+
+#define BUF_ENCLOSE8(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 8)
+#define BUF_ENCLOSE16(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 16)
+#define BUF_ENCLOSE16_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 16_B)
+#define BUF_ENCLOSE16_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 16_L)
+#define BUF_ENCLOSE24(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 24)
+#define BUF_ENCLOSE24_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 24_B)
+#define BUF_ENCLOSE24_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 24_L)
+#define BUF_ENCLOSE32(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 32)
+#define BUF_ENCLOSE32_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 32_B)
+#define BUF_ENCLOSE32_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 32_L)
+#ifdef HAVE_UINT64
+#  define BUF_ENCLOSE64(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 64)
+#  define BUF_ENCLOSE64_B(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 64_B)
+#  define BUF_ENCLOSE64_L(b, mk) BUF_ENCLOSEITAG(encl, (b), (mk), 64_L)
+#else
+#  define BUF_ENCLOSE64(b, mk) BUF_ENCLOSEKTAG(encl, (b), (mk), 64)
+#  define BUF_ENCLOSE64_B(b, mk) BUF_ENCLOSEKTAG(encl, (b), (mk), 64_B)
+#  define BUF_ENCLOSE64_L(b, mk) BUF_ENCLOSEKTAG(encl, (b), (mk), 64_L)
+#endif
+#define BUF_ENCLOSEZ(b) BUF_ENCLOSEZTAG(encl, (b))
+
+#define DBUF_ENCLOSE8(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 8)
+#define DBUF_ENCLOSE16(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 16)
+#define DBUF_ENCLOSE16_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 16_B)
+#define DBUF_ENCLOSE16_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 16_L)
+#define DBUF_ENCLOSE24(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 24)
+#define DBUF_ENCLOSE24_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 24_B)
+#define DBUF_ENCLOSE24_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 24_L)
+#define DBUF_ENCLOSE32(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 32)
+#define DBUF_ENCLOSE32_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 32_B)
+#define DBUF_ENCLOSE32_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 32_L)
 #ifdef HAVE_UINT64
-#  define BUF_ENCLOSE64(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 64)
-#  define BUF_ENCLOSE64_B(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 64_B)
-#  define BUF_ENCLOSE64_L(buf, mk) BUF_ENCLOSENATIVETAG(encl, buf, mk, 64_L)
+#  define DBUF_ENCLOSE64(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 64)
+#  define DBUF_ENCLOSE64_B(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 64_B)
+#  define DBUF_ENCLOSE64_L(db, mk) DBUF_ENCLOSEITAG(encl, (db), (mk), 64_L)
 #else
-#  define BUF_ENCLOSE64(buf, mk) BUF_ENCLOSEK64TAG(encl, buf, mk, 64)
-#  define BUF_ENCLOSE64_B(buf, mk) BUF_ENCLOSEK64TAG(encl, buf, mk, 64_B)
-#  define BUF_ENCLOSE64_L(buf, mk) BUF_ENCLOSEK64TAG(encl, buf, mk, 64_L)
+#  define DBUF_ENCLOSE64(db, mk) DBUF_ENCLOSEKTAG(encl, (db), (mk), 64)
+#  define DBUF_ENCLOSE64_B(db, mk) DBUF_ENCLOSEKTAG(encl, (db), (mk), 64_B)
+#  define DBUF_ENCLOSE64_L(db, mk) DBUF_ENCLOSEKTAG(encl, (db), (mk), 64_L)
 #endif
-#define BUF_ENCLOSEZ(buf) BUF_ENCLOSEZTAG(encl, buf)
+#define DBUF_ENCLOSEZ(db) DBUF_ENCLOSEZTAG(encl, (db))
 
-/* --- @buf_vputstrf@ --- *
+/* --- @{,d}buf_putstrf@, @{,d}buf_vputstrf@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @const char *p@ = pointer to @printf@-style format string
  *             @va_list *ap@ = argument handle
  *
  * Returns:    The number of characters written to the string, or @-1@ on
  *             failure.
  *
- * Use:                As for @buf_putstrf@, but may be used as a back-end to user-
- *             supplied functions with @printf@-style interfaces.
- */
-
-extern int buf_vputstrf(buf */*b*/, const char */*p*/, va_list */*ap*/);
-
-/* --- @buf_putstrf@ --- *
- *
- * Arguments:  @buf *b@ = pointer to a buffer
- *             @const char *p@ = pointer to @printf@-style format string
- *             @...@ = argument handle
- *
- * Returns:    The number of characters written to the string, or @-1@ on
- *             failure.
- *
  * Use:                Format a string to a buffer.  The resulting output is not
  *             null-terminated.
  */
 
-extern PRINTF_LIKE(2, 3) int buf_putstrf(buf */*b*/, const char */*p*/, ...);
+extern PRINTF_LIKE(2, 3)
+  int buf_putstrf(buf */*b*/, const char */*p*/, ...);
+extern PRINTF_LIKE(2, 3)
+  int dbuf_putstrf(dbuf */*db*/, const char */*p*/, ...);
+#if __STDC__ >= 199901
+#  define dbuf_putstrf(db, /*p*/...) (buf_putstr(DBUF_BUF(db), __VA_ARGS__))
+#endif
+extern int buf_vputstrf(buf */*b*/, const char */*p*/, va_list */*ap*/);
+extern int dbuf_vputstrf(dbuf */*db*/, const char */*p*/, va_list */*ap*/);
+#define dbuf_vputstrf(db, p, ap) (buf_vputstrf(DBUF_BUF(db), (p), (ap)))
 
-/* --- @buf_{,v}putstrf{8,{16,24,32,64}{,b,l},z}@ --- *
+/* --- @{,d}buf_{,v}putstrf{8,{16,24,32,64}{,b,l},z}@ --- *
  *
- * Arguments:  @buf *b@ = pointer to a buffer
+ * Arguments:  @buf *b@ or @dbuf *db@ = pointer to a buffer block
  *             @const char *p@ = pointer to @printf@-style format string
  *             @va_list *ap@ = argument handle
  *
@@ -562,12 +820,59 @@ extern PRINTF_LIKE(2, 3) int buf_putstrf(buf */*b*/, const char */*p*/, ...);
  */
 
 #define BUF_DECL_PUTSTRF_(n, W, w)                                     \
+  extern PRINTF_LIKE(2, 3)                                             \
+    int buf_putstrf##w(buf */*b*/, const char */*p*/, ...);            \
+  extern PRINTF_LIKE(2, 3)                                             \
+    int dbuf_putstrf##w(dbuf */*db*/, const char */*p*/, ...);         \
   extern int buf_vputstrf##w(buf */*b*/,                               \
                             const char */*p*/, va_list */*ap*/);       \
-  extern PRINTF_LIKE(2, 3)                                             \
-    int buf_putstrf##w(buf */*b*/, const char */*p*/, ...);
+  extern int dbuf_vputstrf##w(dbuf */*db*/,                            \
+                             const char */*p*/, va_list */*ap*/);
 BUF_DOSUFFIXES(BUF_DECL_PUTSTRF_)
-#undef BUF_DECL_PUTSTRF_
+#if __STDC__ >= 199901
+#  define dbuf_putstrf8(db, /*p*/...)                                  \
+     (buf_putstrf8(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf16(db, /*p*/...)                                 \
+     (buf_putstrf16(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf16l(db, /*p*/...)                                        \
+     (buf_putstrf16l(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf16b(db, /*p*/...)                                        \
+     (buf_putstrf16b(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf24(db, /*p*/...)                                 \
+     (buf_putstrf24(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf24l(db, /*p*/...)                                        \
+     (buf_putstrf24l(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf24b(db, /*p*/...)                                        \
+     (buf_putstrf24b(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf32(db, /*p*/...)                                 \
+     (buf_putstrf32(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf32l(db, /*p*/...)                                        \
+     (buf_putstrf32l(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf32b(db, /*p*/...)                                        \
+     (buf_putstrf32b(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf64(db, /*p*/...)                                 \
+     (buf_putstrf64(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf64l(db, /*p*/...)                                        \
+     (buf_putstrf64l(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrf64b(db, /*p*/...)                                        \
+     (buf_putstrf64b(DBUF_BUF(db), __VA_ARGS__))
+#  define dbuf_putstrfz(db, /*p*/...)                                  \
+     (buf_putstrfz(DBUF_BUF(db), __VA_ARGS__))
+#endif
+#define dbuf_vputstrf8(db, p, ap) (buf_vputstrf8(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf16(db, p, ap) (buf_vputstrf16(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf16l(db, p, ap) (buf_vputstrf16l(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf16b(db, p, ap) (buf_vputstrf16b(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf24(db, p, ap) (buf_vputstrf24(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf24l(db, p, ap) (buf_vputstrf24l(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf24b(db, p, ap) (buf_vputstrf24b(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf32(db, p, ap) (buf_vputstrf32(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf32l(db, p, ap) (buf_vputstrf32l(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf32b(db, p, ap) (buf_vputstrf32b(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf64(db, p, ap) (buf_vputstrf64(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf64l(db, p, ap) (buf_vputstrf64l(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrf64b(db, p, ap) (buf_vputstrf64b(DBUF_BUF(db), (p), (ap)))
+#define dbuf_vputstrfz(db, p, ap) (buf_vputstrfz(DBUF_BUF(db), (p), (ap)))
 
 /*----- That's all, folks -------------------------------------------------*/