@@ -468,18 +468,21 @@ typedef struct _build_stack {
468
468
struct _build_stack * prev ;
469
469
} build_stack ;
470
470
471
- PyObject * _Py_BuildValue_SizeT (const char * format , ... ) {
472
- # define ARG polyglot_get_arg(value_idx)
473
- # define APPEND_VALUE ( list , value ) PyList_Append(list, value); value_idx++
471
+ PyObject * Py_VaBuildValue (const char * format , va_list va ) {
472
+ return _Py_VaBuildValue_SizeT ( format , va );
473
+ }
474
474
475
+ PyObject * _Py_VaBuildValue_SizeT (const char * format , va_list va ) {
475
476
PyObject * (* converter )(void * ) = NULL ;
476
477
char argchar [2 ] = {'\0' };
477
- unsigned int value_idx = 1 ;
478
478
unsigned int format_idx = 0 ;
479
479
build_stack * v = (build_stack * )calloc (1 , sizeof (build_stack ));
480
480
build_stack * next ;
481
481
v -> list = PyList_New (0 );
482
482
483
+ char * char_arg ;
484
+ void * void_arg ;
485
+
483
486
char c = format [format_idx ];
484
487
while (c != '\0' ) {
485
488
PyObject * list = v -> list ;
@@ -488,38 +491,38 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
488
491
case 's' :
489
492
case 'z' :
490
493
case 'U' :
494
+ char_arg = va_arg (va , char * );
491
495
if (format [format_idx + 1 ] == '#' ) {
492
- int size = ( int ) polyglot_get_arg ( value_idx + 1 );
493
- if (ARG == NULL ) {
494
- APPEND_VALUE (list , Py_None );
496
+ int size = va_arg ( va , int );
497
+ if (char_arg == NULL ) {
498
+ PyList_Append (list , Py_None );
495
499
} else {
496
- APPEND_VALUE (list , PyUnicode_FromStringAndSize (( char * ) ARG , size ));
500
+ PyList_Append (list , PyUnicode_FromStringAndSize (char_arg , size ));
497
501
}
498
- value_idx ++ ; // skip length argument
499
502
format_idx ++ ;
500
503
} else {
501
- if (ARG == NULL ) {
502
- APPEND_VALUE (list , Py_None );
504
+ if (char_arg == NULL ) {
505
+ PyList_Append (list , Py_None );
503
506
} else {
504
- APPEND_VALUE (list , PyUnicode_FromString (( char * ) ARG ));
507
+ PyList_Append (list , PyUnicode_FromString (char_arg ));
505
508
}
506
509
}
507
510
break ;
508
511
case 'y' :
512
+ char_arg = va_arg (va , char * );
509
513
if (format [format_idx + 1 ] == '#' ) {
510
- int size = ( int ) polyglot_get_arg ( value_idx + 1 );
511
- if (ARG == NULL ) {
512
- APPEND_VALUE (list , Py_None );
514
+ int size = va_arg ( va , int );
515
+ if (char_arg == NULL ) {
516
+ PyList_Append (list , Py_None );
513
517
} else {
514
- APPEND_VALUE (list , PyBytes_FromStringAndSize (( char * ) ARG , size ));
518
+ PyList_Append (list , PyBytes_FromStringAndSize (char_arg , size ));
515
519
}
516
- value_idx ++ ; // skip length argument
517
520
format_idx ++ ;
518
521
} else {
519
- if (ARG == NULL ) {
520
- APPEND_VALUE (list , Py_None );
522
+ if (char_arg == NULL ) {
523
+ PyList_Append (list , Py_None );
521
524
} else {
522
- APPEND_VALUE (list , PyBytes_FromString (( char * ) ARG ));
525
+ PyList_Append (list , PyBytes_FromString (char_arg ));
523
526
}
524
527
}
525
528
break ;
@@ -529,63 +532,68 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
529
532
case 'i' :
530
533
case 'b' :
531
534
case 'h' :
532
- APPEND_VALUE (list , PyLong_FromLong (( int )ARG ));
535
+ PyList_Append (list , PyLong_FromLong (va_arg ( va , int )));
533
536
break ;
534
537
case 'l' :
535
- APPEND_VALUE (list , PyLong_FromLong (( long )ARG ));
538
+ PyList_Append (list , PyLong_FromLong (va_arg ( va , long )));
536
539
break ;
537
540
case 'B' :
538
541
case 'H' :
539
542
case 'I' :
540
- APPEND_VALUE (list , PyLong_FromUnsignedLong (( unsigned int )ARG ));
543
+ PyList_Append (list , PyLong_FromUnsignedLong (va_arg ( va , unsigned int )));
541
544
break ;
542
545
case 'k' :
543
- APPEND_VALUE (list , PyLong_FromUnsignedLong (( unsigned long )ARG ));
546
+ PyList_Append (list , PyLong_FromUnsignedLong (va_arg ( va , unsigned long )));
544
547
break ;
545
548
case 'L' :
546
- APPEND_VALUE (list , PyLong_FromLongLong (( long long )ARG ));
549
+ PyList_Append (list , PyLong_FromLongLong (va_arg ( va , long long )));
547
550
break ;
548
551
case 'K' :
549
- APPEND_VALUE (list , PyLong_FromLongLong (( unsigned long long )ARG ));
552
+ PyList_Append (list , PyLong_FromLongLong (va_arg ( va , unsigned long long)));
550
553
break ;
551
554
case 'n' :
552
- APPEND_VALUE (list , PyLong_FromSsize_t (( Py_ssize_t )ARG ));
555
+ PyList_Append (list , PyLong_FromSsize_t (va_arg ( va , Py_ssize_t )));
553
556
break ;
554
557
case 'c' :
555
- argchar [0 ] = (char )ARG ;
556
- APPEND_VALUE (list , PyBytes_FromStringAndSize (argchar , 1 ));
558
+ // note: a vararg char is promoted to int according to the C standard
559
+ argchar [0 ] = va_arg (va , int );
560
+ PyList_Append (list , PyBytes_FromStringAndSize (argchar , 1 ));
557
561
break ;
558
562
case 'C' :
559
- argchar [0 ] = (char )ARG ;
560
- APPEND_VALUE (list , polyglot_from_string (argchar , "ascii" ));
563
+ // note: a vararg char is promoted to int according to the C standard
564
+ argchar [0 ] = va_arg (va , int );
565
+ PyList_Append (list , polyglot_from_string (argchar , "ascii" ));
561
566
break ;
562
567
case 'd' :
563
568
case 'f' :
564
- APPEND_VALUE (list , PyFloat_FromDouble (( double )( unsigned long long ) ARG ));
569
+ PyList_Append (list , PyFloat_FromDouble (va_arg ( va , double )));
565
570
break ;
566
571
case 'D' :
567
572
fprintf (stderr , "error: unsupported format 'D'\n" );
568
573
break ;
569
574
case 'O' :
570
- if (format [format_idx + 1 ] == '&' ) {
571
- converter = polyglot_get_arg (value_idx + 1 );
572
- }
573
575
case 'S' :
574
576
case 'N' :
575
- if (ARG == NULL ) {
577
+ void_arg = va_arg (va , void * );
578
+ if (c == 'O' ) {
579
+ if (format [format_idx + 1 ] == '&' ) {
580
+ converter = va_arg (va , void * );
581
+ }
582
+ }
583
+
584
+ if (void_arg == NULL ) {
576
585
if (!PyErr_Occurred ()) {
577
586
/* If a NULL was passed because a call that should have constructed a value failed, that's OK,
578
587
* and we pass the error on; but if no error occurred it's not clear that the caller knew what she was doing. */
579
588
PyErr_SetString (PyExc_SystemError , "NULL object passed to Py_BuildValue" );
580
589
}
581
590
return NULL ;
582
591
} else if (converter != NULL ) {
583
- APPEND_VALUE (list , converter (ARG ));
592
+ PyList_Append (list , converter (void_arg ));
584
593
converter = NULL ;
585
- value_idx ++ ; // skip converter argument
586
594
format_idx ++ ;
587
595
} else {
588
- APPEND_VALUE (list , ARG );
596
+ PyList_Append (list , ( PyObject * ) void_arg );
589
597
}
590
598
break ;
591
599
case '(' :
@@ -648,9 +656,6 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
648
656
c = format [++ format_idx ];
649
657
}
650
658
651
- # undef APPEND_VALUE
652
- # undef ARG
653
-
654
659
if (v -> prev != NULL ) {
655
660
PyErr_SetString (PyExc_SystemError , "dangling group in Py_BuildValue" );
656
661
return NULL ;
@@ -667,6 +672,22 @@ PyObject* _Py_BuildValue_SizeT(const char *format, ...) {
667
672
}
668
673
}
669
674
675
+ PyObject * Py_BuildValue (const char * format , ...) {
676
+ va_list va ;
677
+ va_start (va , format );
678
+ PyObject * result = Py_VaBuildValue (format , va );
679
+ va_end (va );
680
+ return result ;
681
+ }
682
+
683
+ PyObject * _Py_BuildValue_SizeT (const char * format , ...) {
684
+ va_list va ;
685
+ va_start (va , format );
686
+ PyObject * result = _Py_VaBuildValue_SizeT (format , va );
687
+ va_end (va );
688
+ return result ;
689
+ }
690
+
670
691
// taken from CPython "Python/modsupport.c"
671
692
int PyModule_AddStringConstant (PyObject * m , const char * name , const char * value ) {
672
693
PyObject * o = PyUnicode_FromString (value );
0 commit comments