@@ -511,7 +511,12 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) {
511
511
if (sm ) {
512
512
/* Got a typemap. Need to only merge attributes for methods that match our signature */
513
513
Iterator ki ;
514
+ Hash * deferred_add ;
514
515
match = 1 ;
516
+
517
+ /* Since typemap_register can modify the `sm` hash, we *cannot* call typemap_register while iterating over sm.
518
+ * Create a temporary hash of typemaps to add immediately after. */
519
+ deferred_add = NewHash ();
515
520
for (ki = First (sm ); ki .key ; ki = Next (ki )) {
516
521
/* Check for a signature match with the source signature */
517
522
if ((count_args (ki .key ) == narg ) && (Strstr (ki .key , ssig ))) {
@@ -521,34 +526,36 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) {
521
526
Replace (nkey , ssig , dsig , DOH_REPLACE_ANY );
522
527
523
528
/* Make sure the typemap doesn't already exist in the target map */
524
-
525
529
oldm = Getattr (tm , nkey );
526
530
if (!oldm || (!Getattr (tm , "code" ))) {
527
531
String * code ;
528
- ParmList * locals ;
529
- ParmList * kwargs ;
530
532
Hash * sm1 = ki .item ;
531
533
532
534
code = Getattr (sm1 , "code" );
533
- locals = Getattr (sm1 , "locals" );
534
- kwargs = Getattr (sm1 , "kwargs" );
535
535
if (code ) {
536
- String * src_str = ParmList_str_multibrackets (src );
537
- String * dest_str = ParmList_str_multibrackets (dest );
538
- String * source_directive = NewStringf ("apply %s { %s }" , src_str , dest_str );
539
-
540
536
Replace (nkey , dsig , "" , DOH_REPLACE_ANY );
541
537
Replace (nkey , "tmap:" , "" , DOH_REPLACE_ANY );
542
- typemap_register (nkey , dest , code , locals , kwargs , source_directive );
543
-
544
- Delete (source_directive );
545
- Delete (dest_str );
546
- Delete (src_str );
538
+ Setattr (deferred_add , nkey , sm1 );
547
539
}
548
540
}
549
541
Delete (nkey );
550
542
}
551
543
}
544
+
545
+ /* After assembling the key/item pairs, add the resulting typemaps */
546
+ for (ki = First (deferred_add ); ki .key ; ki = Next (ki )) {
547
+ Hash * sm1 = ki .item ;
548
+ String * src_str = ParmList_str_multibrackets (src );
549
+ String * dest_str = ParmList_str_multibrackets (dest );
550
+ String * source_directive = NewStringf ("apply %s { %s }" , src_str , dest_str );
551
+
552
+ typemap_register (ki .key , dest , Getattr (sm1 , "code" ), Getattr (sm1 , "locals" ), Getattr (sm1 , "kwargs" ), source_directive );
553
+
554
+ Delete (source_directive );
555
+ Delete (dest_str );
556
+ Delete (src_str );
557
+ }
558
+ Delete (deferred_add );
552
559
}
553
560
Delete (ssig );
554
561
Delete (dsig );
@@ -2084,14 +2091,23 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
2084
2091
Printf (stdout , "Swig_typemap_attach_parms: embedded\n" );
2085
2092
#endif
2086
2093
if (already_substituting < 10 ) {
2094
+ char * found_colon ;
2087
2095
already_substituting ++ ;
2088
2096
if ((in_typemap_search_multi == 0 ) && typemap_search_debug ) {
2089
2097
String * dtypemap = NewString (dollar_typemap );
2090
2098
Replaceall (dtypemap , "$TYPEMAP" , "$typemap" );
2091
2099
Printf (stdout , " Containing: %s\n" , dtypemap );
2092
2100
Delete (dtypemap );
2093
2101
}
2094
- Swig_typemap_attach_parms (tmap_method , to_match_parms , f );
2102
+ found_colon = Strchr (tmap_method , ':' );
2103
+ if (found_colon ) {
2104
+ /* Substitute from a keyword argument to a typemap. Avoid emitting local variables from the attached typemap by passing NULL for the file. */
2105
+ String * temp_tmap_method = NewStringWithSize (Char (tmap_method ), found_colon - Char (tmap_method ));
2106
+ Swig_typemap_attach_parms (temp_tmap_method , to_match_parms , NULL );
2107
+ Delete (temp_tmap_method );
2108
+ } else {
2109
+ Swig_typemap_attach_parms (tmap_method , to_match_parms , f );
2110
+ }
2095
2111
already_substituting -- ;
2096
2112
2097
2113
/* Look for the typemap code */
0 commit comments