This is the mail archive of the
cygwin-cvs@cygwin.com
mailing list for the Cygwin project.
[newlib-cygwin] Cygwin: small_s[w]printf: add '_' modifier to print lower case hex digits
- From: Corinna Vinschen <corinna at sourceware dot org>
- To: cygwin-cvs at sourceware dot org
- Date: 2 Mar 2018 17:18:18 -0000
- Subject: [newlib-cygwin] Cygwin: small_s[w]printf: add '_' modifier to print lower case hex digits
https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=488221cf5c5263ba1a82391c80c00b8157e362cc
commit 488221cf5c5263ba1a82391c80c00b8157e362cc
Author: Corinna Vinschen <corinna@vinschen.de>
Date: Fri Mar 2 18:09:35 2018 +0100
Cygwin: small_s[w]printf: add '_' modifier to print lower case hex digits
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diff:
---
winsup/cygwin/smallprint.cc | 120 +++++++++++++++++++++++++++-----------------
1 file changed, 74 insertions(+), 46 deletions(-)
diff --git a/winsup/cygwin/smallprint.cc b/winsup/cygwin/smallprint.cc
index 8553f70..9a4a1c8 100644
--- a/winsup/cygwin/smallprint.cc
+++ b/winsup/cygwin/smallprint.cc
@@ -13,13 +13,46 @@ details. */
#include <ctype.h>
#include <wchar.h>
+/*
+ Meaning of format conversion specifiers. If 'l' isn't explicitely mentioned,
+ it's ignored!
+
+ 0 modifier: pad with zero instead of spaces
+ 0-9 modifier: field length
+ + modifier: always add sign
+ l modifier to d, o, R, u, x, y: 4 byte on 32 bit, 8 byte on 64 bit
+ l modifier to s, S, W: non-ASCII tweaking
+ _ modifier: print lower case hex chars a-f instead of A-F
+
+ c char
+ C WCHAR/wchar_t
+ d signed int, 4 byte
+ D signed long long, 8 byte
+ E GetLastError
+ o octal unsigned int, 4 byte
+ O octal unsigned long long, 8 byte
+ p address
+ P process name
+ R return value, 4 byte.
+ s char *
+ S PUNICODE_STRING
+ u unsigned int, 4 byte
+ U unsigned long long, 8 byte
+ W PWCHAR/wchar_t *
+ x hex unsigned int, 4 byte
+ X hex unsigned long long, 8 byte
+ y 0x hex unsigned int, 4 byte
+ Y 0x hex unsigned long long, 8 byte
+*/
+
#define LLMASK (0xffffffffffffffffULL)
#define LMASK (0xffffffff)
#define rnarg(dst, base, dosign, len, pad) __rn ((dst), (base), (dosign), va_arg (ap, int32_t), len, pad, LMASK)
#define rnargLL(dst, base, dosign, len, pad) __rn ((dst), (base), (dosign), va_arg (ap, uint64_t), len, pad, LLMASK)
-static const char hex_str[] = "0123456789ABCDEF";
+static const char hex_str_upper[] = "0123456789ABCDEF";
+static const char hex_str_lower[] = "0123456789abcdef";
class tmpbuf
{
@@ -56,6 +89,15 @@ __rn (char *dst, int base, int dosign, long long val, int len, int pad, unsigned
unsigned long long uval = 0;
char res[20];
int l = 0;
+ const char *hex_str;
+
+ if (base < 0)
+ {
+ base = -base;
+ hex_str = hex_str_lower;
+ }
+ else
+ hex_str = hex_str_upper;
if (dosign && val < 0)
{
@@ -88,40 +130,6 @@ __rn (char *dst, int base, int dosign, long long val, int len, int pad, unsigned
return dst;
}
-/*
- Meaning of format conversion specifiers. If 'l' isn't explicitely mentioned,
- it's ignored!
-
- c char
- C WCHAR/wchar_t
- d signed int, 4 byte
- ld signed long, 4 byte on 32 bit, 8 byte on 64 bit
- D signed long long, 8 byte
- E GetLastError
- o octal unsigned int, 4 byte
- lo octal unsigned long, 4 byte on 32 bit, 8 byte on 64 bit
- O octal unsigned long long, 8 byte
- p address
- P process name
- R return value, 4 byte.
- lR return value, 4 byte on 32 bit, 8 byte on 64 bit.
- s char *
- ls char * w/ non-ASCII tweaking
- S PUNICODE_STRING
- lS PUNICODE_STRING w/ non-ASCII tweaking
- u unsigned int, 4 byte
- lu unsigned long, 4 byte on 32 bit, 8 byte on 64 bit
- U unsigned long long, 8 byte
- W PWCHAR/wchar_t *
- lW PWCHAR/wchar_t * w/ non-ASCII tweaking
- x hex unsigned int, 4 byte
- lx hex unsigned long, 4 byte on 32 bit, 8 byte on 64 bit
- X hex unsigned long long, 8 byte
- y 0x hex unsigned int, 4 byte
- ly 0x hex unsigned long, 4 byte on 32 bit, 8 byte on 64 bit
- Y 0x hex unsigned long long, 8 byte
-*/
-
int
__small_vsprintf (char *dst, const char *fmt, va_list ap)
{
@@ -139,6 +147,9 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap)
{
int i, n = 0x7fff;
bool l_opt = false;
+ /* set to -1 on '_', indicates upper (1)/lower(-1) case */
+ int h_opt = 1;
+ const char *hex_str = hex_str_upper;
if (*fmt != '%')
*dst++ = *fmt++;
else
@@ -170,13 +181,16 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap)
continue;
}
/*FALLTHRU*/
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
+ case '1' ... '9':
len = len * 10 + (c - '0');
continue;
case 'l':
l_opt = true;
continue;
+ case '_':
+ h_opt = -1;
+ hex_str = hex_str_lower;
+ continue;
case 'c':
{
unsigned char c = (va_arg (ap, int) & 0xff);
@@ -186,7 +200,7 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap)
{
*dst++ = '0';
*dst++ = 'x';
- dst = __rn (dst, 16, 0, c, len, pad, LMASK);
+ dst = __rn (dst, h_opt * 16, 0, c, len, pad, LMASK);
}
}
break;
@@ -249,7 +263,7 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap)
goto gen_decimalLL;
#endif
gen_decimal:
- dst = rnarg (dst, base, addsign, len, pad);
+ dst = rnarg (dst, h_opt * base, addsign, len, pad);
break;
case 'D':
base = 10;
@@ -270,15 +284,15 @@ gen_decimal:
base = 16;
addsign = 0;
gen_decimalLL:
- dst = rnargLL (dst, base, addsign, len, pad);
+ dst = rnargLL (dst, h_opt * base, addsign, len, pad);
break;
case 'p':
*dst++ = '0';
*dst++ = 'x';
#ifdef __x86_64__
- dst = rnargLL (dst, 16, 0, len, pad);
+ dst = rnargLL (dst, h_opt * 16, 0, len, pad);
#else
- dst = rnarg (dst, 16, 0, len, pad);
+ dst = rnarg (dst, h_opt * 16, 0, len, pad);
#endif
break;
case '.':
@@ -432,6 +446,15 @@ __wrn (PWCHAR dst, int base, int dosign, long long val, int len, int pad, unsign
unsigned long long uval = 0;
WCHAR res[20];
int l = 0;
+ const char *hex_str;
+
+ if (base < 0)
+ {
+ base = -base;
+ hex_str = hex_str_lower;
+ }
+ else
+ hex_str = hex_str_upper;
if (dosign && val < 0)
{
@@ -483,6 +506,8 @@ __small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap)
#ifdef __x86_64__
bool l_opt = false;
#endif
+ /* set to -1 on '_', indicates upper (1)/lower(-1) case */
+ int h_opt = 1;
if (*fmt != L'%')
*dst++ = *fmt++;
else
@@ -522,6 +547,9 @@ __small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap)
l_opt = true;
#endif
continue;
+ case '_':
+ h_opt = -1;
+ continue;
case L'c':
case L'C':
*dst++ = va_arg (ap, unsigned);
@@ -576,7 +604,7 @@ __small_vswprintf (PWCHAR dst, const WCHAR *fmt, va_list ap)
goto gen_decimalLL;
#endif
gen_decimal:
- dst = wrnarg (dst, base, addsign, len, pad);
+ dst = wrnarg (dst, h_opt * base, addsign, len, pad);
break;
case 'D':
base = 10;
@@ -597,15 +625,15 @@ gen_decimal:
base = 16;
addsign = 0;
gen_decimalLL:
- dst = wrnargLL (dst, base, addsign, len, pad);
+ dst = wrnargLL (dst, h_opt * base, addsign, len, pad);
break;
case L'p':
*dst++ = L'0';
*dst++ = L'x';
#ifdef __x86_64__
- dst = wrnargLL (dst, 16, 0, len, pad);
+ dst = wrnargLL (dst, h_opt * 16, 0, len, pad);
#else
- dst = wrnarg (dst, 16, 0, len, pad);
+ dst = wrnarg (dst, h_opt * 16, 0, len, pad);
#endif
break;
case L'P':