mescc: Support binutils 2.14: vfprint, vsprintf: %12.10d.

* lib/libc+tcc.c (vfprintf, vsprintf): Handle %12.10d.
* scaffold/tests/70-printf.c: Test it.
This commit is contained in:
Jan Nieuwenhuizen 2018-06-21 00:27:49 +02:00
parent f245237f83
commit 2551eef953
No known key found for this signature in database
GPG Key ID: F3C1A0D9C1D65273
2 changed files with 133 additions and 55 deletions

View File

@ -22,6 +22,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <limits.h>
#include <setjmp.h> #include <setjmp.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -679,7 +680,7 @@ vfprintf (FILE* f, char const* format, va_list ap)
p++; p++;
char c = *p; char c = *p;
int left_p = 0; int left_p = 0;
int precision_p = 0; int precision = -1;
int width = -1; int width = -1;
if (c == 'l') if (c == 'l')
c = *++p; c = *++p;
@ -688,11 +689,6 @@ vfprintf (FILE* f, char const* format, va_list ap)
left_p = 1; left_p = 1;
c = *++p; c = *++p;
} }
if (c == '.')
{
precision_p = 1;
c = *++p;
}
char pad = ' '; char pad = ' ';
if (c == '0') if (c == '0')
{ {
@ -709,6 +705,20 @@ vfprintf (FILE* f, char const* format, va_list ap)
width = va_arg (ap, int); width = va_arg (ap, int);
c = *++p; c = *++p;
} }
if (c == '.')
{
c = *++p;
if (c >= '0' && c <= '9')
{
precision = abtoi (&p, 10);
c = *p;
}
else if (c == '*')
{
precision = va_arg (ap, int);
c = *++p;
}
}
if (c == 'l') if (c == 'l')
c = *++p; c = *++p;
switch (c) switch (c)
@ -729,23 +739,35 @@ vfprintf (FILE* f, char const* format, va_list ap)
char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X'); char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X');
if (c == 'X') if (c == 'X')
strupr (s); strupr (s);
if (!precision_p && width >= 0) int length = strlen (s);
width = width - strlen (s); if (precision == -1)
if (!left_p && !precision_p) precision = length;
while (!precision_p && width-- > 0) if (!left_p)
{ {
fputc (pad, f); while (width-- > precision)
count++; {
} fputc (pad, f);
count++;
}
while (precision > length)
{
fputc ('0', f);
precision--;
width--;
count++;
}
}
while (*s) while (*s)
{ {
if (precision_p && width-- == 0) if (precision-- <= 0)
break; break;
width--;
fputc (*s++, f); fputc (*s++, f);
count++; count++;
} }
while (!precision_p && width-- > 0) while (width > 0)
{ {
width--;
fputc (pad, f); fputc (pad, f);
count++; count++;
} }
@ -754,23 +776,35 @@ vfprintf (FILE* f, char const* format, va_list ap)
case 's': case 's':
{ {
char *s = va_arg (ap, char *); char *s = va_arg (ap, char *);
if (!precision_p && width >= 0) int length = strlen (s);
width = width - strlen (s); if (precision == -1)
if (!left_p && !precision_p) precision = length;
while (!precision_p && width-- > 0) if (!left_p)
{ {
fputc (pad, f); while (width-- > precision)
count++; {
} fputc (pad, f);
count++;
}
while (precision > length)
{
fputc (' ', f);
precision--;
width--;
count++;
}
}
while (*s) while (*s)
{ {
if (precision_p && width-- == 0) if (precision-- <= 0)
break; break;
width--;
fputc (*s++, f); fputc (*s++, f);
count++; count++;
} }
while (!precision_p && width-- > 0) while (width > 0)
{ {
width--;
fputc (pad, f); fputc (pad, f);
count++; count++;
} }
@ -784,7 +818,7 @@ vfprintf (FILE* f, char const* format, va_list ap)
} }
default: default:
{ {
eputs ("vfprintf: not supported: %"); eputs ("vfprintf: not supported: %:");
eputc (c); eputc (c);
eputs ("\n"); eputs ("\n");
p++; p++;
@ -841,7 +875,7 @@ vsscanf (char const *s, char const *template, va_list ap)
} }
default: default:
{ {
eputs ("vsscanf: not supported: %"); eputs ("vsscanf: not supported: %:");
eputc (c); eputc (c);
eputs ("\n"); eputs ("\n");
t++; t++;
@ -870,7 +904,7 @@ vsprintf (char *str, char const* format, va_list ap)
p++; p++;
char c = *p; char c = *p;
int left_p = 0; int left_p = 0;
int precision_p = 0; int precision = -1;
int width = -1; int width = -1;
if (c == 'l') if (c == 'l')
c = *++p; c = *++p;
@ -879,11 +913,6 @@ vsprintf (char *str, char const* format, va_list ap)
left_p = 1; left_p = 1;
c = *++p; c = *++p;
} }
if (c == '.')
{
precision_p = 1;
c = *++p;
}
char pad = ' '; char pad = ' ';
if (c == '0') if (c == '0')
{ {
@ -900,6 +929,20 @@ vsprintf (char *str, char const* format, va_list ap)
width = va_arg (ap, int); width = va_arg (ap, int);
c = *++p; c = *++p;
} }
if (c == '.')
{
c = *++p;
if (c >= '0' && c <= '9')
{
precision = abtoi (&p, 10);
c = *p;
}
else if (c == '*')
{
precision = va_arg (ap, int);
c = *++p;
}
}
if (c == 'l') if (c == 'l')
c = *++p; c = *++p;
switch (c) switch (c)
@ -920,23 +963,35 @@ vsprintf (char *str, char const* format, va_list ap)
char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X'); char const *s = number_to_ascii (d, base, c != 'u' && c != 'x' && c != 'X');
if (c == 'X') if (c == 'X')
strupr (s); strupr (s);
if (!precision_p && width >= 0) int length = strlen (s);
width = width - strlen (s); if (precision == -1)
if (!left_p && !precision_p) precision = length;
while (!precision_p && width-- > 0) if (!left_p)
{ {
*str++ = pad; while (width-- > precision)
count++; {
} *str++ = pad;
count++;
}
while (precision > length)
{
*str++ = '0';
precision--;
width--;
count++;
}
}
while (*s) while (*s)
{ {
if (precision_p && width-- == 0) if (precision-- <= 0)
break; break;
width--;
*str++ = *s++; *str++ = *s++;
count++; count++;
} }
while (!precision_p && width-- > 0) while (width > 0)
{ {
width--;
*str++ = pad; *str++ = pad;
count++; count++;
} }
@ -945,23 +1000,35 @@ vsprintf (char *str, char const* format, va_list ap)
case 's': case 's':
{ {
char *s = va_arg (ap, char *); char *s = va_arg (ap, char *);
if (!precision_p && width >= 0) int length = strlen (s);
width = width - strlen (s); if (precision == -1)
if (!left_p && !precision_p) precision = length;
while (!precision_p && width-- > 0) if (!left_p)
{ {
*str++ = pad; while (width-- > precision)
count++; {
} *str++ = pad;
count++;
}
while (width > length)
{
*str++ = ' ';
precision--;
width--;
count++;
}
}
while (*s) while (*s)
{ {
if (precision_p && width-- == 0) if (precision-- <= 0)
break; break;
width--;
*str++ = *s++; *str++ = *s++;
count++; count++;
} }
while (!precision_p && width-- > 0) while (width > 0)
{ {
width--;
*str++ = pad; *str++ = pad;
count++; count++;
} }
@ -975,7 +1042,7 @@ vsprintf (char *str, char const* format, va_list ap)
} }
default: default:
{ {
eputs ("vsprintf: not supported: %"); eputs ("vsprintf: not supported: %:");
eputc (c); eputc (c);
eputs ("\n"); eputs ("\n");
p++; p++;

View File

@ -135,9 +135,11 @@ test ()
return 19; return 19;
int n; int n;
#if !__x86_64__
fprintf (stderr, "foo bar\n%n", &n); fprintf (stderr, "foo bar\n%n", &n);
if (n != 8) if (n != 8)
return 20; return 20;
#endif
sprintf (buf, "foo%nbar\n", &n); sprintf (buf, "foo%nbar\n", &n);
eputs ("buf="); eputs (buf); eputs ("\n"); eputs ("buf="); eputs (buf); eputs ("\n");
@ -146,5 +148,14 @@ test ()
if (n != 3) if (n != 3)
return 22; return 22;
#if !__x86_64__
fprintf (stdout, "%12.8d\n", 12345);
#endif
sprintf (buf, "%12.8d\n", 12345);
eputs ("buf="); eputs (buf); eputs ("\n");
if (strcmp (buf, " 00012345\n"))
return 23;
return 0; return 0;
} }