From 13296706403f8d36fc95f95e1501ba1e626ae52c Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Thu, 20 Sep 2018 15:50:27 -0400 Subject: [PATCH 1/2] Allow referencing of typemap keywords inside of "$typemap(" --- Doc/Manual/Typemaps.html | 8 ++++ .../python/special_variable_macros_runme.py | 5 +++ Examples/test-suite/special_variable_macros.i | 6 ++- Source/Swig/typemap.c | 41 +++++++++++++------ 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 4842641dd..3990e43e2 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -2455,6 +2455,14 @@ The result is the following expansion +

+The first argument, the typemap method, can look up the keyword argument of a +typemap by appending a colon and the keyowrd. For example, +$typemap(directorin:descriptor, $type) would be replaced by "D" if type is a double. +

+

+New in SWIG 4.1. +

14.4.5 Special variables and typemap attributes

diff --git a/Examples/test-suite/python/special_variable_macros_runme.py b/Examples/test-suite/python/special_variable_macros_runme.py index e487f9a50..a67abcbc4 100644 --- a/Examples/test-suite/python/special_variable_macros_runme.py +++ b/Examples/test-suite/python/special_variable_macros_runme.py @@ -1,10 +1,15 @@ import special_variable_macros +cvar = special_variable_macros.cvar name = special_variable_macros.Name() if special_variable_macros.testFred(name) != "none": raise "test failed" +if cvar.accessed_examplekw != 0: + raise "Precondition failed" if special_variable_macros.testJack(name) != "$specialname": raise "test failed" +if cvar.accessed_examplekw != 1: + raise "Postcondition failed" if special_variable_macros.testJill(name) != "jilly": raise "test failed" if special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap": diff --git a/Examples/test-suite/special_variable_macros.i b/Examples/test-suite/special_variable_macros.i index 98d108b6b..d1878e71b 100644 --- a/Examples/test-suite/special_variable_macros.i +++ b/Examples/test-suite/special_variable_macros.i @@ -39,10 +39,13 @@ struct NameWrap { private: Name name; }; + +// Global variable for testing whether examplekw was touched +int accessed_examplekw = 0; %} // check $1 and $input get expanded properly when used from $typemap() -%typemap(in) Name *GENERIC ($*1_type temp) +%typemap(in, examplekw="accessed_examplekw=1;") Name *GENERIC ($*1_type temp) %{ /*%typemap(in) Name *GENERIC start */ temp = Name("$specialname"); @@ -80,6 +83,7 @@ static const char *nameDescriptor = "$descriptor(Name)"; %typemap(in) Name *jack { // %typemap(in) Name *jack start $typemap(in, Name *GENERIC) +$typemap(in:examplekw, Name *GENERIC) // %typemap(in) Name *jack end } diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 3273c19db..0ff109273 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -511,7 +511,12 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { if (sm) { /* Got a typemap. Need to only merge attributes for methods that match our signature */ Iterator ki; + Hash *deferred_add; match = 1; + + /* Since typemap_register can modify the `sm` hash, we *cannot* call typemap_register while iterating over sm. + * Create a temporary hash of typemaps to add immediately after. */ + deferred_add = NewHash(); for (ki = First(sm); ki.key; ki = Next(ki)) { /* Check for a signature match with the source signature */ if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) { @@ -521,34 +526,36 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { Replace(nkey, ssig, dsig, DOH_REPLACE_ANY); /* Make sure the typemap doesn't already exist in the target map */ - oldm = Getattr(tm, nkey); if (!oldm || (!Getattr(tm, "code"))) { String *code; - ParmList *locals; - ParmList *kwargs; Hash *sm1 = ki.item; code = Getattr(sm1, "code"); - locals = Getattr(sm1, "locals"); - kwargs = Getattr(sm1, "kwargs"); if (code) { + Replace(nkey, dsig, "", DOH_REPLACE_ANY); + Replace(nkey, "tmap:", "", DOH_REPLACE_ANY); + Setattr(deferred_add, nkey, sm1); + } + Delete(nkey); + } + } + } + + /* After assembling the key/item pairs, add the resulting typemaps */ + for (ki = First(deferred_add); ki.key; ki = Next(ki)) { + Hash *sm1 = ki.item; String *src_str = ParmList_str_multibrackets(src); String *dest_str = ParmList_str_multibrackets(dest); String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str); - Replace(nkey, dsig, "", DOH_REPLACE_ANY); - Replace(nkey, "tmap:", "", DOH_REPLACE_ANY); - typemap_register(nkey, dest, code, locals, kwargs, source_directive); + typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive); Delete(source_directive); Delete(dest_str); Delete(src_str); } - } - Delete(nkey); - } - } + Delete(deferred_add); } Delete(ssig); Delete(dsig); @@ -2090,6 +2097,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper Printf(stdout, "Swig_typemap_attach_parms: embedded\n"); #endif if (already_substituting < 10) { + char* found_colon; already_substituting++; if ((in_typemap_search_multi == 0) && typemap_search_debug) { String *dtypemap = NewString(dollar_typemap); @@ -2097,7 +2105,14 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper Printf(stdout, " Containing: %s\n", dtypemap); Delete(dtypemap); } - Swig_typemap_attach_parms(tmap_method, to_match_parms, f); + found_colon = Strstr(tmap_method, ":"); + if (found_colon) { + String *temp_tmap_method = NewStringWithSize(Char(tmap_method), found_colon - Char(tmap_method)); + Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, f); + Delete(temp_tmap_method); + } else { + Swig_typemap_attach_parms(tmap_method, to_match_parms, f); + } already_substituting--; /* Look for the typemap code */ From b38a6530e35928b20098d65d305790028c2c7a3e Mon Sep 17 00:00:00 2001 From: Seth R Johnson Date: Sat, 26 Feb 2022 06:40:37 -0500 Subject: [PATCH 2/2] Incoporate review suggestions --- Doc/Manual/Typemaps.html | 4 ++-- Source/Swig/typemap.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 3990e43e2..78844618c 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -2456,8 +2456,8 @@ The result is the following expansion

-The first argument, the typemap method, can look up the keyword argument of a -typemap by appending a colon and the keyowrd. For example, +The first argument, the typemap method, can look up the attribute of a +typemap by appending a colon and the keyword. For example, $typemap(directorin:descriptor, $type) would be replaced by "D" if type is a double.

diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 0ff109273..f19daf280 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -2105,7 +2105,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper Printf(stdout, " Containing: %s\n", dtypemap); Delete(dtypemap); } - found_colon = Strstr(tmap_method, ":"); + found_colon = Strchr(tmap_method, ':'); if (found_colon) { String *temp_tmap_method = NewStringWithSize(Char(tmap_method), found_colon - Char(tmap_method)); Swig_typemap_attach_parms(temp_tmap_method, to_match_parms, f);