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

View file

@ -135,9 +135,11 @@ test ()
return 19;
int n;
#if !__x86_64__
fprintf (stderr, "foo bar\n%n", &n);
if (n != 8)
return 20;
#endif
sprintf (buf, "foo%nbar\n", &n);
eputs ("buf="); eputs (buf); eputs ("\n");
@ -146,5 +148,14 @@ test ()
if (n != 3)
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;
}