+static const char zeros[PADSIZ] = "00000000000000000000";
+static const char spaces[PADSIZ] = " ";
-cvt_sign(int flags, FILE *fp)
+pad(const char *filler, int len, FILE *fp)
- if (flags & NEGATIVE) {
- if (putc('-', fp) == EOF)
- } else if (flags & SIGN) {
- if (putc('+', fp) == EOF)
- } else if (flags & SPACE) {
- if (putc(' ', fp) == EOF)
+ if (fwrite(filler, 1, PADSIZ, fp) != PADSIZ)
+ if (fwrite(filler, 1, len, fp) != len)
-cvt_inf(int flags, FILE *fp)
+lpad(int sign, int width, int siz, int flags, FILE *fp)
- if (cvt_sign(flags, fp))
+ if (width > siz && (flags & (MINUS|ZERO)) == 0 &&
+ pad(spaces, width - siz, fp))
- if (fwrite("inf", 1, 3, fp) != 3)
+ if (sign && putc(sign, fp) == EOF)
+ if (width > siz && (flags & (MINUS|ZERO)) == ZERO &&
+ pad(zeros, width - siz, fp))
-cvt_nan(int flags, FILE *fp)
+rpad(int width, int siz, int flags, FILE *fp)
- if (fwrite("nan", 1, 3, fp) != 3)
+ if (width > siz && (flags & MINUS) &&
+ pad(spaces, width - siz, fp))
-fill_zeros(int len, FILE *fp)
- static const char zeros[10] = "0000000000";
+ else if (flags & SPACE)
- while (len > (int)sizeof(zeros)) {
- if (fwrite(zeros, 1, sizeof(zeros), fp) != sizeof(zeros))
- if (fwrite(zeros, 1, len, fp) != len)
+cvt_inf(int width, int flags, FILE *fp)
+ sign = cvt_sign(flags);
+ if (lpad(sign, width, siz, flags & ~ZERO, fp))
+ if (fwrite("inf", 1, 3, fp) != 3)
+ if (rpad(width, siz, flags, fp))
+cvt_nan(int width, int flags, FILE *fp)
+ if (lpad('\0', width, 3, flags & ~ZERO, fp))
+ if (fwrite("nan", 1, 3, fp) != 3)
+ if (rpad(width, 3, flags, fp))
-cvt_efmt(char *head, int len, int prec, int exp, int flags, FILE *fp)
+cvt_esize(int sign, int len, int prec, int exp, int flags)
- if (cvt_sign(flags, fp))
+ d = (f > 0 || flags & SHARP) ? 1 : 0;
+ return s + i + f + d + e;
+cvt_efmt(char *head, int len, int width, int prec, int exp, int flags, FILE *fp)
+ sign = cvt_sign(flags);
+ size = cvt_esize(sign, len, prec, exp, flags);
+ if (lpad(sign, width, size, flags, fp))
if (putc(*head, fp) == EOF)
- if (((flags & ALT) || prec > 0) && putc('.', fp) == EOF)
+ if (((flags & SHARP) || prec > 0) && putc('.', fp) == EOF)
if (--len > 0 && fwrite(&head[1], 1, len, fp) != len)
- if (prec > len && fill_zeros(prec - len, fp))
+ if (prec > len && pad(zeros, prec - len, fp))
+ if (rpad(width, size, flags, fp))
-ecvt(double dvalue, int prec, FILE *fp)
+ecvt(double dvalue, int width, int prec, FILE *fp)
int flags, exp, neg, ret;
head = dtoa(dvalue, 2, prec + 1, &exp, &neg, &tail);
- ret = cvt_inf(flags, fp);
+ ret = cvt_inf(width, flags, fp);
- ret = cvt_nan(flags, fp);
+ ret = cvt_nan(width, flags, fp);
- ret = cvt_efmt(head, tail - head, prec, exp - 1, flags, fp);
+ ret = cvt_efmt(head, tail - head, width, prec, exp - 1, flags, fp);
for (i = 0; i < arraycount(t); ++i) {
for (prec = -1; prec <= 20; ++prec) {
- if (asprintf(&expect, "%.*e", prec, t[i].dvalue) < 0)
+ if (asprintf(&expect, "%30.*e", prec, t[i].dvalue) < 0)
fp = open_memstream(&result, &n);
- if (ecvt(t[i].dvalue, prec, fp))
+ if (ecvt(t[i].dvalue, 30, prec, fp))
printf("testcase:[%s], expect:[%s], result[%s]\n",