+\f
+/* Buildable strings */
+static uintmax_t string_length;
+
+void
+xheader_string_begin ()
+{
+ string_length = 0;
+}
+
+void
+xheader_string_add (char const *s)
+{
+ if (extended_header.buffer)
+ return;
+ extended_header_init ();
+ string_length += strlen (s);
+ x_obstack_grow (&extended_header, s, strlen (s));
+}
+
+void
+xheader_string_end (char const *keyword)
+{
+ size_t len;
+ size_t p;
+ size_t n = 0;
+ char nbuf[UINTMAX_STRSIZE_BOUND];
+ char const *np;
+ char *cp;
+
+ if (extended_header.buffer)
+ return;
+ extended_header_init ();
+
+ len = strlen (keyword) + string_length + 3; /* ' ' + '=' + '\n' */
+
+ do
+ {
+ p = n;
+ np = umaxtostr (len + p, nbuf);
+ n = nbuf + sizeof nbuf - 1 - np;
+ }
+ while (n != p);
+
+ p = strlen (keyword) + n + 2;
+ x_obstack_blank (&extended_header, p);
+ x_obstack_1grow (&extended_header, '\n');
+ cp = obstack_next_free (extended_header.stk) - string_length - p - 1;
+ memmove (cp + p, cp, string_length);
+ cp = stpcpy (cp, np);
+ *cp++ = ' ';
+ cp = stpcpy (cp, keyword);
+ *cp++ = '=';
+}
+