+If the "extend" flag is true, the string passed in can be NULL,
+empty, or non-empty. Growing is subject to an overall limit given
+by the size_limit argument.
+
+If the "extend" flag is false, the string passed in may not be NULL,
+will not be grown, and is usable in the original place after return.
+The return value can be NULL to signify overflow.
+
+Returns the possibly-new (if copy for growth was needed) string,
+not nul-terminated.
+*/
+
+gstring *
+string_vformat_trc(gstring * g, const uschar * func, unsigned line,
+ unsigned size_limit, unsigned flags, const char *format, va_list ap)
+{
+enum ltypes { L_NORMAL=1, L_SHORT=2, L_LONG=3, L_LONGLONG=4, L_LONGDOUBLE=5, L_SIZE=6 };
+
+int width, precision, off, lim, need;
+const char * fp = format; /* Deliberately not unsigned */
+BOOL dest_tainted = FALSE;
+
+string_datestamp_offset = -1; /* Datestamp not inserted */
+string_datestamp_length = 0; /* Datestamp not inserted */
+string_datestamp_type = 0; /* Datestamp not inserted */
+
+#ifdef COMPILE_UTILITY
+assert(!(flags & SVFMT_EXTEND));
+assert(g);
+#else
+
+/* Ensure we have a string, to save on checking later */
+if (!g) g = string_get(16);
+else if (!(flags & SVFMT_TAINT_NOCHK)) dest_tainted = is_tainted(g->s);
+
+if (!(flags & SVFMT_TAINT_NOCHK) && !dest_tainted && is_tainted(format))
+ {
+ if (!(flags & SVFMT_REBUFFER))
+ die_tainted(US"string_vformat", func, line);
+ gstring_rebuffer(g);
+ dest_tainted = TRUE;
+ }
+#endif /*!COMPILE_UTILITY*/
+
+lim = g->size - 1; /* leave one for a nul */
+off = g->ptr; /* remember initial offset in gstring */