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
145
lib/libc+tcc.c
145
lib/libc+tcc.c
|
@ -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)
|
||||||
|
{
|
||||||
|
while (width-- > precision)
|
||||||
{
|
{
|
||||||
fputc (pad, f);
|
fputc (pad, f);
|
||||||
count++;
|
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)
|
||||||
|
{
|
||||||
|
while (width-- > precision)
|
||||||
{
|
{
|
||||||
fputc (pad, f);
|
fputc (pad, f);
|
||||||
count++;
|
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)
|
||||||
|
{
|
||||||
|
while (width-- > precision)
|
||||||
{
|
{
|
||||||
*str++ = pad;
|
*str++ = pad;
|
||||||
count++;
|
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)
|
||||||
|
{
|
||||||
|
while (width-- > precision)
|
||||||
{
|
{
|
||||||
*str++ = pad;
|
*str++ = pad;
|
||||||
count++;
|
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++;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue