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:
parent
f245237f83
commit
2551eef953
177
lib/libc+tcc.c
177
lib/libc+tcc.c
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue