Simple patch to allow fragments to include other fragments:

%fragment("Hello","header") "..."

%fragment("Hi","header",fragment="Hello") "..."

the latter fragment will include the first one if is invoked.

more than one fragment can be included at the time, just
keep adding fragment="f1",fragment="f2", etc.

this is used to emulate typemaps reuse, where all the
reusable typemap code is put in a fragment static method,
and then it can be included from another fragment typemap
as needed.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@5690 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Marcelo Matus 2004-01-27 23:39:35 +00:00
commit 6dceec6fdb
5 changed files with 64 additions and 16 deletions

View file

@ -0,0 +1,36 @@
%module fragments
%fragment("Hello","header") %{
/* hello!!! */
int foobar(int a)
{
return a;
}
%}
/*
this fragment include the previous fragment if needed.
*/
%fragment("Hi","header",fragment="Hello") %{
/* hi!!! */
int bar(int a)
{
return foobar(a);
}
%}
%typemap(in,fragment="Hi") int hola "$1 = 123;";
%inline %{
int bar(int a);
int foo(int hola)
{
return bar(hola);
}
%}

View file

@ -1266,17 +1266,21 @@ except_directive : EXCEPT LPAREN ID RPAREN LBRACE {
%fragment(name,location) { ... } %fragment(name,location) { ... }
------------------------------------------------------------ */ ------------------------------------------------------------ */
fragment_directive: FRAGMENT LPAREN idstring COMMA idstring RPAREN HBLOCK { fragment_directive: FRAGMENT LPAREN kwargs RPAREN HBLOCK {
Hash *p = nextSibling($3);
$$ = new_node("fragment"); $$ = new_node("fragment");
Setattr($$,"section", $5); Setattr($$,"section", Getattr(p,"name"));
Setattr($$,"name",$3); Setattr($$,"name",Getattr($3,"name"));
Setattr($$,"code",$7); Setattr($$,"kwargs",nextSibling(p));
Setattr($$,"code",$5);
} }
| FRAGMENT LPAREN idstring COMMA idstring RPAREN LBRACE { | FRAGMENT LPAREN kwargs RPAREN LBRACE {
Hash *p = nextSibling($3);
skip_balanced('{','}'); skip_balanced('{','}');
$$ = new_node("fragment"); $$ = new_node("fragment");
Setattr($$,"section",$5); Setattr($$,"section", Getattr(p,"name"));
Setattr($$,"name",$3); Setattr($$,"name",Getattr($3,"name"));
Setattr($$,"kwargs",nextSibling(p));
Delitem(scanner_ccode,0); Delitem(scanner_ccode,0);
Delitem(scanner_ccode,DOH_END); Delitem(scanner_ccode,DOH_END);
Setattr($$,"code",Copy(scanner_ccode)); Setattr($$,"code",Copy(scanner_ccode));

View file

@ -461,10 +461,7 @@ int Language::constantDirective(Node *n) {
* ---------------------------------------------------------------------- */ * ---------------------------------------------------------------------- */
int Language::fragmentDirective(Node *n) { int Language::fragmentDirective(Node *n) {
String *name = Getattr(n,"name"); Swig_fragment_register(n);
String *code = Getattr(n,"code");
String *section = Getattr(n,"section");
Swig_fragment_register(name,section,code);
return SWIG_OK; return SWIG_OK;
} }

View file

@ -23,17 +23,21 @@ static Hash *fragments = 0;
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Swig_fragment_register() * Swig_fragment_register()
* *
* Add a fragment. * Add a fragment. Use the original Node*, so, if something needs to be
* changed, lang.cxx doesn't nedd to be touched again.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
void void
Swig_fragment_register(String *name, String *section, String *code) { Swig_fragment_register(Node* fragment) {
String *ccode; String *name = Getattr(fragment,"name");
String *section = Getattr(fragment,"section");
String *ccode = Copy(Getattr(fragment,"code"));
Hash *kwargs = Getattr(fragment,"kwargs");
if (!fragments) { if (!fragments) {
fragments = NewHash(); fragments = NewHash();
} }
ccode = Copy(code);
Setmeta(ccode,"section",Copy(section)); Setmeta(ccode,"section",Copy(section));
if (kwargs) Setmeta(ccode,"kwargs",Copy(kwargs));
Setattr(fragments,Copy(name),ccode); Setattr(fragments,Copy(name),ccode);
} }
@ -51,6 +55,13 @@ Swig_fragment_emit(String *name) {
code = Getattr(fragments,name); code = Getattr(fragments,name);
if (code) { if (code) {
String *section = Getmeta(code,"section"); String *section = Getmeta(code,"section");
Hash *n = Getmeta(code,"kwargs");
while (n) {
if (Cmp(Getattr(n,"name"),"fragment") == 0) {
Swig_fragment_emit(Getattr(n,"value"));
}
n = nextSibling(n);
}
if (section) { if (section) {
File *f = Swig_filebyname(section); File *f = Swig_filebyname(section);
if (!f) { if (!f) {

View file

@ -499,7 +499,7 @@ extern void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parm
/* --- Code fragment support --- */ /* --- Code fragment support --- */
extern void Swig_fragment_register(String *name, String *section, String *code); extern void Swig_fragment_register(Node* fragment);
extern void Swig_fragment_emit(String *name); extern void Swig_fragment_emit(String *name);
/* hacks defined in C++ ! */ /* hacks defined in C++ ! */