Merge branch 'fragment-typemap' into upstream-master
* fragment-typemap: Add documentation Enable multiple 'fragment' keywords to be attached to typemaps
This commit is contained in:
commit
013be550ed
3 changed files with 151 additions and 3 deletions
|
|
@ -3983,9 +3983,19 @@ inclusion of the other fragments.
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<p>
|
<p>
|
||||||
A typemap can also use more than one fragment, but since the
|
A typemap can also use more than one fragment with the same syntax:
|
||||||
syntax is different, you need to specify the dependent fragments in a comma separated
|
</p>
|
||||||
list. Consider:
|
<div class="code">
|
||||||
|
<pre>
|
||||||
|
%typemap("in", "header", fragment="frag1", fragment="frag2", fragment="frag3") "";
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
<em>New in SWIG 4.1.</em>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>An older syntax allows multiple fragments to be specified in a comma
|
||||||
|
separated list inside a single keyword argument. Consider:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="code">
|
<div class="code">
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,86 @@ int foo(int hola)
|
||||||
}
|
}
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
/* Instantiate multiple fragments at once using multiple keywords */
|
||||||
|
typedef int int_infrag3;
|
||||||
|
typedef int explicit_frag3;
|
||||||
|
|
||||||
|
%fragment("explicit_frag1","header", noblock=1) {
|
||||||
|
typedef int explicit_frag1;
|
||||||
|
}
|
||||||
|
|
||||||
|
%fragment("explicit_frag2","header", noblock=1, noblock=1) {
|
||||||
|
typedef explicit_frag1 explicit_frag2;
|
||||||
|
}
|
||||||
|
|
||||||
|
%fragment("explicit_frag3","header",
|
||||||
|
fragment="explicit_frag1", fragment="explicit_frag2")
|
||||||
|
%{typedef explicit_frag2 explicit_frag3;%}
|
||||||
|
|
||||||
|
%fragment("explicit_frag3");
|
||||||
|
%inline %{
|
||||||
|
explicit_frag3 my_int = 0;
|
||||||
|
%}
|
||||||
|
|
||||||
|
/* Test typemap's ability to instantiate multiple fragments on demand */
|
||||||
|
typedef int int_infrag1;
|
||||||
|
typedef int int_infrag2;
|
||||||
|
typedef int int_outfrag1;
|
||||||
|
typedef int int_outfrag2;
|
||||||
|
typedef int int_outfrag3;
|
||||||
|
|
||||||
|
%fragment("infrag2","runtime") %{
|
||||||
|
typedef int_infrag1 int_infrag2;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%fragment("infrag1","runtime") %{
|
||||||
|
typedef int int_infrag1;
|
||||||
|
%}
|
||||||
|
%fragment("infrag2","runtime") %{
|
||||||
|
typedef int_infrag1 int_infrag2;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%fragment("outfrag1","runtime") %{
|
||||||
|
typedef int int_outfrag1;
|
||||||
|
%}
|
||||||
|
%fragment("outfrag2","runtime") %{
|
||||||
|
typedef int_outfrag1 int_outfrag2;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%fragment("tcfrag1","runtime") %{
|
||||||
|
typedef int int_tcfrag1;
|
||||||
|
%}
|
||||||
|
%fragment("tcfrag2","runtime") %{
|
||||||
|
typedef int_tcfrag1 int_tcfrag2;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%fragment("outspecial"{bool},"runtime") %{
|
||||||
|
typedef int int_outfrag3_temp;
|
||||||
|
%}
|
||||||
|
%fragment("outfrag3","runtime") %{
|
||||||
|
typedef int_outfrag3_temp int_outfrag3;
|
||||||
|
%}
|
||||||
|
|
||||||
|
%typemap(in, fragment="infrag1", fragment="infrag2") int_infrag2
|
||||||
|
%{$typemap(in,int)%}
|
||||||
|
|
||||||
|
%typemap(check, fragment="tcfrag1", noblock=1, fragment="tcfrag2") int_infrag2
|
||||||
|
{(void)sizeof(int_tcfrag2);}
|
||||||
|
|
||||||
|
%typemap(out, fragment="outfrag1", fragment="outfrag2", noblock=1) int_outfrag2
|
||||||
|
{$typemap(out,int)}
|
||||||
|
|
||||||
|
/* Test another permutation of keyword order */
|
||||||
|
%typemap(out, noblock=1, fragment="outfrag1", fragment="outfrag2") int_outfrag1
|
||||||
|
{$typemap(out,int)}
|
||||||
|
|
||||||
|
/* Test fragment specialization */
|
||||||
|
%typemap(out, noblock=1, fragment="outspecial"{bool}, fragment="outfrag3") int_outfrag3
|
||||||
|
{$typemap(out,int)}
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
int identity_in(int_infrag2 inp) { return inp; }
|
||||||
|
int_outfrag2 identity_out(int inp) { return inp; }
|
||||||
|
int_outfrag3 identity_out_2(int inp) { return inp; }
|
||||||
|
%}
|
||||||
|
|
|
||||||
|
|
@ -1256,6 +1256,59 @@ static String *typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) {
|
||||||
return w ? Copy(w) : 0;
|
return w ? Copy(w) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* typemap_merge_fragment_kwargs()
|
||||||
|
*
|
||||||
|
* If multiple 'fragment' attributes are provided to a typemap, combine them by
|
||||||
|
* concatenating with commas.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
static void typemap_merge_fragment_kwargs(Parm *kw) {
|
||||||
|
Parm *reattach_kw = NULL;
|
||||||
|
Parm *prev_kw = NULL;
|
||||||
|
Parm *next_kw = NULL;
|
||||||
|
String *fragment = NULL;
|
||||||
|
while (kw) {
|
||||||
|
next_kw = nextSibling(kw);
|
||||||
|
if (Strcmp(Getattr(kw, "name"), "fragment") == 0) {
|
||||||
|
String *thisfragment = Getattr(kw, "value");
|
||||||
|
String *kwtype = Getattr(kw, "type");
|
||||||
|
if (!fragment) {
|
||||||
|
/* First fragment found; it should remain in the list */
|
||||||
|
fragment = thisfragment;
|
||||||
|
prev_kw = kw;
|
||||||
|
} else {
|
||||||
|
/* Concatentate to previously found fragment */
|
||||||
|
Printv(fragment, ",", thisfragment, NULL);
|
||||||
|
reattach_kw = prev_kw;
|
||||||
|
}
|
||||||
|
if (kwtype) {
|
||||||
|
String *mangle = Swig_string_mangle(kwtype);
|
||||||
|
Append(fragment, mangle);
|
||||||
|
Delete(mangle);
|
||||||
|
/* Remove 'type' from kwargs so it's not duplicated later */
|
||||||
|
Setattr(kw, "type", NULL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Not a fragment */
|
||||||
|
if (reattach_kw) {
|
||||||
|
/* Update linked list to remove duplicate fragment */
|
||||||
|
DohIncref(kw);
|
||||||
|
set_nextSibling(reattach_kw, kw);
|
||||||
|
set_previousSibling(kw, reattach_kw);
|
||||||
|
Delete(reattach_kw);
|
||||||
|
reattach_kw = NULL;
|
||||||
|
}
|
||||||
|
prev_kw = kw;
|
||||||
|
}
|
||||||
|
kw = next_kw;
|
||||||
|
}
|
||||||
|
if (reattach_kw) {
|
||||||
|
/* Update linked list to remove duplicate fragment */
|
||||||
|
set_nextSibling(reattach_kw, kw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Swig_typemap_lookup()
|
* Swig_typemap_lookup()
|
||||||
*
|
*
|
||||||
|
|
@ -1463,6 +1516,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No
|
||||||
|
|
||||||
/* Attach kwargs - ie the typemap attributes */
|
/* Attach kwargs - ie the typemap attributes */
|
||||||
kw = Getattr(tm, "kwargs");
|
kw = Getattr(tm, "kwargs");
|
||||||
|
typemap_merge_fragment_kwargs(kw);
|
||||||
while (kw) {
|
while (kw) {
|
||||||
String *value = Copy(Getattr(kw, "value"));
|
String *value = Copy(Getattr(kw, "value"));
|
||||||
String *kwtype = Getattr(kw, "type");
|
String *kwtype = Getattr(kw, "type");
|
||||||
|
|
@ -1577,6 +1631,7 @@ String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, co
|
||||||
static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *firstp, int nmatch) {
|
static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *firstp, int nmatch) {
|
||||||
String *temp = NewStringEmpty();
|
String *temp = NewStringEmpty();
|
||||||
Parm *kw = Getattr(tm, "kwargs");
|
Parm *kw = Getattr(tm, "kwargs");
|
||||||
|
typemap_merge_fragment_kwargs(kw);
|
||||||
while (kw) {
|
while (kw) {
|
||||||
String *value = Copy(Getattr(kw, "value"));
|
String *value = Copy(Getattr(kw, "value"));
|
||||||
String *type = Getattr(kw, "type");
|
String *type = Getattr(kw, "type");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue