Skip to content

Commit 1329670

Browse files
committed
Allow referencing of typemap keywords inside of "$typemap("
1 parent e36e898 commit 1329670

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

Doc/Manual/Typemaps.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,14 @@ <H4><a name="Typemaps_special_macro_typemap">14.4.4.2 $typemap(method, typepatte
24552455
</pre>
24562456
</div>
24572457

2458+
<p>
2459+
The first argument, the typemap method, can look up the keyword argument of a
2460+
typemap by appending a colon and the keyowrd. For example,
2461+
<tt>$typemap(directorin:descriptor, $type)</tt> would be replaced by <tt>"D"</tt> if <tt>type</tt> is a <tt>double</tt>.
2462+
</p>
2463+
<p>
2464+
<em>New in SWIG 4.1.</em>
2465+
</p>
24582466

24592467
<H3><a name="Typemaps_special_variable_attributes">14.4.5 Special variables and typemap attributes</a></H3>
24602468

Examples/test-suite/python/special_variable_macros_runme.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import special_variable_macros
22

3+
cvar = special_variable_macros.cvar
34
name = special_variable_macros.Name()
45
if special_variable_macros.testFred(name) != "none":
56
raise "test failed"
7+
if cvar.accessed_examplekw != 0:
8+
raise "Precondition failed"
69
if special_variable_macros.testJack(name) != "$specialname":
710
raise "test failed"
11+
if cvar.accessed_examplekw != 1:
12+
raise "Postcondition failed"
813
if special_variable_macros.testJill(name) != "jilly":
914
raise "test failed"
1015
if special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap":

Examples/test-suite/special_variable_macros.i

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@ struct NameWrap {
3939
private:
4040
Name name;
4141
};
42+
43+
// Global variable for testing whether examplekw was touched
44+
int accessed_examplekw = 0;
4245
%}
4346

4447
// check $1 and $input get expanded properly when used from $typemap()
45-
%typemap(in) Name *GENERIC ($*1_type temp)
48+
%typemap(in, examplekw="accessed_examplekw=1;") Name *GENERIC ($*1_type temp)
4649
%{
4750
/*%typemap(in) Name *GENERIC start */
4851
temp = Name("$specialname");
@@ -80,6 +83,7 @@ static const char *nameDescriptor = "$descriptor(Name)";
8083
%typemap(in) Name *jack {
8184
// %typemap(in) Name *jack start
8285
$typemap(in, Name *GENERIC)
86+
$typemap(in:examplekw, Name *GENERIC)
8387
// %typemap(in) Name *jack end
8488
}
8589

Source/Swig/typemap.c

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,12 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) {
511511
if (sm) {
512512
/* Got a typemap. Need to only merge attributes for methods that match our signature */
513513
Iterator ki;
514+
Hash *deferred_add;
514515
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();
515520
for (ki = First(sm); ki.key; ki = Next(ki)) {
516521
/* Check for a signature match with the source signature */
517522
if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) {
@@ -521,34 +526,36 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) {
521526
Replace(nkey, ssig, dsig, DOH_REPLACE_ANY);
522527

523528
/* Make sure the typemap doesn't already exist in the target map */
524-
525529
oldm = Getattr(tm, nkey);
526530
if (!oldm || (!Getattr(tm, "code"))) {
527531
String *code;
528-
ParmList *locals;
529-
ParmList *kwargs;
530532
Hash *sm1 = ki.item;
531533

532534
code = Getattr(sm1, "code");
533-
locals = Getattr(sm1, "locals");
534-
kwargs = Getattr(sm1, "kwargs");
535535
if (code) {
536+
Replace(nkey, dsig, "", DOH_REPLACE_ANY);
537+
Replace(nkey, "tmap:", "", DOH_REPLACE_ANY);
538+
Setattr(deferred_add, nkey, sm1);
539+
}
540+
Delete(nkey);
541+
}
542+
}
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;
536548
String *src_str = ParmList_str_multibrackets(src);
537549
String *dest_str = ParmList_str_multibrackets(dest);
538550
String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
539551

540-
Replace(nkey, dsig, "", DOH_REPLACE_ANY);
541-
Replace(nkey, "tmap:", "", DOH_REPLACE_ANY);
542-
typemap_register(nkey, dest, code, locals, kwargs, source_directive);
552+
typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive);
543553

544554
Delete(source_directive);
545555
Delete(dest_str);
546556
Delete(src_str);
547557
}
548-
}
549-
Delete(nkey);
550-
}
551-
}
558+
Delete(deferred_add);
552559
}
553560
Delete(ssig);
554561
Delete(dsig);
@@ -2090,14 +2097,22 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper
20902097
Printf(stdout, "Swig_typemap_attach_parms: embedded\n");
20912098
#endif
20922099
if (already_substituting < 10) {
2100+
char* found_colon;
20932101
already_substituting++;
20942102
if ((in_typemap_search_multi == 0) && typemap_search_debug) {
20952103
String *dtypemap = NewString(dollar_typemap);
20962104
Replaceall(dtypemap, "$TYPEMAP", "$typemap");
20972105
Printf(stdout, " Containing: %s\n", dtypemap);
20982106
Delete(dtypemap);
20992107
}
2100-
Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
2108+
found_colon = Strstr(tmap_method, ":");
2109+
if (found_colon) {
2110+
String *temp_tmap_method = NewStringWithSize(Char(tmap_method), found_colon - Char(tmap_method));
2111+
Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, f);
2112+
Delete(temp_tmap_method);
2113+
} else {
2114+
Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
2115+
}
21012116
already_substituting--;
21022117

21032118
/* Look for the typemap code */

0 commit comments

Comments
 (0)