From patchwork Wed Jun 11 14:01:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 4336351 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 09944BEECB for ; Wed, 11 Jun 2014 14:02:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F37DA20256 for ; Wed, 11 Jun 2014 14:02:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B777920218 for ; Wed, 11 Jun 2014 14:02:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932351AbaFKOCI (ORCPT ); Wed, 11 Jun 2014 10:02:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:17657 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932299AbaFKOCD (ORCPT ); Wed, 11 Jun 2014 10:02:03 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s5BE1wfo006471 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 11 Jun 2014 10:01:59 -0400 Received: from dhcp-27-201.brq.redhat.com (dhcp-1-235.brq.redhat.com [10.34.1.235]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s5BE1Zbe014365; Wed, 11 Jun 2014 10:01:57 -0400 From: Andrew Jones To: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org Cc: christoffer.dall@linaro.org, pbonzini@redhat.com Subject: [PATCH v5 14/19] printf: support field padding Date: Wed, 11 Jun 2014 16:01:29 +0200 Message-Id: <1402495294-30737-15-git-send-email-drjones@redhat.com> In-Reply-To: <1402495294-30737-1-git-send-email-drjones@redhat.com> References: <1402495294-30737-1-git-send-email-drjones@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Support format flags for field padding, such as "%08x", allowing register dumps to be easier on the eyes. Signed-off-by: Andrew Jones Reviewed-by: Christoffer Dall --- lib/printf.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/lib/printf.c b/lib/printf.c index 867eb1926f742..89308fb26b7d2 100644 --- a/lib/printf.c +++ b/lib/printf.c @@ -6,6 +6,11 @@ typedef struct pstream { int added; } pstream_t; +typedef struct strprops { + char pad; + int npad; +} strprops_t; + static void addchar(pstream_t *p, char c) { if (p->remain) { @@ -15,15 +20,35 @@ static void addchar(pstream_t *p, char c) ++p->added; } -void print_str(pstream_t *p, const char *s) +void print_str(pstream_t *p, const char *s, strprops_t props) { + const char *s_orig = s; + int npad = props.npad; + + if (npad > 0) { + npad -= strlen(s_orig); + while (npad > 0) { + addchar(p, props.pad); + --npad; + } + } + while (*s) addchar(p, *s++); + + if (npad < 0) { + props.pad = ' '; /* ignore '0' flag with '-' flag */ + npad += strlen(s_orig); + while (npad < 0) { + addchar(p, props.pad); + ++npad; + } + } } static char digits[16] = "0123456789abcdef"; -void print_int(pstream_t *ps, long long n, int base) +void print_int(pstream_t *ps, long long n, int base, strprops_t props) { char buf[sizeof(long) * 3 + 2], *p = buf; int s = 0, i; @@ -54,10 +79,11 @@ void print_int(pstream_t *ps, long long n, int base) *p = 0; - print_str(ps, buf); + print_str(ps, buf, props); } -void print_unsigned(pstream_t *ps, unsigned long long n, int base) +void print_unsigned(pstream_t *ps, unsigned long long n, int base, + strprops_t props) { char buf[sizeof(long) * 3 + 1], *p = buf; int i; @@ -80,7 +106,23 @@ void print_unsigned(pstream_t *ps, unsigned long long n, int base) *p = 0; - print_str(ps, buf); + print_str(ps, buf, props); +} + +static int fmtnum(const char **fmt) +{ + const char *f = *fmt; + int len = 0, num; + + if (*f == '-') + ++f, ++len; + + while (*f >= '0' && *f <= '9') + ++f, ++len; + + num = atol(*fmt); + *fmt += len; + return num; } int vsnprintf(char *buf, int size, const char *fmt, va_list va) @@ -93,6 +135,9 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va) while (*fmt) { char f = *fmt++; int nlong = 0; + strprops_t props; + memset(&props, 0, sizeof(props)); + props.pad = ' '; if (f != '%') { addchar(&s, f); @@ -110,41 +155,50 @@ int vsnprintf(char *buf, int size, const char *fmt, va_list va) case '\0': --fmt; break; + case '0': + props.pad = '0'; + ++fmt; + /* fall through */ + case '1'...'9': + case '-': + --fmt; + props.npad = fmtnum(&fmt); + goto morefmt; case 'l': ++nlong; goto morefmt; case 'd': switch (nlong) { case 0: - print_int(&s, va_arg(va, int), 10); + print_int(&s, va_arg(va, int), 10, props); break; case 1: - print_int(&s, va_arg(va, long), 10); + print_int(&s, va_arg(va, long), 10, props); break; default: - print_int(&s, va_arg(va, long long), 10); + print_int(&s, va_arg(va, long long), 10, props); break; } break; case 'x': switch (nlong) { case 0: - print_unsigned(&s, va_arg(va, unsigned), 16); + print_unsigned(&s, va_arg(va, unsigned), 16, props); break; case 1: - print_unsigned(&s, va_arg(va, unsigned long), 16); + print_unsigned(&s, va_arg(va, unsigned long), 16, props); break; default: - print_unsigned(&s, va_arg(va, unsigned long long), 16); + print_unsigned(&s, va_arg(va, unsigned long long), 16, props); break; } break; case 'p': - print_str(&s, "0x"); - print_unsigned(&s, (unsigned long)va_arg(va, void *), 16); + print_str(&s, "0x", props); + print_unsigned(&s, (unsigned long)va_arg(va, void *), 16, props); break; case 's': - print_str(&s, va_arg(va, const char *)); + print_str(&s, va_arg(va, const char *), props); break; default: addchar(&s, f);