base64 base224 \
sync \
qache \
- string
+ string \
+ bbuf
LIBUCW_INCLUDES= \
lib.h config.h math.h \
$(o)/lib/kmp-test: $(o)/lib/kmp-test.o $(LIBUCW) $(LIBCHARSET)
$(o)/lib/ipaccess-test: $(o)/lib/ipaccess-test.o $(LIBUCW)
-TESTS+=$(addprefix $(o)/lib/,regex.test unicode-utf8.test hash-test.test mempool.test stkstring.test slists.test kmp-test.test)
+TESTS+=$(addprefix $(o)/lib/,regex.test unicode-utf8.test hash-test.test mempool.test stkstring.test slists.test kmp-test.test bbuf.test)
$(o)/lib/regex.test: $(o)/lib/regex-t
$(o)/lib/unicode-utf8.test: $(o)/lib/unicode-utf8-t
$(o)/lib/hash-test.test: $(o)/lib/hash-test
$(o)/lib/bitops.test: $(o)/lib/bit-ffs-t $(o)/lib/bit-fls-t
$(o)/lib/slists.test: $(o)/lib/slists-t
$(o)/lib/kmp-test.test: $(o)/lib/kmp-test
+$(o)/lib/bbuf.test: $(o)/lib/bbuf-t
INCLUDES+=$(o)/lib/.include-stamp
$(o)/lib/.include-stamp: $(addprefix $(s)/lib/,$(LIBUCW_INCLUDES))
--- /dev/null
+/*
+ * UCW Library -- A simple growing buffers for byte-sized items
+ *
+ * (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *
+ * This software may be freely distributed and used according to the terms
+ * of the GNU Lesser General Public License.
+ */
+
+#include "lib/lib.h"
+#include "lib/bbuf.h"
+
+#include <stdio.h>
+
+char *
+bb_vprintf_at(bb_t *bb, uns ofs, char *fmt, va_list args)
+{
+ bb_grow(bb, ofs + 1);
+ va_list args2;
+ va_copy(args2, args);
+ int cnt = vsnprintf(bb->ptr + ofs, bb->len - ofs, fmt, args2);
+ va_end(args2);
+ if (cnt < 0)
+ {
+ /* Our C library doesn't support C99 return value of vsnprintf, so we need to iterate */
+ do
+ {
+ bb_do_grow(bb, bb->len + 1);
+ va_copy(args2, args);
+ cnt = vsnprintf(bb->ptr + ofs, bb->len - ofs, fmt, args2);
+ va_end(args2);
+ }
+ while (cnt < 0);
+ }
+ else if ((uns)cnt >= bb->len - ofs)
+ {
+ bb_do_grow(bb, ofs + cnt + 1);
+ va_copy(args2, args);
+ int cnt2 = vsnprintf(bb->ptr + ofs, bb->len - ofs, fmt, args2);
+ va_end(args2);
+ ASSERT(cnt2 == cnt);
+ }
+ return bb->ptr + ofs;
+}
+
+char *
+bb_printf_at(bb_t *bb, uns ofs, char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char *res = bb_vprintf_at(bb, ofs, fmt, args);
+ va_end(args);
+ return res;
+}
+
+char *
+bb_vprintf(bb_t *bb, char *fmt, va_list args)
+{
+ return bb_vprintf_at(bb, 0, fmt, args);
+}
+
+char *
+bb_printf(bb_t *bb, char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char *res = bb_vprintf_at(bb, 0, fmt, args);
+ va_end(args);
+ return res;
+}
+
+#ifdef TEST
+
+int main(void)
+{
+ bb_t bb;
+ bb_init(&bb);
+ char *x = bb_printf(&bb, "<Hello, %s!>", "World");
+ fputs(x, stdout);
+ x = bb_printf_at(&bb, 5, "<Hello, %50s!>\n", "World");
+ fputs(x, stdout);
+ bb_done(&bb);
+ return 0;
+}
+
+#endif
#define GBUF_PREFIX(x) bb_##x
#include "lib/gbuf.h"
+char *bb_vprintf(bb_t *bb, char *fmt, va_list args);
+char *bb_printf(bb_t *bb, char *fmt, ...);
+char *bb_vprintf_at(bb_t *bb, uns ofs, char *fmt, va_list args);
+char *bb_printf_at(bb_t *bb, uns ofs, char *fmt, ...);
+
#endif
--- /dev/null
+# Tests for growing buffers
+
+Run: obj/lib/bbuf-t
+Out: <Hello, World!><Hello, World!>
#define CLIST_FOR_EACH(type,n,list) for(type n=(void*)(list).head.next; (cnode*)(n) != &(list).head; n=(void*)((cnode*)(n))->next)
#define CLIST_FOR_EACH_DELSAFE(type,n,list,tmp) for(type n=(void*)(list).head.next; tmp=(void*)((cnode*)(n))->next, (cnode*)(n) != &(list).head; n=(void*)tmp)
+#define CLIST_FOR_EACH_BACKWARDS(type,n,list) for(type n=(void*)(list).head.prev; (cnode*)(n) != &(list).head; n=(void*)((cnode*)(n))->prev)
+
static inline void clist_insert_after(cnode *what, cnode *after)
{
cnode *before = after->next;
* int PREFIX_compare(SORT_KEY *a, *b)
* compare two keys, result like strcmp
* int PREFIX_fetch_key(struct fastbuf *f, SORT_KEY *k)
- * fetch next key, returns 1=ok, 0=eof
+ * fetch next key, returns nonzero=ok, 0=eof
* void PREFIX_copy_data(struct fastbuf *src, *dest, SORT_KEY *k)
* write just fetched key k to dest and copy all data
* belonging to this key from src to dest.