+size_t
+format_uintmax (uintmax_t val, char *buf, size_t s)
+{
+ if (!buf)
+ {
+ s = 0;
+ do
+ s++;
+ while ((val /= 10) != 0);
+ }
+ else
+ {
+ char *p = buf + s - 1;
+
+ do
+ {
+ *p-- = val % 10 + '0';
+ }
+ while ((val /= 10) != 0);
+
+ while (p >= buf)
+ *p-- = '0';
+ }
+ return s;
+}
+
+void
+xheader_print (struct xheader *xhdr, char *keyword, char *value)
+{
+ size_t len = strlen (keyword) + strlen (value) + 3; /* ' ' + '=' + '\n' */
+ size_t p, n = 0;
+ char nbuf[100];
+
+ do
+ {
+ p = n;
+ n = format_uintmax (len + p, NULL, 0);
+ }
+ while (n != p);
+
+ format_uintmax (len + n, nbuf, n);
+ obstack_grow (xhdr->stk, nbuf, n);
+ obstack_1grow (xhdr->stk, ' ');
+ obstack_grow (xhdr->stk, keyword, strlen (keyword));
+ obstack_1grow (xhdr->stk, '=');
+ obstack_grow (xhdr->stk, value, strlen (value));
+ obstack_1grow (xhdr->stk, '\n');
+}
+
+void
+xheader_finish (struct xheader *xhdr)
+{
+ obstack_1grow (xhdr->stk, 0);
+ xhdr->buffer = obstack_finish (xhdr->stk);
+ xhdr->size = strlen (xhdr->buffer);
+}
+
+void
+xheader_destroy (struct xheader *xhdr)
+{
+ if (xhdr->stk)
+ {
+ obstack_free (xhdr->stk, NULL);
+ free (xhdr->stk);
+ xhdr->stk = NULL;
+ }
+ else
+ free (xhdr->buffer);
+ xhdr->buffer = 0;
+ xhdr->size = 0;
+}
+