From 7c4a6a88edb87584f447dee81d087ca73e3f7461 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Wed, 6 Jun 2018 19:29:32 +0200 Subject: [PATCH] mescc: Support gcc-3.4.0: *printf: Support `%n'. * lib/libc+tcc.c (vfprintf, vsprintf): Support `%n'. For Gcc 3.4.0. * scaffold/tests/70-printf.c: Test it. --- lib/libc+tcc.c | 74 +++++++++++++++++++++++++++++++------- scaffold/tests/70-printf.c | 12 +++++++ 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/lib/libc+tcc.c b/lib/libc+tcc.c index 56892b5d..6b66eabb 100644 --- a/lib/libc+tcc.c +++ b/lib/libc+tcc.c @@ -576,9 +576,13 @@ vfprintf (FILE* f, char const* format, va_list ap) { int fd = (int)f; char const *p = format; + int count = 0; while (*p) if (*p != '%') - fputc (*p++, fd); + { + count++; + fputc (*p++, fd); + } else { p++; @@ -618,7 +622,7 @@ vfprintf (FILE* f, char const* format, va_list ap) c = *++p; switch (c) { - case '%': {fputc (*p, fd); break;} + case '%': {fputc (*p, fd); count++; break;} case 'c': {char c; c = va_arg (ap, int); fputc (c, fd); break;} case 'd': case 'i': @@ -638,15 +642,22 @@ vfprintf (FILE* f, char const* format, va_list ap) width = width - strlen (s); if (!left_p && !precision_p) while (!precision_p && width-- > 0) - fputc (pad, f); + { + fputc (pad, f); + count++; + } while (*s) { if (precision_p && width-- == 0) break; fputc (*s++, f); + count++; } while (!precision_p && width-- > 0) - fputc (pad, f); + { + fputc (pad, f); + count++; + } break; } case 's': @@ -656,15 +667,28 @@ vfprintf (FILE* f, char const* format, va_list ap) width = width - strlen (s); if (!left_p && !precision_p) while (!precision_p && width-- > 0) - fputc (pad, f); + { + fputc (pad, f); + count++; + } while (*s) { if (precision_p && width-- == 0) break; fputc (*s++, f); + count++; } while (!precision_p && width-- > 0) - fputc (pad, f); + { + fputc (pad, f); + count++; + } + break; + } + case 'n': + { + int *n = va_arg (ap, int *); + *n = count; break; } default: @@ -741,9 +765,13 @@ int vsprintf (char *str, char const* format, va_list ap) { char const *p = format; + int count = 0; while (*p) if (*p != '%') - *str++ = *p++; + { + *str++ = *p++; + count++; + } else { p++; @@ -783,8 +811,8 @@ vsprintf (char *str, char const* format, va_list ap) c = *++p; switch (c) { - case '%': {*str++ = *p; break;} - case 'c': {c = va_arg (ap, int); *str++ = c; break;} + case '%': {*str++ = *p; count++; break;} + case 'c': {c = va_arg (ap, int); *str++ = c; count++; break;} case 'd': case 'i': case 'o': @@ -803,15 +831,22 @@ vsprintf (char *str, char const* format, va_list ap) width = width - strlen (s); if (!left_p && !precision_p) while (!precision_p && width-- > 0) - *str++ = pad; + { + *str++ = pad; + count++; + } while (*s) { if (precision_p && width-- == 0) break; *str++ = *s++; + count++; } while (!precision_p && width-- > 0) - *str++ = pad; + { + *str++ = pad; + count++; + } break; } case 's': @@ -821,15 +856,28 @@ vsprintf (char *str, char const* format, va_list ap) width = width - strlen (s); if (!left_p && !precision_p) while (!precision_p && width-- > 0) - *str++ = pad; + { + *str++ = pad; + count++; + } while (*s) { if (precision_p && width-- == 0) break; *str++ = *s++; + count++; } while (!precision_p && width-- > 0) - *str++ = pad; + { + *str++ = pad; + count++; + } + break; + } + case 'n': + { + int *n = va_arg (ap, int *); + *n = count; break; } default: diff --git a/scaffold/tests/70-printf.c b/scaffold/tests/70-printf.c index d62e3825..653e2128 100644 --- a/scaffold/tests/70-printf.c +++ b/scaffold/tests/70-printf.c @@ -134,5 +134,17 @@ test () if (strcmp (buf, ">>C<<\n")) return 19; + int n; + fprintf (stderr, "foo bar\n%n", &n); + if (n != 8) + return 20; + + sprintf (buf, "foo%nbar\n", &n); + eputs ("buf="); eputs (buf); eputs ("\n"); + if (strcmp (buf, "foobar\n")) + return 21; + if (n != 3) + return 22; + return 0; }