+ if (f & f_plus) DPUTC(&dd, '+');
+ if (f & f_minus) DPUTC(&dd, '-');
+ if (f & f_sharp) DPUTC(&dd, '#');
+ if (f & f_zero) DPUTC(&dd, '0');
+
+ if (f & f_wd) {
+ DENSURE(&dd, PUTFSTEP);
+ dd.len += sprintf(dd.buf + dd.len, "%d", wd);
+ }
+
+ if (f & f_prec) {
+ DENSURE(&dd, PUTFSTEP + 1);
+ dd.len += sprintf(dd.buf + dd.len, ".%d", prec);
+ }
+
+ /* --- Write out the length gadget --- */
+
+ switch (f & f_len) {
+ case len_hh: DPUTC(&dd, 'h'); /* fall through */
+ case len_h: DPUTC(&dd, 'h'); break;
+ IF_LONGLONG( case len_ll: DPUTC(&dd, 'l'); /* fall through */ )
+ case len_l: DPUTC(&dd, 'l'); break;
+ case len_z: DPUTC(&dd, 'z'); break;
+ case len_t: DPUTC(&dd, 't'); break;
+ case len_L: DPUTC(&dd, 'L'); break;
+ IF_INTMAX( case len_j: DPUTC(&dd, 'j'); break; )
+ case len_std: break;
+ default: abort();
+ }
+
+ /* --- And finally the actually important bit --- */
+
+ DPUTC(&dd, fs->ch);
+ DPUTZ(&dd);
+
+ /* --- Make sure we have enough space for the output --- */
+
+ sz = PUTFSTEP;
+ if (sz < wd) sz = wd;
+ if (sz < prec + 16) sz = prec + 16;
+ switch (fs->ch) {
+ case 'a': case 'A':
+ case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
+#ifdef HAVE_FLOAT_H
+ if (fs->ch == 'f') {
+ mx = ((fs->f & f_len) == len_L ?
+ LDBL_MAX_10_EXP : DBL_MAX_10_EXP) + 16;
+ if (sz < mx) sz = mx;
+ }
+ break;
+#else
+ DPUTS(d, "<no float support>");
+ continue;
+#endif
+ case 's':
+ if (!(f & f_prec)) {
+ n = strlen(fa[fs->arg].u.s);
+ if (sz < n) sz = n;
+ }
+ break;
+ case 'n':
+ switch (fs->fmt) {
+#define CASE(code, ty) \
+ case fmt_##code: *fa[fs->arg].u.code = d->len - n; break;
+ PERCENT_N_FMTTYPES(CASE)
+#undef CASE
+ default: abort();
+ }
+ continue;
+ }
+
+ /* --- Finally do the output stage --- */
+
+ DENSURE(d, sz + 1);
+ switch (fs->fmt) {
+#ifdef HAVE_SNPRINTF
+# define CASE(code, ty) case fmt_##code: \
+ i = snprintf(d->buf + d->len, sz + 1, dd.buf, fa[fs->arg].u.code); \
+ break;
+#else
+# define CASE(code, ty) case fmt_##code: \
+ i = sprintf(d->buf + d->len, dd.buf, fa[fs->arg].u.code); \
+ break;
+#endif
+ OUTPUT_FMTTYPES(CASE)
+#undef CASE
+ default: abort();
+ }
+ assert(0 <= i && i <= sz); d->len += i;