@@ -446,16 +446,26 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
446
446
}
447
447
}
448
448
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
453
451
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
+
454
458
if (* fmt == 'l' ) {
455
459
++ fmt ;
456
- #ifdef __LP64__
460
+ #if LONG_MAX > INT_MAX
457
461
long_arg = true;
458
462
#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
459
469
}
460
470
461
471
if (* fmt == '\0' ) {
@@ -501,35 +511,48 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
501
511
chrs += mp_print_strn (print , str , len , flags , fill , width );
502
512
break ;
503
513
}
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' :
514
517
case 'u' :
515
518
case 'x' :
516
519
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 ;
519
521
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' +<
10000
/span> 'A' ; // maps char u/x/X to char a/a/A
548
+ if (fmt_chr == 'd' || fmt_chr == 'u' ) {
549
+ base = 10 ;
522
550
} else {
523
- val = va_arg ( args , unsigned int ) ;
551
+ base = 16 ;
524
552
}
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 );
526
554
break ;
527
555
}
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 ;
533
556
#if MICROPY_PY_BUILTINS_FLOAT
534
557
case 'e' :
535
558
case 'E' :
@@ -545,18 +568,6 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
545
568
#endif
546
569
break ;
547
570
}
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
- }
560
571
#endif
561
572
default :
562
573
// if it's not %% then it's an unsupported format character
0 commit comments