From 6dceec6fdb7f0164988c44c17eb065886c860148 Mon Sep 17 00:00:00 2001 From: Marcelo Matus Date: Tue, 27 Jan 2004 23:39:35 +0000 Subject: [PATCH] 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 --- Examples/test-suite/fragments.i | 36 +++++++++++++++++++++++++++++++++ Source/CParse/parser.y | 18 ++++++++++------- Source/Modules/lang.cxx | 5 +---- Source/Swig/fragment.c | 19 +++++++++++++---- Source/Swig/swig.h | 2 +- 5 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 Examples/test-suite/fragments.i diff --git a/Examples/test-suite/fragments.i b/Examples/test-suite/fragments.i new file mode 100644 index 000000000..4bf399a21 --- /dev/null +++ b/Examples/test-suite/fragments.i @@ -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); +} + +%} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 1ed950240..40123a757 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1266,17 +1266,21 @@ except_directive : EXCEPT LPAREN ID RPAREN LBRACE { %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"); - Setattr($$,"section", $5); - Setattr($$,"name",$3); - Setattr($$,"code",$7); + Setattr($$,"section", Getattr(p,"name")); + Setattr($$,"name",Getattr($3,"name")); + 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('{','}'); $$ = new_node("fragment"); - Setattr($$,"section",$5); - Setattr($$,"name",$3); + Setattr($$,"section", Getattr(p,"name")); + Setattr($$,"name",Getattr($3,"name")); + Setattr($$,"kwargs",nextSibling(p)); Delitem(scanner_ccode,0); Delitem(scanner_ccode,DOH_END); Setattr($$,"code",Copy(scanner_ccode)); diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 517d932ae..dfc7ceb58 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -461,10 +461,7 @@ int Language::constantDirective(Node *n) { * ---------------------------------------------------------------------- */ int Language::fragmentDirective(Node *n) { - String *name = Getattr(n,"name"); - String *code = Getattr(n,"code"); - String *section = Getattr(n,"section"); - Swig_fragment_register(name,section,code); + Swig_fragment_register(n); return SWIG_OK; } diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c index b039759a3..b83d43869 100644 --- a/Source/Swig/fragment.c +++ b/Source/Swig/fragment.c @@ -23,17 +23,21 @@ static Hash *fragments = 0; /* ----------------------------------------------------------------------------- * 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 -Swig_fragment_register(String *name, String *section, String *code) { - String *ccode; +Swig_fragment_register(Node* fragment) { + String *name = Getattr(fragment,"name"); + String *section = Getattr(fragment,"section"); + String *ccode = Copy(Getattr(fragment,"code")); + Hash *kwargs = Getattr(fragment,"kwargs"); if (!fragments) { fragments = NewHash(); } - ccode = Copy(code); Setmeta(ccode,"section",Copy(section)); + if (kwargs) Setmeta(ccode,"kwargs",Copy(kwargs)); Setattr(fragments,Copy(name),ccode); } @@ -51,6 +55,13 @@ Swig_fragment_emit(String *name) { code = Getattr(fragments,name); if (code) { 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) { File *f = Swig_filebyname(section); if (!f) { diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index c378026fd..2da19154c 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -499,7 +499,7 @@ extern void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parm /* --- 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); /* hacks defined in C++ ! */