Skip to content

Commit 198876f

Browse files
committed
mpprint: Rework integer vararg handling.
This adds support for %llx (needed by XINT_FMT for printing cell objects) and incidentally support for capitalized output of %P. Signed-off-by: Jeff Epler <jepler@gmail.com>
1 parent a7842a7 commit 198876f

File tree

1 file changed

+49
-38
lines changed

1 file changed

+49
-38
lines changed

py/mpprint.c

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -446,16 +446,26 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
446446
}
447447
}
448448

449-
// parse long specifiers (only for LP64 model where they make a difference)
450-
#ifndef __LP64__
451-
const
452-
#endif
449+
// parse long and long long specifiers (only where they make a difference)
450+
#if LONG_MAX > INT_MAX
453451
bool long_arg = false;
452+
#endif
453+
454+
#if (MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D) || defined(_WIN64)
455+
bool long_long_arg = false;
456+
#endif
457+
454458
if (*fmt == 'l') {
455459
++fmt;
456-
#ifdef __LP64__
460+
#if LONG_MAX > INT_MAX
457461
long_arg = true;
458462
#endif
463+
#if (MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D) || defined(_WIN64)
464+
if (*fmt == 'l') {
465+
++fmt;
466+
long_long_arg = true;
467+
}
468+
#endif
459469
}
460470

461471
if (*fmt == '\0') {
@@ -501,35 +511,48 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
501511
chrs += mp_print_strn(print, str, len, flags, fill, width);
502512
break;
503513
}
504-
case 'd': {
505-
mp_int_t val;
506-
if (long_arg) {
507-
val = va_arg(args, long int);
508-
} else {
509-
val = va_arg(args, int);
510-
}
511-
chrs += mp_print_int(print, val, 1, 10, 'a', flags, fill, width);
512-
break;
513-
}
514+
case 'p':
515+
case 'P':
516+
case 'd':
514517
case 'u':
515518
case 'x':
516519
case 'X': {
517-
int base = 16 - ((*fmt + 1) & 6); // maps char u/x/X to base 10/16/16
518-
char fmt_c = (*fmt & 0xf0) - 'P' + 'A'; // maps char u/x/X to char a/a/A
520+
char fmt_chr = *fmt;
519521
mp_uint_t val;
520-
if (long_arg) {
521-
val = va_arg(args, unsigned long int);
522+
if (fmt_chr == 'p' || fmt_chr == 'P') {
523+
val = va_arg(args, intptr_t);
524+
}
525+
#if (MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D) || defined(_WIN64)
526+
else if (long_long_arg) {
527+
val = va_arg(args, unsigned long long);
528+
}
529+
#endif
530+
#if LONG_MAX > INT_MAX
531+
else if (long_arg) {
532+
if (sizeof(long) != sizeof(mp_uint_t) && fmt_chr == 'd') {
533+
val = va_arg(args, long);
534+
} else {
535+
val = va_arg(args, unsigned long);
536+
}
537+
}
538+
#endif
539+
else {
540+
if (sizeof(int) != sizeof(mp_uint_t) && fmt_chr == 'd') {
541+
val = va_arg(args, int);
542+
} else {
543+
val = va_arg(args, unsigned);
544+
}
545+
}
546+
int base;
547+
char fmt_c = (fmt_chr & 0xf0) - 'P' + 'A'; // maps char u/x/X to char a/a/A
548+
if (fmt_chr == 'd' || fmt_chr == 'u') {
549+
base = 10;
522550
} else {
523-
val = va_arg(args, unsigned int);
551+
base = 16;
524552
}
525-
chrs += mp_print_int(print, val, 0, base, fmt_c, flags, fill, width);
553+
chrs += mp_print_int(print, val, fmt_chr == 'd', base, fmt_c, flags, fill, width);
526554
break;
527555
}
528-
case 'p':
529-
case 'P': // don't bother to handle upcase for 'P'
530-
// Use unsigned long int to work on both ILP32 and LP64 systems
531-
chrs += mp_print_int(print, va_arg(args, unsigned long int), 0, 16, 'a', flags, fill, width);
532-
break;
533556
#if MICROPY_PY_BUILTINS_FLOAT
534557
case 'e':
535558
case 'E':
@@ -545,18 +568,6 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
545568
#endif
546569
break;
547570
}
548-
#endif
549-
// Because 'l' is eaten above, another 'l' means %ll. We need to support
550-
// this length specifier for OBJ_REPR_D (64-bit NaN boxing).
551-
// TODO Either enable this unconditionally, or provide a specific config var.
552-
#if (MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D) || defined(_WIN64)
553-
case 'l': {
554-
unsigned long long int arg_value = va_arg(args, unsigned long long int);
555-
++fmt;
556-
assert(*fmt == 'u' || *fmt == 'd' || !"unsupported fmt char");
557-
chrs += mp_print_int(print, arg_value, *fmt == 'd', 10, 'a', flags, fill, width);
558-
break;
559-
}
560571
#endif
561572
default:
562573
// if it's not %% then it's an unsupported format character

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy