@@ -230,9 +230,8 @@ PyObject * PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) {
230
230
return to_sulong (polyglot_from_string_n (u , size , SRC_CS ));
231
231
}
232
232
233
- #define AS_I64 (__arg__ ) (polyglot_fits_in_i64((__arg__)) ? polyglot_as_i64((__arg__)) : (int64_t)(__arg__))
234
-
235
233
MUST_INLINE PyObject * PyTruffle_Unicode_FromFormat (const char * fmt , va_list va ) {
234
+ va_list vacpy ;
236
235
size_t fmt_size = strlen (fmt ) + 1 ;
237
236
char * fmtcpy = strdup (fmt );
238
237
char * c = fmtcpy ;
@@ -242,22 +241,25 @@ MUST_INLINE PyObject* PyTruffle_Unicode_FromFormat(const char *fmt, va_list va)
242
241
char * full_buffer = buffer ;
243
242
244
243
void * variable = NULL ;
244
+ PyObject * tmp = NULL ;
245
245
char * allocated = NULL ; // points to the same as variable, if it has to be free'd
246
246
247
+ va_copy (vacpy , va );
248
+
247
249
while (c [0 ]) {
248
250
if (c [0 ] == '%' ) {
249
251
// we've reached the next directive, write until here
250
252
c [0 ] = '\0' ;
251
253
int bytes_written ;
252
254
if (variable != NULL ) {
253
- bytes_written = snprintf (buffer , remaining_space , fmtcpy , AS_I64 ( variable ) );
255
+ bytes_written = snprintf (buffer , remaining_space , fmtcpy , variable );
254
256
if (allocated != NULL ) {
255
257
free (allocated );
256
258
allocated = NULL ;
257
259
}
258
260
variable = NULL ;
259
261
} else {
260
- bytes_written = vsnprintf (buffer , remaining_space , fmtcpy , va );
262
+ bytes_written = vsnprintf (buffer , remaining_space , fmtcpy , vacpy );
261
263
}
262
264
remaining_space -= bytes_written ;
263
265
buffer += bytes_written ;
@@ -278,18 +280,64 @@ MUST_INLINE PyObject* PyTruffle_Unicode_FromFormat(const char *fmt, va_list va)
278
280
case 'R' :
279
281
if (converter == NULL ) converter = PyObject_Repr ;
280
282
c [1 ] = 's' ;
281
- allocated = variable = as_char_pointer (converter (va_arg (va , PyObject * )));
283
+ tmp = va_arg (va , PyObject * );
284
+ // just advance cursor on 'vacpy'
285
+ va_arg (vacpy , PyObject * );
286
+ allocated = variable = as_char_pointer (converter (tmp ));
282
287
break ;
288
+ case 'c' :
289
+ // This case should just treat it's argument as an integer
290
+ c [1 ] = 'd' ;
291
+ // intentionally fall-through
283
292
case 'd' :
284
- break ;
293
+ case 'i' :
294
+ case 'x' :
295
+ // just advance cursor on 'va'
296
+ va_arg (va , int );
297
+ break ;
298
+ case 'u' :
299
+ // just advance cursor on 'va'
300
+ va_arg (va , unsigned int );
301
+ break ;
302
+ case 'l' :
303
+ // 'c[2]' is guaranteed to be a correct memory access since
304
+ // it will in the worst case be '\0'.
305
+ switch (c [2 ]) {
306
+ // %ld, %li
307
+ case 'd' :
308
+ case 'i' :
309
+ // just advance cursor on 'va'
310
+ va_arg (va , long );
311
+ break ;
312
+ // %lu
313
+ case 'u' :
314
+ // just advance cursor on 'va'
315
+ va_arg (va , unsigned long );
316
+ // %ll?
317
+ case 'l' :
318
+ // just advance cursor on 'va'
319
+ va_arg (va , long long );
320
+ }
321
+ break ;
322
+ case 'z' :
323
+ // just advance cursor on 'va'
324
+ va_arg (va , Py_ssize_t );
325
+ break ;
326
+ case 's' :
327
+ // just advance cursor on 'va'
328
+ va_arg (va , char * );
329
+ break ;
330
+ case 'p' :
331
+ // just advance cursor on 'va'
332
+ va_arg (va , void * );
333
+ break ;
285
334
case '%' :
286
335
// literal %
287
336
break ;
288
- case 'c' :
289
- // This case should just treat it's argument as an integer
290
- c [1 ] = 'd' ;
291
337
default :
292
338
variable = va_arg (va , PyObject * );
339
+ // just advance cursor on 'vacpy'
340
+ va_arg (vacpy , PyObject * );
293
341
}
294
342
// skip over next char, we checked it
295
343
c += 1 ;
@@ -299,16 +347,17 @@ MUST_INLINE PyObject* PyTruffle_Unicode_FromFormat(const char *fmt, va_list va)
299
347
300
348
// write the remaining buffer
301
349
if (variable != NULL ) {
302
- snprintf (buffer , remaining_space , fmtcpy , AS_I64 ( variable ) );
350
+ snprintf (buffer , remaining_space , fmtcpy , variable );
303
351
if (allocated ) {
304
352
free (allocated );
305
353
}
306
354
} else {
307
- vsnprintf (buffer , remaining_space , fmtcpy , va );
355
+ vsnprintf (buffer , remaining_space , fmtcpy , vacpy );
308
356
}
309
357
310
358
PyObject * result = PyUnicode_FromString (full_buffer );
311
359
free (full_buffer );
360
+ va_end (vacpy );
312
361
return result ;
313
362
}
314
363
0 commit comments