@@ -197,6 +197,9 @@ private static void doParsingExploded(String funName, PTuple argv, Object kwds,
197
197
198
198
private static ParserState convertArg (ParserState state , Object kwds , char [] format , int format_idx , Object kwdnames , Object varargs , ConvertArgNode convertArgNode ,
199
199
PRaiseNativeNode raiseNode ) throws InteropException , ParseArgumentsException {
200
+ if (state .skip ) {
201
+ return state .skipped ();
202
+ }
200
203
char c = format [format_idx ];
201
204
switch (c ) {
202
205
case FORMAT_LOWER_S :
@@ -300,42 +303,52 @@ static char[] getChars(String format) {
300
303
static final class ParserState {
301
304
private final String funName ;
302
305
private final int outIndex ;
306
+ private final boolean skip ; // skip the next format char
303
307
private final boolean restOptional ;
304
308
private final boolean restKeywordsOnly ;
305
309
private final PositionalArgStack v ;
306
310
private final CExtContext nativeContext ;
307
311
308
312
ParserState (String funName , PositionalArgStack v , CExtContext nativeContext ) {
309
- this (funName , 0 , false , false , v , nativeContext );
313
+ this (funName , 0 , false , false , false , v , nativeContext );
310
314
}
311
315
312
- private ParserState (String funName , int outIndex , boolean restOptional , boolean restKeywordsOnly , PositionalArgStack v , CExtContext nativeContext ) {
316
+ private ParserState (String funName , int outIndex , boolean skip , boolean restOptional , boolean restKeywordsOnly , PositionalArgStack v , CExtContext nativeContext ) {
313
317
this .funName = funName ;
314
318
this .outIndex = outIndex ;
319
+ this .skip = skip ;
315
320
this .restOptional = restOptional ;
316
321
this .restKeywordsOnly = restKeywordsOnly ;
317
322
this .v = v ;
318
323
this .nativeContext = nativeContext ;
319
324
}
320
325
321
326
ParserState incrementOutIndex () {
322
- return new ParserState (funName , outIndex + 1 , restOptional , restKeywordsOnly , v , nativeContext );
327
+ return new ParserState (funName , outIndex + 1 , false , restOptional , restKeywordsOnly , v , nativeContext );
323
328
}
324
329
325
330
ParserState restOptional () {
326
- return new ParserState (funName , outIndex , true , restKeywordsOnly , v , nativeContext );
331
+ return new ParserState (funName , outIndex , false , true , restKeywordsOnly , v , nativeContext );
327
332
}
328
333
329
334
ParserState restKeywordsOnly () {
330
- return new ParserState (funName , outIndex , restOptional , true , v , nativeContext );
335
+ return new ParserState (funName , outIndex , false , restOptional , true , v , nativeContext );
331
336
}
332
337
333
338
ParserState open (PositionalArgStack nestedArgs ) {
334
- return new ParserState (funName , outIndex , restOptional , false , nestedArgs , nativeContext );
339
+ return new ParserState (funName , outIndex , false , restOptional , false , nestedArgs , nativeContext );
340
+ }
341
+
342
+ ParserState skip () {
343
+ return new ParserState (funName , outIndex , true , restOptional , restKeywordsOnly , v , nativeContext );
344
+ }
345
+
346
+ ParserState skipped () {
347
+ return new ParserState (funName , outIndex , false , restOptional , restKeywordsOnly , v , nativeContext );
335
348
}
336
349
337
350
ParserState close () {
338
- return new ParserState (funName , outIndex , restOptional , false , v .prev , nativeContext );
351
+ return new ParserState (funName , outIndex , false , restOptional , false , v .prev , nativeContext );
339
352
}
340
353
341
354
}
@@ -514,17 +527,39 @@ static ParserState doUnicode(ParserState state, Object kwds, @SuppressWarnings("
514
527
return state .incrementOutIndex ();
515
528
}
516
529
530
+ @ SuppressWarnings ("unused" )
517
531
@ Specialization (guards = "c == FORMAT_LOWER_E" )
518
- static ParserState doEncodedString (ParserState state , Object kwds , @ SuppressWarnings ("unused" ) char c , @ SuppressWarnings ("unused" ) char [] format , @ SuppressWarnings ("unused" ) int format_idx ,
532
+ static ParserState doEncodedString (ParserState stateIn , Object kwds , @ SuppressWarnings ("unused" ) char c , @ SuppressWarnings ("unused" ) char [] format , @ SuppressWarnings ("unused" ) int format_idx ,
519
533
Object kwdnames , @ SuppressWarnings ("unused" ) Object varargs ,
534
+ @ Cached AsCharPointerNode asCharPointerNode ,
535
+ @ Cached GetVaArgsNode getVaArgNode ,
536
+ @ Cached (value = "createTJ(stateIn)" , uncached = "getUncachedTJ(stateIn)" ) CExtToJavaNode argToJavaNode ,
537
+ @ CachedLibrary (limit = "3" ) PythonObjectLibrary lib ,
520
538
@ Shared ("getArgNode" ) @ Cached GetArgNode getArgNode ,
539
+ @ Shared ("writeOutVarNode" ) @ Cached WriteOutVarNode writeOutVarNode ,
521
540
@ Shared ("raiseNode" ) @ Cached PRaiseNativeNode raiseNode ) throws InteropException , ParseArgumentsException {
522
-
541
+ ParserState state = stateIn ;
523
542
Object arg = getArgNode .execute (state , kwds , kwdnames , state .restKeywordsOnly );
524
543
if (!skipOptionalArg (arg , state .restOptional )) {
525
- throw raise (raiseNode , TypeError , ErrorMessages .ESTAR_FORMAT_SPECIFIERS_NOT_ALLOWED , arg );
544
+ Object encoding = getVaArgNode .getCharPtr (varargs , state .outIndex );
545
+ state = state .incrementOutIndex ();
546
+ final boolean recodeStrings ;
547
+ if (isLookahead (format , format_idx , 's' )) {
548
+ recodeStrings = true ;
549
+ } else if (isLookahead (format , format_idx , 't' )) {
550
+ recodeStrings = false ;
551
+ } else {
552
+ throw raise (raiseNode , TypeError , ErrorMessages .ESTAR_FORMAT_SPECIFIERS_NOT_ALLOWED , arg );
553
+ }
554
+ // XXX: TODO: actual support for the en-/re-coding of objects, proper error handling
555
+ writeOutVarNode .writePyObject (varargs , state .outIndex , asCharPointerNode .execute (arg ));
556
+ if (isLookahead (format , format_idx + 1 , '#' )) {
557
+ final int size = lib .length (argToJavaNode .execute (state .nativeContext , arg ));
558
+ state = state .incrementOutIndex ();
559
+ writeOutVarNode .writeInt64 (varargs , state .outIndex , size );
560
+ }
526
561
}
527
- return state ;
562
+ return state . incrementOutIndex (). skip (); // e is always followed by 's' or 't', which me must skip
528
563
}
529
564
530
565
@ Specialization (guards = "c == FORMAT_LOWER_B" )
0 commit comments