A lot of work on the type system. Experimental language module.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@516 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
33c9ebbdc8
commit
765ad025b9
8 changed files with 609 additions and 96 deletions
|
|
@ -427,7 +427,8 @@ yylex1(void) {
|
||||||
if (strcmp(yytext,"%apply") == 0) return(APPLY);
|
if (strcmp(yytext,"%apply") == 0) return(APPLY);
|
||||||
if (strcmp(yytext,"%clear") == 0) return(CLEAR);
|
if (strcmp(yytext,"%clear") == 0) return(CLEAR);
|
||||||
if (strcmp(yytext,"%doconly") == 0) return(DOCONLY);
|
if (strcmp(yytext,"%doconly") == 0) return(DOCONLY);
|
||||||
|
if (strcmp(yytext,"%map") == 0) return(MAP);
|
||||||
|
|
||||||
/* Have an unknown identifier, as a last step, we'll */
|
/* Have an unknown identifier, as a last step, we'll */
|
||||||
/* do a typedef lookup on it. */
|
/* do a typedef lookup on it. */
|
||||||
yylval.tok.text = NewString(yytext);
|
yylval.tok.text = NewString(yytext);
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ static DOH *top = 0;
|
||||||
static DOH *ATTR_TAG = 0;
|
static DOH *ATTR_TAG = 0;
|
||||||
static DOH *ATTR_CHILD = 0;
|
static DOH *ATTR_CHILD = 0;
|
||||||
static DOH *ATTR_PARENT = 0;
|
static DOH *ATTR_PARENT = 0;
|
||||||
static DOH *ATTR_SIBLING = 0;
|
static DOH *ATTR_NEXT = 0;
|
||||||
|
static DOH *ATTR_PREV = 0;
|
||||||
static DOH *ATTR_NAME = 0;
|
static DOH *ATTR_NAME = 0;
|
||||||
static DOH *ATTR_VALUE = 0;
|
static DOH *ATTR_VALUE = 0;
|
||||||
static DOH *ATTR_TYPE = 0;
|
static DOH *ATTR_TYPE = 0;
|
||||||
|
|
@ -52,7 +53,24 @@ static DOH *TAG_VARIABLE = 0;
|
||||||
o = child;
|
o = child;
|
||||||
while (o) {
|
while (o) {
|
||||||
Setattr(o,ATTR_PARENT,parent);
|
Setattr(o,ATTR_PARENT,parent);
|
||||||
o = Getattr(o,ATTR_SIBLING);
|
o = Getattr(o,ATTR_NEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create all back links so we get a doubly-linked lists */
|
||||||
|
static void create_backlinks(DOH *top) {
|
||||||
|
DOH *prev = 0;
|
||||||
|
DOH *obj;
|
||||||
|
|
||||||
|
if (!top) return;
|
||||||
|
obj = top;
|
||||||
|
while (obj) {
|
||||||
|
if (prev) {
|
||||||
|
Setattr(obj,ATTR_PREV,prev);
|
||||||
|
}
|
||||||
|
create_backlinks(Getattr(obj,ATTR_CHILD));
|
||||||
|
prev = obj;
|
||||||
|
obj = Getattr(obj,ATTR_NEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,11 +79,13 @@ static DOH *TAG_VARIABLE = 0;
|
||||||
int yyparse();
|
int yyparse();
|
||||||
DOH *tp;
|
DOH *tp;
|
||||||
|
|
||||||
if (!ATTR_SIBLING) {
|
if (!ATTR_NEXT) {
|
||||||
ATTR_PARENT = NewString("parent");
|
ATTR_PARENT = NewString("parent");
|
||||||
DohIntern(ATTR_PARENT);
|
DohIntern(ATTR_PARENT);
|
||||||
ATTR_SIBLING = NewString("sibling");
|
ATTR_NEXT = NewString("next");
|
||||||
DohIntern(ATTR_SIBLING);
|
DohIntern(ATTR_NEXT);
|
||||||
|
ATTR_PREV = NewString("prev");
|
||||||
|
DohIntern(ATTR_PREV);
|
||||||
ATTR_CHILD = NewString("child");
|
ATTR_CHILD = NewString("child");
|
||||||
DohIntern(ATTR_CHILD);
|
DohIntern(ATTR_CHILD);
|
||||||
ATTR_TAG = NewString("tag");
|
ATTR_TAG = NewString("tag");
|
||||||
|
|
@ -76,7 +96,7 @@ static DOH *TAG_VARIABLE = 0;
|
||||||
DohIntern(ATTR_VALUE);
|
DohIntern(ATTR_VALUE);
|
||||||
ATTR_TYPE = NewString("type");
|
ATTR_TYPE = NewString("type");
|
||||||
DohIntern(ATTR_TYPE);
|
DohIntern(ATTR_TYPE);
|
||||||
ATTR_PARMS = NewString("parameters");
|
ATTR_PARMS = NewString("parms");
|
||||||
DohIntern(ATTR_PARMS);
|
DohIntern(ATTR_PARMS);
|
||||||
ATTR_PARM = NewString("parm");
|
ATTR_PARM = NewString("parm");
|
||||||
DohIntern(ATTR_PARM);
|
DohIntern(ATTR_PARM);
|
||||||
|
|
@ -98,6 +118,7 @@ static DOH *TAG_VARIABLE = 0;
|
||||||
yyparse();
|
yyparse();
|
||||||
Setattr(tp, ATTR_CHILD, top);
|
Setattr(tp, ATTR_CHILD, top);
|
||||||
setparent(tp,top);
|
setparent(tp,top);
|
||||||
|
create_backlinks(tp);
|
||||||
return tp;
|
return tp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,15 +135,17 @@ static DOH *TAG_VARIABLE = 0;
|
||||||
static DOH *parmstotype(DOH *parms) {
|
static DOH *parmstotype(DOH *parms) {
|
||||||
int i, l;
|
int i, l;
|
||||||
DOH *p, *r;
|
DOH *p, *r;
|
||||||
r = NewString("(");
|
DOHList *ty;
|
||||||
|
|
||||||
|
ty = NewList();
|
||||||
p = parms;
|
p = parms;
|
||||||
while (p) {
|
while (p) {
|
||||||
Append(r,Getattr(p,ATTR_TYPE));
|
Append(ty,Getattr(p,ATTR_TYPE));
|
||||||
p = Getattr(p,ATTR_SIBLING);
|
p = Getattr(p,ATTR_NEXT);
|
||||||
if (p)
|
|
||||||
Append(r,",");
|
|
||||||
}
|
}
|
||||||
Append(r,")");
|
r = NewString("");
|
||||||
|
SwigType_add_function(r,ty);
|
||||||
|
Delete(ty);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -212,7 +235,7 @@ static int promote(int t1, int t2) {
|
||||||
%token <tok> ADDMETHODS ALPHA_MODE APPLY CHECKOUT CLEAR CONSTANT DOCONLY DOC_DISABLE DOC_ENABLE ECHO EXCEPT
|
%token <tok> ADDMETHODS ALPHA_MODE APPLY CHECKOUT CLEAR CONSTANT DOCONLY DOC_DISABLE DOC_ENABLE ECHO EXCEPT
|
||||||
%token <tok> ILLEGAL IMPORT INCLUDE INIT INLINE LOCALSTYLE MACRO MODULE NAME NATIVE NEW PRAGMA
|
%token <tok> ILLEGAL IMPORT INCLUDE INIT INLINE LOCALSTYLE MACRO MODULE NAME NATIVE NEW PRAGMA
|
||||||
%token <tok> RAW_MODE READONLY READWRITE RENAME SECTION STYLE SUBSECTION SUBSUBSECTION TEXT TITLE
|
%token <tok> RAW_MODE READONLY READWRITE RENAME SECTION STYLE SUBSECTION SUBSUBSECTION TEXT TITLE
|
||||||
%token <tok> TYPE TYPEMAP USERDIRECTIVE WEXTERN WRAPPER
|
%token <tok> TYPE TYPEMAP USERDIRECTIVE WEXTERN WRAPPER MAP
|
||||||
|
|
||||||
/* Operators */
|
/* Operators */
|
||||||
%left <tok> LOR
|
%left <tok> LOR
|
||||||
|
|
@ -237,8 +260,8 @@ static int promote(int t1, int t2) {
|
||||||
%type <tmname> tm_name
|
%type <tmname> tm_name
|
||||||
%type <tok> tm_method
|
%type <tok> tm_method
|
||||||
%type <node> statement swig_directive c_declaration
|
%type <node> statement swig_directive c_declaration
|
||||||
%type <node> file_include code_block doc_directive except_directive pragma_directive modifier_directive native_directive typemap_directive
|
%type <node> file_include code_block doc_directive except_directive pragma_directive modifier_directive native_directive typemap_directive map_directive
|
||||||
%type <node> variable_decl function_decl enum_decl typedef_decl stail edecl typedeflist
|
%type <node> variable_decl function_decl enum_decl typedef_decl stail edecl typedeflist map_element
|
||||||
%type <nodelist> enumlist interface
|
%type <nodelist> enumlist interface
|
||||||
%type <node> inherit base_list
|
%type <node> inherit base_list
|
||||||
%type <tok> base_specifier access_specifier cpp_end ctor_end opt_id
|
%type <tok> base_specifier access_specifier cpp_end ctor_end opt_id
|
||||||
|
|
@ -261,21 +284,21 @@ interface : interface statement {
|
||||||
o = $2;
|
o = $2;
|
||||||
while (o) {
|
while (o) {
|
||||||
o2 = o;
|
o2 = o;
|
||||||
o = Getattr(o,ATTR_SIBLING);
|
o = Getattr(o,ATTR_NEXT);
|
||||||
}
|
}
|
||||||
$$.last = o2;
|
$$.last = o2;
|
||||||
} else {
|
} else {
|
||||||
if ($2) {
|
if ($2) {
|
||||||
o = $1.last;
|
o = $1.last;
|
||||||
if (o) {
|
if (o) {
|
||||||
Setattr(o,ATTR_SIBLING,$2);
|
Setattr(o,ATTR_NEXT,$2);
|
||||||
} else {
|
} else {
|
||||||
Setattr($1.node,ATTR_SIBLING,$2);
|
Setattr($1.node,ATTR_NEXT,$2);
|
||||||
}
|
}
|
||||||
o = $2;
|
o = $2;
|
||||||
while (o) {
|
while (o) {
|
||||||
o2 = o;
|
o2 = o;
|
||||||
o = Getattr(o,ATTR_SIBLING);
|
o = Getattr(o,ATTR_NEXT);
|
||||||
}
|
}
|
||||||
$1.last = o2;
|
$1.last = o2;
|
||||||
}
|
}
|
||||||
|
|
@ -369,6 +392,7 @@ swig_directive : MODULE idstring {
|
||||||
| modifier_directive { $$ = $1; }
|
| modifier_directive { $$ = $1; }
|
||||||
| native_directive { $$ = $1; }
|
| native_directive { $$ = $1; }
|
||||||
| typemap_directive { $$ = $1; }
|
| typemap_directive { $$ = $1; }
|
||||||
|
| map_directive { $$ = $1; }
|
||||||
| TYPE ID idlist SEMI { $$ = 0; }
|
| TYPE ID idlist SEMI { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -412,20 +436,20 @@ modifier_directive : READONLY { $$ = new_node("readonlydirective",$1.filename, $
|
||||||
|
|
||||||
code_block : HBLOCK {
|
code_block : HBLOCK {
|
||||||
$$ = new_node("headerblock",$1.filename,$1.line);
|
$$ = new_node("headerblock",$1.filename,$1.line);
|
||||||
Setattr($$,"text", $1.text);
|
Setattr($$,"code", $1.text);
|
||||||
}
|
}
|
||||||
| WRAPPER HBLOCK {
|
| WRAPPER HBLOCK {
|
||||||
$$ = new_node("wrapperblock",$2.filename,$2.line);
|
$$ = new_node("wrapperblock",$2.filename,$2.line);
|
||||||
Setattr($$,"text",$2.text);
|
Setattr($$,"code",$2.text);
|
||||||
}
|
}
|
||||||
| INIT HBLOCK {
|
| INIT HBLOCK {
|
||||||
$$ = new_node("initblock",$2.filename,$2.line);
|
$$ = new_node("initblock",$2.filename,$2.line);
|
||||||
Setattr($$,"text",$2.text);
|
Setattr($$,"code",$2.text);
|
||||||
}
|
}
|
||||||
| INLINE HBLOCK {
|
| INLINE HBLOCK {
|
||||||
DOH *pp;
|
DOH *pp;
|
||||||
$$ = new_node("headerblock",$2.filename,$2.line);
|
$$ = new_node("headerblock",$2.filename,$2.line);
|
||||||
Setattr($$,"text", $2.text);
|
Setattr($$,"code", $2.text);
|
||||||
Seek($2.text,0,SEEK_SET);
|
Seek($2.text,0,SEEK_SET);
|
||||||
pp = Preprocessor_parse($2.text);
|
pp = Preprocessor_parse($2.text);
|
||||||
Seek(pp,0,SEEK_SET);
|
Seek(pp,0,SEEK_SET);
|
||||||
|
|
@ -569,7 +593,7 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
|
||||||
Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
|
Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
|
||||||
if (!$$) $$ = o;
|
if (!$$) $$ = o;
|
||||||
if (prev) {
|
if (prev) {
|
||||||
Setattr(prev,ATTR_SIBLING,o);
|
Setattr(prev,ATTR_NEXT,o);
|
||||||
}
|
}
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
|
|
@ -590,7 +614,7 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
|
||||||
Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
|
Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
|
||||||
Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
|
Setattr(o,ATTR_PARMS,Getattr(l,ATTR_PARMS));
|
||||||
if (!$$) $$ = o;
|
if (!$$) $$ = o;
|
||||||
if (prev) Setattr(prev,ATTR_SIBLING,o);
|
if (prev) Setattr(prev,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -609,7 +633,7 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
|
||||||
Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
|
Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
|
||||||
Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
|
Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
|
||||||
if (!$$) $$ = o;
|
if (!$$) $$ = o;
|
||||||
if (prev) Setattr(prev,ATTR_SIBLING,o);
|
if (prev) Setattr(prev,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -627,7 +651,7 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
|
||||||
Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
|
Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
|
||||||
Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
|
Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
|
||||||
if (!$$) $$ = o;
|
if (!$$) $$ = o;
|
||||||
if (prev) Setattr(prev,ATTR_SIBLING,o);
|
if (prev) Setattr(prev,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -649,7 +673,7 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
|
||||||
Setattr(o,"srcname",Getattr($9,ATTR_NAME));
|
Setattr(o,"srcname",Getattr($9,ATTR_NAME));
|
||||||
Setattr(o,"srctype",Getattr($9,ATTR_TYPE));
|
Setattr(o,"srctype",Getattr($9,ATTR_TYPE));
|
||||||
if (!$$) $$ = o;
|
if (!$$) $$ = o;
|
||||||
if (prev) Setattr(prev,ATTR_SIBLING,o);
|
if (prev) Setattr(prev,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -670,7 +694,7 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
|
||||||
Setattr(o,"srcname",Getattr($7,ATTR_NAME));
|
Setattr(o,"srcname",Getattr($7,ATTR_NAME));
|
||||||
Setattr(o,"srctype",Getattr($7,ATTR_TYPE));
|
Setattr(o,"srctype",Getattr($7,ATTR_TYPE));
|
||||||
if (!$$) $$ = o;
|
if (!$$) $$ = o;
|
||||||
if (prev) Setattr(prev,ATTR_SIBLING,o);
|
if (prev) Setattr(prev,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -782,6 +806,52 @@ tm_args : LPAREN parms RPAREN {
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
map_directive : MAP ID LPAREN parms RPAREN LBRACE map_element RBRACE {
|
||||||
|
$$ = new_node("map", $1.filename, $1.line);
|
||||||
|
Setattr($$,ATTR_NAME,$2.text);
|
||||||
|
Setattr($$,ATTR_PARMS,$4);
|
||||||
|
if ($7) {
|
||||||
|
Setattr($$,ATTR_CHILD,$7);
|
||||||
|
setparent($$,$7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
map_element : variable_decl map_element {
|
||||||
|
DOH *o, *o2;
|
||||||
|
$$ = $1;
|
||||||
|
o = $1;
|
||||||
|
while (o) {
|
||||||
|
o2 = o;
|
||||||
|
o = Getattr(o,ATTR_NEXT);
|
||||||
|
}
|
||||||
|
Setattr(o2,ATTR_NEXT,$2);
|
||||||
|
}
|
||||||
|
| function_decl map_element {
|
||||||
|
DOH *o, *o2;
|
||||||
|
$$ = $1;
|
||||||
|
o = $1;
|
||||||
|
while (o) {
|
||||||
|
o2 = o;
|
||||||
|
o = Getattr(o,ATTR_NEXT);
|
||||||
|
}
|
||||||
|
Setattr(o2,ATTR_NEXT,$2);
|
||||||
|
}
|
||||||
|
| STRING COLON LBRACE {
|
||||||
|
DOH *text = LParse_skip_balanced('{','}');
|
||||||
|
$$ = new_node("mapelement",$1.filename, $1.line);
|
||||||
|
Setattr($$,ATTR_NAME,$1.text);
|
||||||
|
Setattr($$,"code",text);
|
||||||
|
$1.text = $$;
|
||||||
|
} map_element {
|
||||||
|
$$ = $1.text;
|
||||||
|
if ($5)
|
||||||
|
Setattr($$,ATTR_NEXT,$5);
|
||||||
|
}
|
||||||
|
| empty {
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/* =============================================================================
|
/* =============================================================================
|
||||||
|
|
@ -812,7 +882,7 @@ variable_decl : storage_spec type declaration array2 def_args stail {
|
||||||
Setattr($$,ATTR_VALUE,$5.text);
|
Setattr($$,ATTR_VALUE,$5.text);
|
||||||
}
|
}
|
||||||
if ($6) {
|
if ($6) {
|
||||||
Setattr($$,ATTR_SIBLING,$6);
|
Setattr($$,ATTR_NEXT,$6);
|
||||||
o = $6;
|
o = $6;
|
||||||
while (o) {
|
while (o) {
|
||||||
t = Copy($2);
|
t = Copy($2);
|
||||||
|
|
@ -821,7 +891,7 @@ variable_decl : storage_spec type declaration array2 def_args stail {
|
||||||
if ($1.ivalue) {
|
if ($1.ivalue) {
|
||||||
Setattr(o,ATTR_STORAGE,$1.text);
|
Setattr(o,ATTR_STORAGE,$1.text);
|
||||||
}
|
}
|
||||||
o = Getattr(o,ATTR_SIBLING);
|
o = Getattr(o,ATTR_NEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -850,7 +920,7 @@ function_decl : storage_spec type declaration LPAREN parms RPAREN cpp_const sta
|
||||||
Setattr($$,ATTR_STORAGE, $1.text);
|
Setattr($$,ATTR_STORAGE, $1.text);
|
||||||
}
|
}
|
||||||
if ($8) {
|
if ($8) {
|
||||||
Setattr($$,ATTR_SIBLING,$8);
|
Setattr($$,ATTR_NEXT,$8);
|
||||||
o = $8;
|
o = $8;
|
||||||
while (o) {
|
while (o) {
|
||||||
t = Copy($2);
|
t = Copy($2);
|
||||||
|
|
@ -859,7 +929,7 @@ function_decl : storage_spec type declaration LPAREN parms RPAREN cpp_const sta
|
||||||
if ($1.ivalue) {
|
if ($1.ivalue) {
|
||||||
Setattr(o,ATTR_STORAGE,$1.text);
|
Setattr(o,ATTR_STORAGE,$1.text);
|
||||||
}
|
}
|
||||||
o = Getattr(o,ATTR_SIBLING);
|
o = Getattr(o,ATTR_NEXT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -922,7 +992,7 @@ stail : SEMI { $$ = 0; }
|
||||||
if ($4.text)
|
if ($4.text)
|
||||||
Setattr($$,ATTR_VALUE,$4.text);
|
Setattr($$,ATTR_VALUE,$4.text);
|
||||||
if ($5)
|
if ($5)
|
||||||
Setattr($$,ATTR_SIBLING, $5);
|
Setattr($$,ATTR_NEXT, $5);
|
||||||
}
|
}
|
||||||
| COMMA declaration LPAREN parms RPAREN stail {
|
| COMMA declaration LPAREN parms RPAREN stail {
|
||||||
DOH *t = NewString("");
|
DOH *t = NewString("");
|
||||||
|
|
@ -932,7 +1002,7 @@ stail : SEMI { $$ = 0; }
|
||||||
Setattr($$,ATTR_PARMS,$4);
|
Setattr($$,ATTR_PARMS,$4);
|
||||||
Setattr($$,ATTR_TYPE, t);
|
Setattr($$,ATTR_TYPE, t);
|
||||||
if ($6)
|
if ($6)
|
||||||
Setattr($$,ATTR_SIBLING,$6);
|
Setattr($$,ATTR_NEXT,$6);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
@ -983,7 +1053,7 @@ enum_decl : storage_spec ENUM ename LBRACE enumlist RBRACE SEMI {
|
||||||
o = new_node("typedef",$7.filename,$7.line);
|
o = new_node("typedef",$7.filename,$7.line);
|
||||||
Setattr(o,ATTR_NAME,$7.text);
|
Setattr(o,ATTR_NAME,$7.text);
|
||||||
Setattr(o,ATTR_TYPE,$3.text);
|
Setattr(o,ATTR_TYPE,$3.text);
|
||||||
Setattr($$,ATTR_SIBLING,o);
|
Setattr($$,ATTR_NEXT,o);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
@ -995,22 +1065,9 @@ ename : ID { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
enumlist : enumlist COMMA edecl {
|
enumlist : enumlist COMMA edecl {
|
||||||
Setattr($1.last,ATTR_SIBLING,$3);
|
Setattr($1.last,ATTR_NEXT,$3);
|
||||||
$1.last = $3;
|
$1.last = $3;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
/*
|
|
||||||
DOH *o;
|
|
||||||
if ($3) {
|
|
||||||
o = Getattr($1,LASTATTR_SIBLING);
|
|
||||||
if (o) {
|
|
||||||
Setattr(o,ATTR_SIBLING,$3);
|
|
||||||
} else {
|
|
||||||
Setattr($1,ATTR_SIBLING,$3);
|
|
||||||
}
|
|
||||||
Setattr($1,LASTSIBLING,$3);;
|
|
||||||
}
|
|
||||||
$$ = $1;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
| edecl {
|
| edecl {
|
||||||
$$.node = $1;
|
$$.node = $1;
|
||||||
|
|
@ -1050,7 +1107,7 @@ typedef_decl : TYPEDEF type declaration array2 typedeflist SEMI {
|
||||||
SwigType_push(ty,Getattr(d,"array"));
|
SwigType_push(ty,Getattr(d,"array"));
|
||||||
Setattr(o,ATTR_TYPE,ty);
|
Setattr(o,ATTR_TYPE,ty);
|
||||||
Setattr(o,ATTR_NAME,Getattr(d,ATTR_NAME));
|
Setattr(o,ATTR_NAME,Getattr(d,ATTR_NAME));
|
||||||
Setattr(prev,ATTR_SIBLING,o);
|
Setattr(prev,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
Delete($5);
|
Delete($5);
|
||||||
|
|
@ -1162,7 +1219,7 @@ cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id S
|
||||||
t = Copy($3.text);
|
t = Copy($3.text);
|
||||||
SwigType_push(t,$8.decl);
|
SwigType_push(t,$8.decl);
|
||||||
Setattr(o,ATTR_TYPE,t);
|
Setattr(o,ATTR_TYPE,t);
|
||||||
Setattr($$,ATTR_SIBLING,o);
|
Setattr($$,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
for (i = 0; i < Len($9); i++) {
|
for (i = 0; i < Len($9); i++) {
|
||||||
d = Getitem($9,i);
|
d = Getitem($9,i);
|
||||||
|
|
@ -1172,7 +1229,7 @@ cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id S
|
||||||
SwigType_push(t,Getattr(d,"array"));
|
SwigType_push(t,Getattr(d,"array"));
|
||||||
Setattr(o,ATTR_TYPE,t);
|
Setattr(o,ATTR_TYPE,t);
|
||||||
Setattr(o,ATTR_NAME,Getattr(d,ATTR_NAME));
|
Setattr(o,ATTR_NAME,Getattr(d,ATTR_NAME));
|
||||||
Setattr(prev,ATTR_SIBLING,o);
|
Setattr(prev,ATTR_NEXT,o);
|
||||||
prev = o;
|
prev = o;
|
||||||
}
|
}
|
||||||
Delete($9);
|
Delete($9);
|
||||||
|
|
@ -1301,7 +1358,7 @@ cpp_other :/* A dummy class name */
|
||||||
$$ = new_node("addmethods",$1.filename,$1.line);
|
$$ = new_node("addmethods",$1.filename,$1.line);
|
||||||
if ($1.text)
|
if ($1.text)
|
||||||
Setattr($$,ATTR_NAME,$1.text);
|
Setattr($$,ATTR_NAME,$1.text);
|
||||||
if ($4.node) {
|
if ($4.node) {
|
||||||
Setattr($$,ATTR_CHILD,$4.node);
|
Setattr($$,ATTR_CHILD,$4.node);
|
||||||
setparent($$,$4.node);
|
setparent($$,$4.node);
|
||||||
}
|
}
|
||||||
|
|
@ -1318,17 +1375,21 @@ opt_id : ID { $$ = $1; }
|
||||||
/* -- Function parameter lists -- */
|
/* -- Function parameter lists -- */
|
||||||
|
|
||||||
parms : parm ptail {
|
parms : parm ptail {
|
||||||
if ($2)
|
if ($2) {
|
||||||
Setattr($1,ATTR_SIBLING,$2);
|
Setattr($1,ATTR_NEXT,$2);
|
||||||
$$ = $1;
|
Setattr($2,ATTR_PREV,$1);
|
||||||
}
|
}
|
||||||
|
$$ = $1;
|
||||||
|
}
|
||||||
| empty { $$ = 0; }
|
| empty { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
ptail : COMMA parm ptail {
|
ptail : COMMA parm ptail {
|
||||||
if ($3)
|
if ($3) {
|
||||||
Setattr($2,ATTR_SIBLING,$3);
|
Setattr($2,ATTR_NEXT,$3);
|
||||||
$$ = $2;
|
Setattr($3,ATTR_PREV,$2);
|
||||||
|
}
|
||||||
|
$$ = $2;
|
||||||
}
|
}
|
||||||
| empty { $$ = 0; }
|
| empty { $$ = 0; }
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#define CPLUS_PRIVATE 2
|
#define CPLUS_PRIVATE 2
|
||||||
#define CPLUS_PROTECTED 3
|
#define CPLUS_PROTECTED 3
|
||||||
|
|
||||||
|
static DOHFile *runtime = 0;
|
||||||
static DOHFile *headers = 0;
|
static DOHFile *headers = 0;
|
||||||
static DOHFile *wrappers = 0;
|
static DOHFile *wrappers = 0;
|
||||||
static DOHFile *init = 0;
|
static DOHFile *init = 0;
|
||||||
|
|
@ -26,6 +27,15 @@ static DOHString *ModuleName = 0;
|
||||||
static int NativeMode = 0;
|
static int NativeMode = 0;
|
||||||
static DOHString *NewName = 0;
|
static DOHString *NewName = 0;
|
||||||
static DOHHash *RenameHash = 0;
|
static DOHHash *RenameHash = 0;
|
||||||
|
static DOHHash *Rules = 0;
|
||||||
|
|
||||||
|
/* Object oriented flags */
|
||||||
|
|
||||||
|
static int InClass = 0;
|
||||||
|
static DOHString *ClassType = 0;
|
||||||
|
static DOHString *ClassName = 0;
|
||||||
|
static DOHString *ClassRename = 0;
|
||||||
|
static int AddMethods = 0;
|
||||||
|
|
||||||
/* -------- File inclusion directions -------- */
|
/* -------- File inclusion directions -------- */
|
||||||
|
|
||||||
|
|
@ -76,18 +86,22 @@ emit_scope(DOH *obj, void *clientdata) {
|
||||||
|
|
||||||
|
|
||||||
/* -------- Code blocks -------- */
|
/* -------- Code blocks -------- */
|
||||||
|
|
||||||
|
/* %{ ... %} directive */
|
||||||
static int
|
static int
|
||||||
emit_headerblock(DOH *obj, void *clientdata) {
|
emit_headerblock(DOH *obj, void *clientdata) {
|
||||||
Dump(Getattr(obj,"code"),headers);
|
Dump(Getattr(obj,"code"),headers);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* %wrapper %{ ... %} directive */
|
||||||
static int
|
static int
|
||||||
emit_wrapperblock(DOH *obj, void *clientdata) {
|
emit_wrapperblock(DOH *obj, void *clientdata) {
|
||||||
Dump(Getattr(obj,"code"),wrappers);
|
Dump(Getattr(obj,"code"),wrappers);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* %init %{ ... %} directive */
|
||||||
static int
|
static int
|
||||||
emit_initblock(DOH *obj, void *clientdata) {
|
emit_initblock(DOH *obj, void *clientdata) {
|
||||||
Dump(Getattr(obj,"code"),init);
|
Dump(Getattr(obj,"code"),init);
|
||||||
|
|
@ -96,18 +110,121 @@ emit_initblock(DOH *obj, void *clientdata) {
|
||||||
|
|
||||||
/* ------ Basic C declarations ----- */
|
/* ------ Basic C declarations ----- */
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* function
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
emit_function(DOH *obj, void *clientdata) {
|
emit_function(DOH *obj, void *clientdata) {
|
||||||
Printf(stdout,"function\n");
|
DOHString *name, *scriptname, *type, *storage;
|
||||||
|
DOHList *parms;
|
||||||
|
DOHHash *p;
|
||||||
|
SwigWrapper *wf;
|
||||||
|
int numarg = 0, numopt = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ExternMode) return 0;
|
||||||
|
|
||||||
|
name = Getattr(obj,"name"); /* Name of the function */
|
||||||
|
type = Getattr(obj,"type"); /* Return type */
|
||||||
|
parms = Getattr(obj,"parms"); /* Parameters */
|
||||||
|
storage = Getattr(obj,"storage"); /* Storage class */
|
||||||
|
|
||||||
|
/* See if the function is being renamed */
|
||||||
|
if (NewName) scriptname = NewName;
|
||||||
|
else scriptname = name;
|
||||||
|
|
||||||
|
/* Is this a member function? */
|
||||||
|
if (InClass) {
|
||||||
|
/* Handle member functions */
|
||||||
|
/* goto function_exit; */
|
||||||
|
}
|
||||||
|
|
||||||
|
wf = NewSwigWrapper();
|
||||||
|
/* Printf(wf->def,"void %s(args) {\n", Swig_name_wrapper(scriptname));*/
|
||||||
|
|
||||||
|
Printv(wf->def,
|
||||||
|
"static PyObject *", Swig_name_wrapper(scriptname), "(PyObject *self, PyObject *args) {\n",
|
||||||
|
0);
|
||||||
|
|
||||||
|
/* Mapping test */
|
||||||
|
|
||||||
|
{
|
||||||
|
DOH *rules;
|
||||||
|
int mlen = 0;
|
||||||
|
rules = Swig_map_match(Rules,"input",parms, &mlen);
|
||||||
|
Printf(stdout,"match(%d)\n", mlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop over all of the function arguments and build pieces of the wrapper function */
|
||||||
|
{
|
||||||
|
DOHString *formatstr; /* Format string for parsing arguments */
|
||||||
|
DOHString *argstr; /* List of arguments */
|
||||||
|
formatstr = NewString("");
|
||||||
|
argstr = NewString("");
|
||||||
|
|
||||||
|
for (p = parms, i=0; p; p = Swig_next(p), i++) {
|
||||||
|
DOHString *pdecl, *pname, *ptype, *value;
|
||||||
|
pname = NewStringf("_arg%d",i);
|
||||||
|
|
||||||
|
ptype = Getattr(p,"type");
|
||||||
|
|
||||||
|
if (SwigType_isarray(ptype)) {
|
||||||
|
int i;
|
||||||
|
int nd;
|
||||||
|
nd = SwigType_array_ndim(ptype);
|
||||||
|
for (i = 0; i < nd; i++) {
|
||||||
|
Printf(stdout,"array[%d] = %s\n", i, SwigType_array_getdim(ptype,i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pdecl = SwigType_cstr(ptype,pname);
|
||||||
|
|
||||||
|
if ((value = Getattr(p,"value"))) {
|
||||||
|
Printf(pdecl," = %s", value);
|
||||||
|
numopt++;
|
||||||
|
} else {
|
||||||
|
if (numopt > 0) {
|
||||||
|
printf("*** Error: Non-optional argument follows optional argument!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SwigWrapper_add_local(wf,pdecl,pname);
|
||||||
|
Printf(argstr,",&%s",pname);
|
||||||
|
|
||||||
|
Delete(pname);
|
||||||
|
Delete(pdecl);
|
||||||
|
}
|
||||||
|
|
||||||
|
Printv(wf->code,
|
||||||
|
"if (!PyParseArgs(\"", formatstr, "\"", argstr, ")) {\n",
|
||||||
|
"return NULL;\n",
|
||||||
|
"}\n",
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Printf(wf->code,"}\n");
|
||||||
|
SwigWrapper_print(wf,wrappers);
|
||||||
|
|
||||||
|
function_exit:
|
||||||
|
Delete(NewName);
|
||||||
|
NewName = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* variable
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
emit_variable(DOH *obj, void *clientdata) {
|
emit_variable(DOH *obj, void *clientdata) {
|
||||||
Printf(stdout,"variable\n");
|
Printf(stdout,"variable\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* constant
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
emit_constant(DOH *obj, void *clientdata) {
|
emit_constant(DOH *obj, void *clientdata) {
|
||||||
Printf(stdout,"constant\n");
|
Printf(stdout,"constant\n");
|
||||||
|
|
@ -145,7 +262,10 @@ emit_class(DOH *obj, void *clientdata) {
|
||||||
Printf(stdout,"class\n");
|
Printf(stdout,"class\n");
|
||||||
c = Getattr(obj, "child");
|
c = Getattr(obj, "child");
|
||||||
if (c) {
|
if (c) {
|
||||||
|
int ic = InClass;
|
||||||
|
InClass = 1;
|
||||||
Swig_emit(c,clientdata);
|
Swig_emit(c,clientdata);
|
||||||
|
InClass = ic;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +317,7 @@ static int
|
||||||
emit_moduledirective(DOH *obj, void *clientdata) {
|
emit_moduledirective(DOH *obj, void *clientdata) {
|
||||||
if (!ModuleName) {
|
if (!ModuleName) {
|
||||||
ModuleName = Getattr(obj,"name");
|
ModuleName = Getattr(obj,"name");
|
||||||
Incref(ModuleName);
|
DohIncref(ModuleName);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +348,7 @@ static int
|
||||||
emit_namedirective(DOH *obj, void *clientdata) {
|
emit_namedirective(DOH *obj, void *clientdata) {
|
||||||
if (NewName) Delete(NewName);
|
if (NewName) Delete(NewName);
|
||||||
NewName = Getattr(obj,"name");
|
NewName = Getattr(obj,"name");
|
||||||
if (NewName) Incref(NewName);
|
if (NewName) DohIncref(NewName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,24 +407,65 @@ emit_cleardirective(DOH *obj, void *clientdata) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
emit_map(DOH *obj, void *clientdata) {
|
||||||
|
DOH *parms;
|
||||||
|
DOH *rulename;
|
||||||
|
DOH *rules;
|
||||||
|
|
||||||
|
rulename = Getattr(obj,"name");
|
||||||
|
parms = Getattr(obj,"parms");
|
||||||
|
rules = Getattr(obj,"child");
|
||||||
|
|
||||||
|
Swig_map_add(Rules,rulename,parms,rules);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------- Entry point -------- */
|
/* -------- Entry point -------- */
|
||||||
|
|
||||||
|
static char *runtime_banner = "\n\
|
||||||
|
/* ----------------------------------------------------------------------------- \n\
|
||||||
|
Runtime\n\
|
||||||
|
----------------------------------------------------------------------------- */\n";
|
||||||
|
|
||||||
|
static char *header_banner = "\n\
|
||||||
|
/* ----------------------------------------------------------------------------- \n\
|
||||||
|
Headers\n\
|
||||||
|
----------------------------------------------------------------------------- */\n";
|
||||||
|
|
||||||
|
static char *wrapper_banner = "\n\
|
||||||
|
/* ----------------------------------------------------------------------------- \n\
|
||||||
|
Wrappers\n\
|
||||||
|
----------------------------------------------------------------------------- */\n";
|
||||||
|
|
||||||
|
static char *init_banner = "\n\
|
||||||
|
/* ----------------------------------------------------------------------------- \n\
|
||||||
|
Initialization\n\
|
||||||
|
----------------------------------------------------------------------------- */\n";
|
||||||
|
|
||||||
void test_emit(DOH *top, void *clientdata) {
|
void test_emit(DOH *top, void *clientdata) {
|
||||||
|
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
|
|
||||||
headers = NewString("\n/* --- Headers --- */\n");
|
runtime = NewString(runtime_banner);
|
||||||
wrappers = NewString("\n/* --- Wrappers --- */\n");
|
headers = NewString(header_banner);
|
||||||
init = NewString("\n/* --- Initialization --- */\n");
|
wrappers = NewString(wrapper_banner);
|
||||||
|
init = NewString(init_banner);
|
||||||
|
|
||||||
|
Rules = NewHash();
|
||||||
RenameHash = NewHash();
|
RenameHash = NewHash();
|
||||||
|
|
||||||
Swig_emit(top, clientdata);
|
Swig_emit(top, clientdata);
|
||||||
|
|
||||||
Swig_banner(stdout);
|
Swig_banner(stdout);
|
||||||
|
|
||||||
|
/* Get the runtime library */
|
||||||
|
Swig_insert_file("python.swg",runtime);
|
||||||
|
|
||||||
|
Dump(runtime,stdout);
|
||||||
Dump(headers,stdout);
|
Dump(headers,stdout);
|
||||||
Dump(wrappers,stdout);
|
Dump(wrappers,stdout);
|
||||||
Dump(init, stdout);
|
Dump(init, stdout);
|
||||||
|
Delete(runtime);
|
||||||
Delete(headers);
|
Delete(headers);
|
||||||
Delete(wrappers);
|
Delete(wrappers);
|
||||||
Delete(init);
|
Delete(init);
|
||||||
|
|
@ -345,6 +506,7 @@ static SwigRule rules[] = {
|
||||||
"typemapcopy", emit_typemapcopy,
|
"typemapcopy", emit_typemapcopy,
|
||||||
"applydirective", emit_applydirective,
|
"applydirective", emit_applydirective,
|
||||||
"cleardirective", emit_cleardirective,
|
"cleardirective", emit_cleardirective,
|
||||||
|
"map", emit_map,
|
||||||
NULL, NULL
|
NULL, NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
SRCS = naming.c tree.c stype.c scanner.c include.c getopt.c misc.c
|
SRCS = map.c wrapfunc.c naming.c tree.c stype.c scanner.c include.c getopt.c misc.c
|
||||||
OBJS = naming.o tree.o stype.o scanner.o include.o getopt.o misc.o
|
OBJS = map.o wrapfunc.o naming.o tree.o stype.o scanner.o include.o getopt.o misc.o
|
||||||
|
|
||||||
prefix = @prefix@
|
prefix = @prefix@
|
||||||
exec_prefix = @exec_prefix@
|
exec_prefix = @exec_prefix@
|
||||||
|
|
|
||||||
200
Source/Swig/map.c
Normal file
200
Source/Swig/map.c
Normal file
|
|
@ -0,0 +1,200 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* map.c
|
||||||
|
*
|
||||||
|
* This file provides support for defining %map rules that match lists of
|
||||||
|
* parameters to objects defining code generation rules.
|
||||||
|
*
|
||||||
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||||
|
*
|
||||||
|
* Copyright (C) 1999-2000. The University of Chicago
|
||||||
|
* See the file LICENSE for information on usage and redistribution.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "swig.h"
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Synopsis
|
||||||
|
*
|
||||||
|
* One of the biggest problems in wrapper generation is that of defining
|
||||||
|
* the handling of various datatypes and function parameters. This module
|
||||||
|
* provides support for a generic object known as a 'mapping rule' that is
|
||||||
|
* defined using the %map directive like this:
|
||||||
|
*
|
||||||
|
* %map rulename(typelist) {
|
||||||
|
* vars;
|
||||||
|
* rule1 { ... }
|
||||||
|
* rule2 { ... }
|
||||||
|
* rule3 { ... }
|
||||||
|
* rule4 { ... }
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* A mapping rule is somewhat similar to a class or structure definition. The
|
||||||
|
* "vars" field is a list of variable declarations that will be local to the
|
||||||
|
* mapping rule when it is used. The "rulen" fields simply define code
|
||||||
|
* fragments and other information that language specific modules can examine
|
||||||
|
* for their own nefarious purposes.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_map_add()
|
||||||
|
*
|
||||||
|
* Adds a new mapping rule. The parms input to this function should be a
|
||||||
|
* properly constructed parameter list with associated attributes. The rules
|
||||||
|
* field can technically be any valid object.
|
||||||
|
*
|
||||||
|
* The structure of how data is stored is as follows:
|
||||||
|
*
|
||||||
|
* ruleset (hash)
|
||||||
|
* --------------
|
||||||
|
* rulename ------> nameset (hash)
|
||||||
|
* --------------
|
||||||
|
* parm1 ---------> rule (hash)
|
||||||
|
* -------------
|
||||||
|
* parm2 -----------> rule (hash)
|
||||||
|
* *obj* --> obj
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* For multiple arguments, we end up building a large tree of hash tables.
|
||||||
|
* The object will be stored in the *obj* attribute of the last hash table.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void
|
||||||
|
Swig_map_add(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, DOH *obj)
|
||||||
|
{
|
||||||
|
|
||||||
|
DOHHash *nameset;
|
||||||
|
DOHHash *p, *n;
|
||||||
|
/* Locate the appropriate nameset */
|
||||||
|
|
||||||
|
nameset = Getattr(ruleset,rulename);
|
||||||
|
if (!nameset) {
|
||||||
|
/* Hmmm. First time we've seen this. Let's add it to our mapping table */
|
||||||
|
nameset = NewHash();
|
||||||
|
Setattr(ruleset,rulename,nameset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now, we walk down the parms list and create a series of hash tables */
|
||||||
|
|
||||||
|
p = parms;
|
||||||
|
n = nameset;
|
||||||
|
while (p) {
|
||||||
|
DOHString *ty, *name, *key;
|
||||||
|
DOHHash *nn;
|
||||||
|
ty = Getattr(p,"type");
|
||||||
|
name = Getattr(p,"name");
|
||||||
|
|
||||||
|
/* Create a hash table key */
|
||||||
|
|
||||||
|
key = NewStringf("%s-%s",name,ty);
|
||||||
|
|
||||||
|
/* See if there is already a entry with this type in the table */
|
||||||
|
nn = Getattr(n,key);
|
||||||
|
if (!nn) {
|
||||||
|
/* No. Go ahead and create it */
|
||||||
|
nn = NewHash();
|
||||||
|
Setattr(n,key,nn);
|
||||||
|
}
|
||||||
|
Delete(key);
|
||||||
|
n = nn;
|
||||||
|
p = Swig_next(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No more parameters. At this point, n points to the very last hash table in our search.
|
||||||
|
We'll stick our object there */
|
||||||
|
|
||||||
|
Setattr(n,"*obj*",obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_map_match()
|
||||||
|
*
|
||||||
|
* Perform a longest map for a list of parameters and a set of mapping rules.
|
||||||
|
* Returns the corresponding rule object and the number of parameters that
|
||||||
|
* were matched.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Internal function used for recursively searching rulesets */
|
||||||
|
static DOH *
|
||||||
|
Swig_map_match_internal(DOHHash *nameset, DOHHash *parms, int *nmatch) {
|
||||||
|
DOHHash *nn1, *nn2;
|
||||||
|
DOHString *ty;
|
||||||
|
DOHString *name;
|
||||||
|
DOHString *key;
|
||||||
|
int mlen1 = 0, mlen2 = 0, bestlen = 0;
|
||||||
|
DOH *obj1 = 0, *obj2 = 0;
|
||||||
|
DOH *bestobj, *bestn;
|
||||||
|
DOHHash *nextp;
|
||||||
|
|
||||||
|
if (!parms) {
|
||||||
|
bestobj = Getattr(nameset,"*obj*");
|
||||||
|
if (bestobj) *nmatch++;
|
||||||
|
return bestobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
ty = Getattr(parms,"type");
|
||||||
|
name = Getattr(parms,"name");
|
||||||
|
key = NewStringf("%s-%s",name,ty);
|
||||||
|
|
||||||
|
/* See if there is an exact name match */
|
||||||
|
nn1 = Getattr(nameset,key);
|
||||||
|
if (nn1) {
|
||||||
|
mlen1++;
|
||||||
|
obj1 = Swig_map_match_internal(nn1,Swig_next(parms), &mlen1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if there is a generic name match */
|
||||||
|
Clear(key);
|
||||||
|
Printf(key,"-%s",ty);
|
||||||
|
nn2 = Getattr(nameset,key);
|
||||||
|
if (nn2) {
|
||||||
|
mlen2++;
|
||||||
|
obj2 = Swig_map_match_internal(nn2, Swig_next(parms), &mlen2);
|
||||||
|
}
|
||||||
|
/* Pick the best match. Note: an exact name match is preferred */
|
||||||
|
if (obj1 && obj2) {
|
||||||
|
if (mlen2 > mlen1) {
|
||||||
|
bestlen = mlen2;
|
||||||
|
bestobj = obj2;
|
||||||
|
} else {
|
||||||
|
bestlen = mlen1;
|
||||||
|
bestobj = obj1;
|
||||||
|
}
|
||||||
|
} else if (obj1) {
|
||||||
|
bestobj = obj1;
|
||||||
|
bestlen = mlen1;
|
||||||
|
} else if (obj2) {
|
||||||
|
bestobj = obj2;
|
||||||
|
bestlen = mlen2;
|
||||||
|
}
|
||||||
|
if (!bestobj) {
|
||||||
|
bestobj = Getattr(nameset,"*obj*");
|
||||||
|
if (bestobj) bestlen = 1;
|
||||||
|
}
|
||||||
|
Delete(key);
|
||||||
|
*nmatch = *nmatch + bestlen;
|
||||||
|
return bestobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
DOH *
|
||||||
|
Swig_map_match(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, int *nmatch)
|
||||||
|
{
|
||||||
|
DOHHash *nameset;
|
||||||
|
int mlen = 0;
|
||||||
|
DOH *best;
|
||||||
|
|
||||||
|
/* Get the nameset */
|
||||||
|
nameset = Getattr(ruleset,rulename);
|
||||||
|
if (!nameset) return 0;
|
||||||
|
|
||||||
|
best = Swig_map_match_internal(nameset,parms,&mlen);
|
||||||
|
*nmatch = mlen;
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -418,6 +418,40 @@ DOHString *SwigType_prefix(DOHString *t) {
|
||||||
return NewString("");
|
return NewString("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* SwigType_array_ndim()
|
||||||
|
*
|
||||||
|
* Returns the number of dimensions of an array.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int SwigType_array_ndim(DOHString_or_char *id) {
|
||||||
|
int ndim = 0;
|
||||||
|
char *c = Char(id);
|
||||||
|
|
||||||
|
while (c && SwigType_isarray(c)) {
|
||||||
|
c = strchr(c,'.');
|
||||||
|
ndim++;
|
||||||
|
}
|
||||||
|
return ndim;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* SwigType_array_getdim()
|
||||||
|
*
|
||||||
|
* Get the value of the nth dimension.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
DOHString *SwigType_array_getdim(DOHString_or_char *id, int n) {
|
||||||
|
|
||||||
|
char *c = Char(id);
|
||||||
|
while (c && SwigType_isarray(c) && (n > 0)) {
|
||||||
|
c = strchr(c,'.');
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
if (n == 0) return SwigType_parm(c);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* SwigType_cstr(DOH *s, DOH *id)
|
* SwigType_cstr(DOH *s, DOH *id)
|
||||||
*
|
*
|
||||||
|
|
@ -705,25 +739,3 @@ int SwigType_cmp(DOHString_or_char *tpat, DOHString_or_char *type) {
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
int main() {
|
|
||||||
DOHString *a,*b,*c,*d;
|
|
||||||
|
|
||||||
a = NewString("int");
|
|
||||||
SwigType_add_pointer(a);
|
|
||||||
|
|
||||||
SwigType_typedef(a,"IntPtr");
|
|
||||||
|
|
||||||
b = NewString("IntPtr");
|
|
||||||
SwigType_add_array(b,"1000");
|
|
||||||
|
|
||||||
Printf(stdout,"b = '%s'\n", b);
|
|
||||||
c = SwigType_typedef_resolve(b);
|
|
||||||
Printf(stdout,"c = '%s'\n", c);
|
|
||||||
|
|
||||||
Printf(stdout,"cmp = %d\n", SwigType_cmp("a(1000).p.p.int",b));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,8 @@ extern DOHHash *SwigType_pop_scope();
|
||||||
extern DOHString *SwigType_typedef_resolve(DOHString_or_char *t);
|
extern DOHString *SwigType_typedef_resolve(DOHString_or_char *t);
|
||||||
extern int SwigType_istypedef(DOHString_or_char *t);
|
extern int SwigType_istypedef(DOHString_or_char *t);
|
||||||
extern int SwigType_cmp(DOHString_or_char *pat, DOHString_or_char *t);
|
extern int SwigType_cmp(DOHString_or_char *pat, DOHString_or_char *t);
|
||||||
|
extern int SwigType_array_ndim(DOHString_or_char *t);
|
||||||
|
extern DOHString *SwigType_array_getdim(DOHString_or_char *t, int n);
|
||||||
|
|
||||||
/* --- Parse tree support --- */
|
/* --- Parse tree support --- */
|
||||||
|
|
||||||
|
|
@ -159,6 +161,9 @@ extern void Swig_add_rule(DOHString_or_char *, int (*action)(DOH *, void *));
|
||||||
extern void Swig_add_rules(SwigRule ruleset[]);
|
extern void Swig_add_rules(SwigRule ruleset[]);
|
||||||
extern void Swig_clear_rules();
|
extern void Swig_clear_rules();
|
||||||
extern int Swig_emit(DOH *obj, void *clientdata);
|
extern int Swig_emit(DOH *obj, void *clientdata);
|
||||||
|
extern void Swig_cut_node(DOH *obj);
|
||||||
|
extern DOH *Swig_next(DOH *obj);
|
||||||
|
extern DOH *Swig_prev(DOH *obj);
|
||||||
|
|
||||||
/* -- Wrapper function Object */
|
/* -- Wrapper function Object */
|
||||||
|
|
||||||
|
|
@ -186,6 +191,11 @@ extern char *Swig_name_set(DOHString_or_char *vname);
|
||||||
extern char *Swig_name_construct(DOHString_or_char *classname);
|
extern char *Swig_name_construct(DOHString_or_char *classname);
|
||||||
extern char *Swig_name_destroy(DOHString_or_char *classname);
|
extern char *Swig_name_destroy(DOHString_or_char *classname);
|
||||||
|
|
||||||
|
/* --- Mapping interface --- */
|
||||||
|
|
||||||
|
extern void Swig_map_add(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, DOH *obj);
|
||||||
|
extern DOH *Swig_map_match(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, int *nmatch);
|
||||||
|
|
||||||
/* --- Misc --- */
|
/* --- Misc --- */
|
||||||
extern char *Swig_copy_string(const char *c);
|
extern char *Swig_copy_string(const char *c);
|
||||||
extern void Swig_banner(DOHFile *f);
|
extern void Swig_banner(DOHFile *f);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* tree.c
|
* tree.c
|
||||||
*
|
*
|
||||||
* This file provides some general purpose functions for walking through
|
* This file provides some general purpose functions for manipulating
|
||||||
* parse trees.
|
* parse trees.
|
||||||
*
|
*
|
||||||
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||||
|
|
@ -16,6 +16,21 @@ static char cvsroot[] = "$Header$";
|
||||||
|
|
||||||
static DOHHash *rules = 0;
|
static DOHHash *rules = 0;
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_next()
|
||||||
|
* Swig_prev()
|
||||||
|
*
|
||||||
|
* Return next/prev node in a parse tree
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
DOH *Swig_next(DOH *obj) {
|
||||||
|
return Getattr(obj,"next");
|
||||||
|
}
|
||||||
|
|
||||||
|
DOH *Swig_prev(DOH *obj) {
|
||||||
|
return Getattr(obj,"prev");
|
||||||
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------------
|
/* -----------------------------------------------------------------------------
|
||||||
* Swig_dump_tags()
|
* Swig_dump_tags()
|
||||||
*
|
*
|
||||||
|
|
@ -38,7 +53,7 @@ Swig_dump_tags(DOH *obj, DOH *root) {
|
||||||
Swig_dump_tags(cobj,newroot);
|
Swig_dump_tags(cobj,newroot);
|
||||||
Delete(newroot);
|
Delete(newroot);
|
||||||
}
|
}
|
||||||
obj = Getattr(obj,"sibling");
|
obj = Swig_next(obj);
|
||||||
}
|
}
|
||||||
if (!root)
|
if (!root)
|
||||||
Delete(croot);
|
Delete(croot);
|
||||||
|
|
@ -115,10 +130,62 @@ Swig_emit(DOH *obj, void *clientdata) {
|
||||||
} else {
|
} else {
|
||||||
Printf(stderr,"warning: no action defined for '%s'\n", tag);
|
Printf(stderr,"warning: no action defined for '%s'\n", tag);
|
||||||
}
|
}
|
||||||
obj = Getattr(obj,"sibling");
|
obj = Swig_next(obj);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* Swig_cut_node(DOH *obj)
|
||||||
|
*
|
||||||
|
* This function cuts an object out of a parse tree. To do this, the object
|
||||||
|
* MUST be properly initialized with "next", "prev", and "parent" attributes.
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void Swig_cut_node(DOH *obj) {
|
||||||
|
DOH *parent;
|
||||||
|
DOH *next;
|
||||||
|
DOH *prev;
|
||||||
|
|
||||||
|
parent = Getattr(obj,"parent");
|
||||||
|
assert(parent);
|
||||||
|
next = Getattr(obj,"next");
|
||||||
|
prev = Getattr(obj,"prev");
|
||||||
|
|
||||||
|
DohIncref(obj); /* Make sure object doesn't go away */
|
||||||
|
Delattr(obj,"parent"); /* Disassociate from my parent */
|
||||||
|
|
||||||
|
if (!next && !prev) {
|
||||||
|
/* Well, this is a single child. Guess we'll just update the parent their child is gone */
|
||||||
|
Delattr(parent,"child");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no next node, then this must be at the end of a list */
|
||||||
|
if (!next) {
|
||||||
|
Delattr(prev,"next"); /* Break the 'next' link in the previous node */
|
||||||
|
Delattr(obj,"prev"); /* Break my link back to the previous object */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No previous node. This must be the beginning of a list */
|
||||||
|
if (!prev) {
|
||||||
|
Delattr(next,"prev"); /* Break the 'prev' link of the next node */
|
||||||
|
Setattr(parent,"child",next); /* Update parent to point at next node */
|
||||||
|
Delattr(obj,"next"); /* Break my link to the next object */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* In the middle of a list someplace */
|
||||||
|
Setattr(prev,"next",next); /* Update previous node to my next node */
|
||||||
|
Setattr(next,"prev",prev); /* Update next node to my previous node */
|
||||||
|
Delattr(obj,"next");
|
||||||
|
Delattr(obj,"prev");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue