Merge branch 'typemap-colon'

* typemap-colon:
  Incoporate review suggestions
  Allow referencing of typemap keywords inside of "$typemap("
This commit is contained in:
William S Fulton 2022-06-01 07:57:01 +01:00
commit da40946aaa
4 changed files with 46 additions and 14 deletions

View file

@ -2457,6 +2457,14 @@ The result is the following expansion
</pre>
</div>
<p>
The first argument, the typemap method, can look up the attribute of a
typemap by appending a colon and the keyword. For example,
<tt>$typemap(directorin:descriptor, $type)</tt> would be replaced by <tt>"D"</tt> if <tt>type</tt> is a <tt>double</tt>.
</p>
<p>
<em>New in SWIG 4.1.</em>
</p>
<H3><a name="Typemaps_special_variable_attributes">14.4.5 Special variables and typemap attributes</a></H3>

View file

@ -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":

View file

@ -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
}

View file

@ -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);
@ -2084,6 +2091,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);
@ -2091,7 +2099,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 = 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);
Delete(temp_tmap_method);
} else {
Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
}
already_substituting--;
/* Look for the typemap code */