From patchwork Thu Apr 10 16:56:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 3963581 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 1CFE9C0DA2 for ; Thu, 10 Apr 2014 16:57:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 49DDD20825 for ; Thu, 10 Apr 2014 16:57:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4D1C520819 for ; Thu, 10 Apr 2014 16:57:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758781AbaDJQ5j (ORCPT ); Thu, 10 Apr 2014 12:57:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53102 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758764AbaDJQ5a (ORCPT ); Thu, 10 Apr 2014 12:57:30 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s3AGvSo5023807 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 10 Apr 2014 12:57:28 -0400 Received: from hawk.usersys.redhat.com.com (dhcp-1-170.brq.redhat.com [10.34.1.170]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s3AGv4Uv021128; Thu, 10 Apr 2014 12:57:26 -0400 From: Andrew Jones To: kvmarm@lists.cs.columbia.edu, kvm@vger.kernel.org Cc: christoffer.dall@linaro.org Subject: [PATCH v4 14/19] printf: support field padding Date: Thu, 10 Apr 2014 18:56:55 +0200 Message-Id: <1397149020-3501-15-git-send-email-drjones@redhat.com> In-Reply-To: <1397149020-3501-1-git-send-email-drjones@redhat.com> References: <1397149020-3501-1-git-send-email-drjones@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 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 --- 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);