Substantial changes for new module system.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@908 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2000-10-02 03:04:25 +00:00
commit 28127aa9be
12 changed files with 1007 additions and 845 deletions

View file

@ -48,7 +48,7 @@ static int map[][2] = {
{ SWIG_TOKEN_BACKSLASH, -1 },
{ SWIG_TOKEN_ENDLINE, -1},
{ SWIG_TOKEN_STRING, STRING },
{ SWIG_TOKEN_POUND, POUND },
{ SWIG_TOKEN_POUND, -1 },
{ SWIG_TOKEN_PERCENT, -1 },
{ SWIG_TOKEN_COLON, COLON },
{ SWIG_TOKEN_DCOLON, DCOLON },
@ -384,7 +384,6 @@ yylex1(void) {
}
if (strcmp(yytext,"enum") == 0) return(ENUM);
if (strcmp(yytext,"sizeof") == 0) return(SIZEOF);
if (strcmp(yytext,"defined") == 0) return(DEFINED);
/* Ignored keywords */
if (strcmp(yytext,"volatile") == 0) return(lparse_yylex());
@ -393,12 +392,9 @@ yylex1(void) {
if (yytext[0] == '%') {
if (strcmp(yytext,"%module") == 0) return(MODULE);
if (strcmp(yytext,"%constant") == 0) return (CONSTANT);
if (strcmp(yytext,"%type") == 0) return (TYPE);
if (strcmp(yytext,"%file") == 0) return(FILEDIRECTIVE);
if (strcmp(yytext,"%insert") == 0) return (INSERT);
if (strcmp(yytext,"%macro") == 0) return(MACRO);
if (strcmp(yytext,"%typedef") == 0) return(TYPEDEF);
if (strcmp(yytext,"%native") == 0) return(NATIVE);
if (strcmp(yytext,"%pragma") == 0) return(PRAGMA);
if (strcmp(yytext,"%addmethods") == 0) return(ADDMETHODS);
if (strcmp(yytext,"%inline") == 0) return(INLINE);
@ -407,7 +403,7 @@ yylex1(void) {
if (strcmp(yytext,"%echo") == 0) return(ECHO);
if (strcmp(yytext,"%apply") == 0) return(APPLY);
if (strcmp(yytext,"%clear") == 0) return(CLEAR);
if (strcmp(yytext,"%map") == 0) return(MAP);
if (strcmp(yytext,"%scope") == 0) return(SCOPE);
}
/* Have an unknown identifier, as a last step, we'll */
/* do a typedef lookup on it. */

View file

@ -102,18 +102,18 @@ static DOH *TAG_VARIABLE = 0;
DohIntern(ATTR_PARM);
ATTR_STORAGE = NewString("storage");
DohIntern(ATTR_STORAGE);
TAG_ENUMVALUE = NewString("enumvalue");
TAG_ENUMVALUE = NewString("c:enumvalue");
DohIntern(TAG_ENUMVALUE);
TAG_FUNCTION = NewString("function");
TAG_FUNCTION = NewString("c:function");
DohIntern(TAG_FUNCTION);
TAG_VARIABLE = NewString("variable");
TAG_VARIABLE = NewString("c:variable");
DohIntern(TAG_VARIABLE);
}
LParse_push(str);
top = 0;
tp = NewHash();
Setattr(tp, "tag", "includefile");
Setattr(tp, "tag", "swig:top");
Setattr(tp, ATTR_NAME, Getfile(str));
yyparse();
Setattr(tp, ATTR_CHILD, top);
@ -216,10 +216,10 @@ static int promote(int t1, int t2) {
/* C Symbols */
%token <tok> LPAREN RPAREN LBRACE RBRACE COMMA SEMI PERIOD LBRACKET RBRACKET EQUAL COLON POUND
%token <tok> LPAREN RPAREN LBRACE RBRACE COMMA SEMI PERIOD LBRACKET RBRACKET EQUAL COLON
/* C keywords */
%token <tok> CONST DEFINED ENUM EXTERN SIZEOF STATIC STRUCT TYPEDEF UNION
%token <tok> CONST ENUM EXTERN SIZEOF STATIC STRUCT TYPEDEF UNION
/* C++ keywords */
%token <tok> CLASS FRIEND OPERATOR PRIVATE PROTECTED PUBLIC TEMPLATE THROW
@ -231,9 +231,9 @@ static int promote(int t1, int t2) {
%token <tok> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL
/* SWIG directives */
%token <tok> ADDMETHODS APPLY CLEAR CONSTANT ECHO EXCEPT
%token <tok> ILLEGAL FILEDIRECTIVE INLINE MACRO MODULE NAME NATIVE PRAGMA INSERT
%token <tok> TYPE TYPEMAP MAP
%token <tok> ADDMETHODS APPLY CLEAR CONSTANT ECHO EXCEPT SCOPE
%token <tok> ILLEGAL FILEDIRECTIVE INLINE MACRO MODULE NAME PRAGMA INSERT
%token <tok> TYPEMAP
/* Operators */
%left <tok> LOR
@ -248,8 +248,8 @@ static int promote(int t1, int t2) {
%left <tok> UMINUS NOT LNOT
%left <tok> DCOLON
%type <tok> idstring template_decl cpptype expr definetype def_args storage_spec pragma_arg ename
%type <node> parm parms ptail idlist stars
%type <tok> idstring template_decl cpptype expr definetype def_args storage_spec pragma_arg ename tm_code
%type <node> parm parms ptail stars
%type <node> array array2
%type <node> type strict_type opt_signed opt_unsigned
%type <decl> declaration
@ -258,8 +258,8 @@ static int promote(int t1, int t2) {
%type <tmname> tm_name
%type <tok> tm_method
%type <node> statement swig_directive c_declaration
%type <node> file_include code_block except_directive pragma_directive native_directive typemap_directive map_directive
%type <node> variable_decl function_decl enum_decl typedef_decl stail edecl typedeflist map_element
%type <node> file_include code_block except_directive pragma_directive typemap_directive scope_directive
%type <node> variable_decl function_decl enum_decl typedef_decl stail edecl typedeflist
%type <nodelist> enumlist interface
%type <node> inherit base_list
%type <tok> base_specifier access_specifier cpp_end ctor_end opt_id
@ -308,13 +308,6 @@ interface : interface statement {
statement : swig_directive { $$ = $1; }
| c_declaration { $$ = $1; }
| LBRACE interface RBRACE {
$$ = new_node("scope",$1.filename,$1.line);
if ($2.node) {
Setattr($$,ATTR_CHILD,$2.node);
setparent($$,$2.node);
}
}
| SEMI { $$ = 0; }
| error { $$ = 0; }
;
@ -323,7 +316,7 @@ statement : swig_directive { $$ = $1; }
* -- SWIG DIRECTIVES --
* ============================================================================= */
swig_directive : MODULE idstring {
$$ = new_node("module",$1.filename,$1.line);
$$ = new_node("swig:module",$1.filename,$1.line);
Setattr($$,ATTR_NAME,$2.text);
}
| MACRO ID COMMA STRING COMMA NUM_INT LBRACE {
@ -335,7 +328,7 @@ swig_directive : MODULE idstring {
$$ = $9.node;
}
| CONSTANT ID definetype SEMI {
$$ = new_node("constant",$2.filename, $2.line);
$$ = new_node("swig:constant",$2.filename, $2.line);
Setattr($$,ATTR_NAME,$2.text);
Setattr($$,ATTR_VALUE,$3.text);
switch($3.ivalue) {
@ -381,10 +374,25 @@ swig_directive : MODULE idstring {
| code_block { $$ = $1; }
| except_directive { $$ = $1; }
| pragma_directive { $$ = $1; }
| native_directive { $$ = $1; }
| typemap_directive { $$ = $1; }
| map_directive { $$ = $1; }
| TYPE ID idlist SEMI { $$ = 0; }
| scope_directive {$$ = $1; }
;
scope_directive: SCOPE LBRACE interface RBRACE {
$$ = new_node("swig:scope",$1.filename,$1.line);
if ($3.node) {
Setattr($$,ATTR_CHILD,$3.node);
setparent($$,$3.node);
}
}
| SCOPE LPAREN idstring RPAREN interface RBRACE {
$$ = new_node("swig:scope",$1.filename,$1.line);
if ($5.node) {
Setattr($$,ATTR_CHILD,$5.node);
Setattr($$,ATTR_NAME,$3.text);
setparent($$,$5.node);
}
}
;
echo_directive: ECHO HBLOCK { Printf(stderr,"%s\n", $2.text); }
@ -394,39 +402,39 @@ echo_directive: ECHO HBLOCK { Printf(stderr,"%s\n", $2.text); }
/* -- File inclusion directives -- */
file_include : FILEDIRECTIVE LPAREN STRING RPAREN STRING LBRACE {
$$ = new_node("file",$1.filename,$1.line);
Setattr($$,ATTR_NAME,$5.text);
Setattr($$,"type",$3.text);
$1.data = new_node("swig:file",$1.filename,$1.line);
Setattr($1.data,ATTR_NAME,$5.text);
Setattr($1.data,ATTR_TYPE,$3.text);
LParse_set_location($5.text,0);
} interface RBRACE {
LParse_set_location($6.filename,$6.line + 1);
$$ = $1.data;
if ($8.node) {
Setattr($$,ATTR_CHILD,$8.node);
setparent($$,$8.node);
}
}
;
/* -- Code inclusion directives -- */
code_block : INSERT LPAREN idstring RPAREN STRING {
$$ = new_node("insert", $1.filename, $1.line);
$$ = new_node("swig:insert", $1.filename, $1.line);
Setattr($$,"filename", $5.text);
Setattr($$,"section",$3.text);
}
| INSERT LPAREN idstring RPAREN HBLOCK {
$$ = new_node("insert",$1.filename, $1.line);
$$ = new_node("swig:insert",$1.filename, $1.line);
Setattr($$,"section",$3.text);
Setattr($$,"code",$5.text);
}
| HBLOCK {
$$ = new_node("insert",$1.filename, $1.line);
Setattr($$,"section","header");
$$ = new_node("swig:insert",$1.filename, $1.line);
Setattr($$,"code",$1.text);
}
| INLINE HBLOCK {
DOH *pp;
$$ = new_node("insert",$2.filename,$2.line);
Setattr($$,"section","header");
$$ = new_node("swig:insert",$2.filename,$2.line);
Setattr($$,"code", $2.text);
Seek($2.text,0,SEEK_SET);
pp = Preprocessor_parse($2.text);
@ -445,80 +453,70 @@ idstring : ID { $$ = $1; }
except_directive: EXCEPT LPAREN ID RPAREN LBRACE {
DOH *t;
t = LParse_skip_balanced('{','}');
$$ = new_node("exception",$1.filename,$1.line);
$$ = new_node("swig:exception",$1.filename,$1.line);
Setattr($$,"lang",$3.text);
Setattr($$,"code",t);
LParse_error($1.filename,$1.line,"Warning. Language specifier in %except is now ignored.\n");
}
/* A Generic Exception (no language specified */
/* A Generic Exception (no language specified) */
| EXCEPT LBRACE {
DOH *t;
t = LParse_skip_balanced('{','}');
$$ = new_node("exception",$1.filename,$1.line);
$$ = new_node("swig:exception",$1.filename,$1.line);
Setattr($$,"code",t);
}
/* Clear an exception */
| EXCEPT LPAREN ID RPAREN SEMI {
$$ = new_node("exception",$1.filename,$1.line);
$$ = new_node("swig:exception",$1.filename,$1.line);
Setattr($$,"lang",$3.text);
LParse_error($1.filename,$1.line,"Warning. Language specifier in %except is now ignored.\n");
}
/* Generic clear */
| EXCEPT SEMI {
$$ = new_node("exception",$1.filename,$1.line);
$$ = new_node("swig:exception",$1.filename,$1.line);
}
;
pragma_directive : PRAGMA idstring pragma_arg SEMI {
$$ = new_node("pragma",$1.filename,$1.line);
$$ = new_node("swig:pragma",$1.filename,$1.line);
Setattr($$,ATTR_NAME,$2.text);
Setattr($$,ATTR_VALUE,$3.text);
}
| PRAGMA LPAREN idstring RPAREN idstring pragma_arg SEMI {
$$ = new_node("pragma",$1.filename,$1.line);
$$ = new_node("swig:pragma",$1.filename,$1.line);
Setattr($$,ATTR_NAME,$5.text);
Setattr($$,"lang",$3.text);
Setattr($$,ATTR_VALUE,$6.text);
}
;
pragma_arg : definetype {
pragma_arg : idstring {
$$.text = $1.text;
}
| EQUAL definetype {
| EQUAL idstring {
$$.text = $2.text;
/* print warning message here */
}
| HBLOCK {
$$.text = $1.text;
}
| empty {
$$.text = 0;
}
;
/* A native wrapper function */
native_directive : NATIVE LBRACE interface RBRACE {
$$ = new_node("nativedirective",$1.filename,$1.line);
if ($3.node) {
Setattr($$,ATTR_CHILD,$3.node);
setparent($$,$3.node);
}
}
;
/* -- Typemap directives -- */
typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list tm_code {
DOH *o, *prev = 0, *t, *l;
int i;
t = LParse_skip_balanced('{','}');
t = $8.text;
$$ = 0;
for (i = 0; i < Len($7); i++) {
l = Getitem($7,i);
o = new_node("typemap",$1.filename, $1.line);
for (l = $7; l; l = Getnext(l)) {
o = new_node("swig:typemap",$1.filename, $1.line);
Setattr(o,"lang",$3.text);
Setattr(o,"method",$5.text);
Setattr(o,"code",t);
@ -534,14 +532,13 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
}
/* Create a new typemap in current language */
| TYPEMAP LPAREN tm_method RPAREN tm_list LBRACE {
| TYPEMAP LPAREN tm_method RPAREN tm_list tm_code {
DOH *o, *t, *l, *prev = 0;
int i;
t = LParse_skip_balanced('{','}');
/* t = LParse_skip_balanced('{','}');*/
t = $6.text;
$$ = 0;
for (i = 0; i < Len($5); i++) {
l = Getitem($5,i);
o = new_node("typemap",$1.filename, $1.line);
for (l = $5; l; l = Getnext(l)) {
o = new_node("swig:typemap",$1.filename, $1.line);
Setattr(o,"method",$3.text);
Setattr(o,"code",t);
Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
@ -557,11 +554,9 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
| TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list SEMI {
DOH *o, *l, *prev = 0;
int i;
$$ = 0;
for (i = 0; i < Len($7); i++) {
l = Getitem($7,i);
o = new_node("typemap",$1.filename, $1.line);
for (l = $7; l; l = Getnext(l)) {
o = new_node("swig:typemap",$1.filename, $1.line);
Setattr(o,"lang",$3.text);
Setattr(o,"method",$5.text);
Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
@ -576,11 +571,9 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
| TYPEMAP LPAREN tm_method RPAREN tm_list SEMI {
DOH *o, *l, *prev = 0;
int i;
$$ = 0;
for (i = 0; i < Len($5); i++) {
l = Getitem($5,i);
o = new_node("typemap",$1.filename, $1.line);
for (l = $5; l; l = Getnext(l)) {
o = new_node("swig:typemap",$1.filename, $1.line);
Setattr(o,"method",$3.text);
Setattr(o,ATTR_NAME,Getattr(l,ATTR_NAME));
Setattr(o,ATTR_TYPE,Getattr(l,ATTR_TYPE));
@ -594,11 +587,9 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
| TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list EQUAL tm_parm SEMI {
DOH *o, *l, *prev = 0;
int i;
$$ = 0;
for (i = 0; i < Len($7); i++) {
l = Getitem($7,i);
o = new_node("typemapcopy",$1.filename, $1.line);
for (l = $7; l ; l = Getnext(l)) {
o = new_node("swig:typemap",$1.filename, $1.line);
Setattr(o,"method", $5.text);
Setattr(o,"lang", $3.text);
Setattr(o,ATTR_NAME, Getattr(l,ATTR_NAME));
@ -616,11 +607,9 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
| TYPEMAP LPAREN tm_method RPAREN tm_list EQUAL tm_parm SEMI {
DOH *o, *l, *prev = 0;
int i;
$$ = 0;
for (i = 0; i < Len($5); i++) {
l = Getitem($5,i);
o = new_node("typemapcopy",$1.filename, $1.line);
for (l = $5; l; l = Getnext(l)) {
o = new_node("swig:typemap",$1.filename, $1.line);
Setattr(o,"method", $3.text);
Setattr(o,ATTR_NAME, Getattr(l,ATTR_NAME));
Setattr(o,ATTR_TYPE, Getattr(l,ATTR_TYPE));
@ -636,7 +625,7 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
/* Apply directive */
| APPLY tm_parm LBRACE tm_list RBRACE {
$$ = new_node("applydirective",$1.filename, $1.line);
$$ = new_node("swig:apply",$1.filename, $1.line);
Setattr($$,ATTR_NAME,Getattr($2,ATTR_NAME));
Setattr($$,ATTR_TYPE,Getattr($2,ATTR_TYPE));
Setattr($$,ATTR_PARMS,$4);
@ -645,11 +634,19 @@ typemap_directive: TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list LBRACE {
/* Clear directive */
| CLEAR tm_list SEMI {
$$ = new_node("cleardirective",$1.filename, $1.line);
$$ = new_node("swig:clear",$1.filename, $1.line);
Setattr($$,ATTR_PARMS,$2);
}
;
tm_code : STRING {
$$.text = $1.text;
}
| LBRACE {
$$.text = LParse_skip_balanced('{','}');
}
;
tm_method : ID {
$$ = $1;
}
@ -660,16 +657,22 @@ tm_method : ID {
tm_list : tm_parm tm_tail {
Insert($2,0,$1);
$$ = $2;
if ($2) {
Setattr($1,ATTR_NEXT,$2);
Setattr($2,ATTR_PREV,$1);
}
$$ = $1;
}
;
tm_tail : COMMA tm_parm tm_tail {
Insert($3,0,$2);
$$ = $3;
if ($3) {
Setattr($2,ATTR_NEXT,$3);
Setattr($3,ATTR_PREV,$2);
}
$$ = $2;
}
| empty { $$ = NewList(); }
| empty { $$ = 0; }
;
tm_parm : type tm_name {
@ -739,101 +742,6 @@ 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);
/* Uh. Okay, this is a little nasty. We're going to take the
children and split them into rules and locals */
{
DOHHash *rules;
DOHHash *children = 0;
DOHHash *node, *nnode, *pnode;
rules = NewHash();
node = $7;
children = node;
pnode = 0;
while (node) {
nnode = Getattr(node,"next");
if (Cmp(Getattr(node,"tag"),"maprule") == 0) {
Setattr(rules,Getattr(node,"name"),Getattr(node,"code"));
if (pnode) {
if (nnode)
Setattr(pnode,"next",nnode);
else
Delattr(pnode,"next");
} else {
children = nnode;
}
Delete(node);
} else {
pnode = node;
}
node = nnode;
}
Setattr($$,"rules",rules);
if (children) {
Setattr($$,ATTR_CHILD,children);
setparent($$,children);
}
}
}
;
map_element : variable_decl map_element {
DOH *o, *o2 = 0;
$$ = $1;
o = $1;
while (o) {
o2 = o;
o = Getattr(o,ATTR_NEXT);
}
Setattr(o2,ATTR_NEXT,$2);
}
| function_decl map_element {
DOH *o, *o2 = 0;
$$ = $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('{','}');
Delitem(text,0);
Delitem(text,DOH_END);
$$ = new_node("maprule",$1.filename, $1.line);
Setattr($$,ATTR_NAME,$1.text);
Setattr($$,"code",text);
$1.text = $$;
} map_element {
$$ = $1.text;
if ($5)
Setattr($$,ATTR_NEXT,$5);
}
| STRING COLON STRING SEMI {
$$ = new_node("maprule",$1.filename, $1.line);
Setattr($$,ATTR_NAME,$1.text);
Setattr($$,"code",$3.text);
$1.text = $$;
} map_element {
$$ = $1.text;
if ($6)
Setattr($$,ATTR_NEXT,$6);
}
| empty {
$$ = 0;
}
;
/* =============================================================================
* -- C Declarations --
* ============================================================================= */
@ -946,14 +854,14 @@ function_decl : storage_spec type declaration LPAREN parms RPAREN cpp_const sta
/* A C++ destructor */
| NOT ID LPAREN parms RPAREN cpp_end {
$$ = new_node("destructor",$2.filename,$2.line);
$$ = new_node("c:destructor",$2.filename,$2.line);
Setattr($$,ATTR_NAME,$2.text);
if ($6.text) {
Setattr($$,"code",$6.text);
}
}
| NOT ID LPAREN parms RPAREN cpp_const SEMI {
$$ = new_node("destructor",$2.filename,$2.line);
$$ = new_node("c:destructor",$2.filename,$2.line);
Setattr($$,ATTR_NAME,$2.text);
}
@ -1013,7 +921,7 @@ cpp_const : CONST {}
/* Enumerations */
enum_decl : storage_spec ENUM ename LBRACE enumlist RBRACE SEMI {
$$ = new_node("enum", $2.filename,$2.line);
$$ = new_node("c:enum", $2.filename,$2.line);
Setattr($$,ATTR_NAME,$2.text);
Setattr($$,ATTR_CHILD,$5.node);
setparent($$,$5.node);
@ -1023,14 +931,14 @@ enum_decl : storage_spec ENUM ename LBRACE enumlist RBRACE SEMI {
/* A typdef'd enum. Pretty common in C headers */
| TYPEDEF ENUM ename LBRACE enumlist RBRACE ID SEMI {
$$ = new_node("enum",$2.filename,$2.line);
$$ = new_node("c:enum",$2.filename,$2.line);
Setattr($$,ATTR_NAME,$3.text);
Setattr($$,ATTR_CHILD,$5.node);
setparent($$,$5.node);
/* Add typedef for enum */
{
DOH *o;
o = new_node("typedef",$7.filename,$7.line);
o = new_node("c:typedef",$7.filename,$7.line);
Setattr(o,ATTR_NAME,$7.text);
Setattr(o,ATTR_TYPE,$3.text);
Setattr($$,ATTR_NEXT,o);
@ -1070,7 +978,7 @@ edecl : ID {
typedef_decl : TYPEDEF type declaration array2 typedeflist SEMI {
DOH *t, *d, *o, *prev;
int i;
$$ = new_node("typedef", $1.filename,$1.line);
$$ = new_node("c:typedef", $1.filename,$1.line);
t = Copy($2);
SwigType_push($2,$3.decl);
if ($4) SwigType_push($2,$4);
@ -1081,7 +989,7 @@ typedef_decl : TYPEDEF type declaration array2 typedeflist SEMI {
for (i = 0; i < Len($5); i++) {
DOH *ty;
d = Getitem($5,i);
o = new_node("typedef",$1.filename,$1.line);
o = new_node("c:typedef",$1.filename,$1.line);
ty = Copy(t);
SwigType_push(ty,Getattr(d,"decl"));
SwigType_push(ty,Getattr(d,"array"));
@ -1096,7 +1004,7 @@ typedef_decl : TYPEDEF type declaration array2 typedeflist SEMI {
/* A rudimentary typedef involving function pointers */
| TYPEDEF type LPAREN stars pname RPAREN LPAREN parms RPAREN SEMI {
$$ = new_node("typedef", $1.filename,$1.line);
$$ = new_node("c:typedef", $1.filename,$1.line);
SwigType_push($2,parmstotype($8));
SwigType_push($2,$4);
if ($5.array)
@ -1108,7 +1016,7 @@ typedef_decl : TYPEDEF type declaration array2 typedeflist SEMI {
/* A typedef involving function pointers again */
| TYPEDEF type stars LPAREN stars pname RPAREN LPAREN parms RPAREN SEMI {
$$ = new_node("typedef", $1.filename,$1.line);
$$ = new_node("c:typedef", $1.filename,$1.line);
SwigType_push($2,$3);
SwigType_push($2,parmstotype($9));
SwigType_push($2,$5);
@ -1152,10 +1060,11 @@ cpp_decl : cpp_class { $$ = $1; }
;
cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id SEMI {
$$ = new_node("class",$3.filename,$3.line);
$$ = new_node("c:class",$3.filename,$3.line);
Setattr($$,"classtype",$2.text);
Setattr($$,ATTR_NAME,$3.text);
Setattr($$,"bases", $4);
Setattr($$,"namespace",$3.text);
if ($6.node) {
Setattr($$,ATTR_CHILD,$6.node);
setparent($$,$6.node);
@ -1166,7 +1075,7 @@ cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id S
}
| storage_spec cpptype LBRACE interface RBRACE opt_id SEMI {
$$ = new_node("class",$3.filename,$3.line);
$$ = new_node("c:class",$3.filename,$3.line);
Setattr($$,"classtype",$2.text);
if ($4.node) {
Setattr($$,ATTR_CHILD,$4.node);
@ -1179,10 +1088,11 @@ cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id S
/* Class with a typedef */
| TYPEDEF cpptype ID inherit LBRACE interface RBRACE declaration typedeflist {
$$ = new_node("class",$3.filename,$3.line);
$$ = new_node("c:class",$3.filename,$3.line);
Setattr($$,"classtype",$2.text);
Setattr($$,ATTR_NAME,$3.text);
Setattr($$,"bases",$4);
Setattr($$,"namespace",$3.text);
if ($6.node) {
Setattr($$,ATTR_CHILD,$6.node);
setparent($$,$6.node);
@ -1194,7 +1104,7 @@ cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id S
/* Go add a bunch of typedef declarations */
DOH *o, *t, *prev, *d;
int i;
o = new_node("typedef",$3.filename,$3.line);
o = new_node("c:typedef",$3.filename,$3.line);
Setattr(o,ATTR_NAME,$8.id);
t = Copy($3.text);
SwigType_push(t,$8.decl);
@ -1203,7 +1113,7 @@ cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id S
prev = o;
for (i = 0; i < Len($9); i++) {
d = Getitem($9,i);
o = new_node("typedef",$3.filename,$3.line);
o = new_node("c:typedef",$3.filename,$3.line);
t = Copy($3.text);
SwigType_push(t,Getattr(d,"decl"));
SwigType_push(t,Getattr(d,"array"));
@ -1219,7 +1129,7 @@ cpp_class : storage_spec cpptype ID inherit LBRACE interface RBRACE opt_id S
/* An unnamed struct with a typedef */
| TYPEDEF cpptype LBRACE interface RBRACE declaration typedeflist {
$$ = new_node("class",$3.filename,$3.line);
$$ = new_node("c:class",$3.filename,$3.line);
Setattr($$,"classtype",$2.text);
if ($4.node) {
Setattr($$,ATTR_CHILD,$4.node);
@ -1305,13 +1215,21 @@ mem_initializer : ID LPAREN { LParse_skip_balanced('(',')'); }
cpp_other :/* A dummy class name */
storage_spec cpptype ID SEMI {
DOH *o = new_node("classdecl",$4.filename,$4.line);
DOH *o = new_node("c:classdecl",$4.filename,$4.line);
Setattr(o,ATTR_NAME,$3.text);
}
| PUBLIC COLON { $$ = new_node("public",$1.filename,$1.line); }
| PRIVATE COLON { $$ = new_node("private",$1.filename,$1.line); }
| PROTECTED COLON { $$ = new_node("protected",$1.filename,$1.line); }
| PUBLIC COLON {
$$ = new_node("c:access",$1.filename,$1.line);
Setattr($$,ATTR_NAME,"public");
}
| PRIVATE COLON {
$$ = new_node("c:access",$1.filename,$1.line);
Setattr($$,ATTR_NAME,"public");
}
| PROTECTED COLON {
$$ = new_node("c:access",$1.filename,$1.line);
Setattr($$,ATTR_NAME,"public");
}
| FRIEND {
LParse_skip_decl();
@ -1335,7 +1253,7 @@ cpp_other :/* A dummy class name */
/* %addmethods directive */
| ADDMETHODS opt_id LBRACE interface RBRACE {
$$ = new_node("addmethods",$1.filename,$1.line);
$$ = new_node("swig:addmethods",$1.filename,$1.line);
if ($1.text)
Setattr($$,ATTR_NAME,$1.text);
if ($4.node) {
@ -1808,14 +1726,6 @@ expr : NUM_INT {
}
;
idlist : idlist COMMA ID {
Append($$,$3.text);
}
| empty {
$$ = NewList();
}
;
empty : ;
%%

View file

@ -15,40 +15,71 @@ Attribute name Description
"parent" - Parent node
"child" - First child node (is the start of a linked list)
2. Parse tree nodes
2. Reserved attribute names
Attributes starting with a "-" are used internally by the parsed and should not be
used as attributes by any extension module.
3. General philosophy
In SWIG1.1, all SWIG directives were defined as parser rules. This made for a rather
large and inflexible parsing module. In this version, the parser has been greatly
reduced to a few very general purpose directives. Older SWIG directives, in turn,
are then implemented as preprocessor macros. For example, in SWIG1.3 the following
directive is used to insert code into part of the output:
%insert(section) %{ code %}
Then, the following macros are used to emulate old behavior
#define %wrapper %insert("wrapper")
#define %init %insert("init")
#define %runtime %insert("runtime")
... etc ...
Similarly, most old SWIG directives such as "%readonly", "%readwrite", and so forth have
been consolidated into a single "%pragma" directive.
By consolidating parser rules, the number of tags are reduced and language module
implementation is simplified.
4. Namespaces
Swig directives are tagged as "swig:tagname".
C/C++ declarations are tagged as "c:decl".
Motivation: Maybe I'll add other stuff someday like "fortran:decl".
5. Parse Tree nodes
The following list describes all of the possible nodes that can be
produced by the parser and their attributes (not including the common
attributes above).
5.1 SWIG Directives
tag : "scope"
syntax : { statements }
attributes : None. "child" attribute contains nodes within the scope.
tag : "swig:scope"
syntax : %scope(name) { statements }
attributes : "name" - Scope name
"child" - attribute contains nodes within the scope.
tag : "module"
tag : "swig:module"
syntax : %module idstring
attributes : "name" - Module name
tag : "constant"
tag : "swig:constant"
syntax : %constant name value;
attributes : "name" - Constant name
"value" - Constant value
"type" - Constant type
tag : "includefile"
tag : "swig:file"
syntax : %include filename
attributes : None
: %extern filename
: %import filename
attributes : "type" - File type ("include", "extern", "import")
tag : "externfile"
syntax : %extern filename
attributes : None
tag : "importfile"
syntax : %import filename
attributes : None
tag : "insert"
tag : "swig:insert"
syntax : %insert(section) "filename"
%insert(section) %{ code %}
%{ code %} Note: same as %insert("header") %{ code %}
@ -57,11 +88,95 @@ attributes : "section" - Code section
"filename" - File to include (if given)
"code" - Code to include (if given)
tag : "pragma"
tag : "swig:pragma"
syntax : %pragma name [ value ];
%pragma(lang) name [ value ];
tag : "swig:exception"
syntax : %exception { code }
attributes : "code" - Exception code
tag : "swig:typemap"
syntax : %typemap(method) type (parms) {
code
}
| %typemap(method) type (parms) "code";
attributes : "method" - Typemap method
"code" - Typemap code (if supplied)
"type" - Type
"name" - Typemap Name
"parms" - Parameter list
"srcname" - Source name (of another typemap)
"srctype" - Source type
Notes : If code is not set, srcname and srctype may point to another typemap
in which a copy is performed.
If neither code nor srcname and srctype are set, then the typemap
is deleted.
tag : "swig:apply"
syntax : %apply type name { parms }
attributes : "name"
"type"
"parms"
tag : "swig:clear"
syntax : %clear parms;
attributes : "parms"
tag : "swig:addmethods"
syntax : %addmethods [(name)] { statements }
attributes : "name" - Class name (optional)
5.2 C/C++ Declarations
tag : "c:function"
attributes : "name" - Function name
"type" - Return type
"parms" - Parameters
"storage" - Storage class
"code" - Code
tag : "c:variable"
attributes : "name" - Variable name
"type" - Variable type
"storage" - Storage class
"value" - Value
tag : "c:typedef"
attributes : "name" - Typedef name
"type" - Typedef type
tag : "c:enum"
attributes : "name" - Enum name
"child" - Enum members
tag : "c:enumvalue"
attributes : "name" - Enum value name
"value" - Enum value
tag : "c:class"
attributes : "name" - Class name
"bases" - Base classes
"classtype" - { struct, class, union }
"altname" - Alternative name (from typedef)
"namespace" - Namespace attribute (used to get fully qualified names)
tag : "c:destructor"
attributes : "name" - Destructor name
tag : "c:classdecl"
attributes : "name" - Class name
tag : "c:access"
attributes : "name" - { public, private, protected }

View file

@ -5,8 +5,8 @@
srcdir = @srcdir@
VPATH = @srcdir@
SRCS = test.c
OBJS = test.o
SRCS = init.c test.c
OBJS = init.o test.o
prefix = @prefix@
exec_prefix = @exec_prefix@

37
Source/Modules/init.c Normal file
View file

@ -0,0 +1,37 @@
/* -----------------------------------------------------------------------------
* init.c
*
* Initialize built-in SWIG modules.
*
* 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"
extern void testmodule();
static void (*modules[])(void) = {
testmodule,
0
};
/* -----------------------------------------------------------------------------
* init_modules()
*
* ----------------------------------------------------------------------------- */
void init_modules() {
int i = 0;
while (modules[i]) {
(*modules[i])();
i++;
}
}
int main(int argc, char **argv) {
init_modules();
return Swig_main(argc, argv);
}

View file

@ -1,647 +1,218 @@
/* -----------------------------------------------------------------------------
* test.c
*
* This module implements a SWIG module in the new tag-based parser.
* This is work in progress.
* This module is used to test the tag-based parser.
* ----------------------------------------------------------------------------- */
#include "swig.h"
#include "preprocessor.h"
#include "lparse.h"
#ifdef OLDSTUFF
/* -------- Module variables ------- */
int test_unknown(DOH *node, void *clientdata) {
Printf(stdout,"::: Unknown tag - '%s'\n", Getattr(node,"tag"));
return 0;
}
#define CPLUS_PUBLIC 1
#define CPLUS_PRIVATE 2
#define CPLUS_PROTECTED 3
static DOHFile *runtime = 0;
static DOHFile *headers = 0;
static DOHFile *wrappers = 0;
static DOHFile *init = 0;
static DOH *config_top = 0;
static int ExternMode = 0;
static int ImportMode = 0;
static int ReadOnly = 0;
static int CPlusMode = CPLUS_PUBLIC;
static int NewMode = 0;
static DOHString *ModuleName = 0;
static int NativeMode = 0;
static DOHString *NewName = 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 -------- */
static int
emit_includefile(DOH *obj, void *clientdata) {
int test_file(DOH *node, void *clientdata) {
DOH *c;
c = Getattr(obj,"child");
if (c) {
Swig_emit(c,clientdata);
}
}
static int
emit_externfile(DOH *obj, void *clientdata) {
DOH *c;
int oldem = ExternMode;
ExternMode = 1;
c = Getattr(obj,"child");
if (c) {
Swig_emit(c,clientdata);
}
ExternMode = oldem;
}
static int
emit_importfile(DOH *obj, void *clientdata) {
DOH *c;
int oldem = ExternMode;
ExternMode = 1;
ImportMode = 1;
c = Getattr(obj,"child");
if (c) {
Swig_emit(c,clientdata);
}
ExternMode = oldem;
ImportMode = 0;
}
static int
emit_scope(DOH *obj, void *clientdata) {
DOH *c;
c = Getattr(obj,"child");
if (c) {
Swig_emit(c,clientdata);
}
Printf(stdout,"::: File\n");
Printf(stdout," name = '%s'\n", Getattr(node,"name"));
Printf(stdout," type = '%s'\n", Getattr(node,"type"));
c = Getchild(node);
Printf(stdout," # elements = %d\n", Swig_count_nodes(c));
Swig_emit_all(c,clientdata);
return 0;
}
/* -------- Code blocks -------- */
/* %{ ... %} directive */
static int
emit_headerblock(DOH *obj, void *clientdata) {
Dump(Getattr(obj,"code"),headers);
int test_module(DOH *node, void *clientdata) {
Printf(stdout,"::: Module\n");
Printf(stdout," name = '%s'\n", Getname(node));
return 0;
}
/* %wrapper %{ ... %} directive */
static int
emit_wrapperblock(DOH *obj, void *clientdata) {
Dump(Getattr(obj,"code"),wrappers);
int test_insert(DOH *node, void *clientdata) {
Printf(stdout,"::: Insert\n");
Printf(stdout," section = '%s'\n", Getattr(node,"section"));
Printf(stdout," filename = '%s'\n", Getattr(node,"filename"));
Printf(stdout," code = '%s'\n", Getattr(node,"code"));
return 0;
}
/* %init %{ ... %} directive */
static int
emit_initblock(DOH *obj, void *clientdata) {
Dump(Getattr(obj,"code"),init);
int test_pragma(DOH *node, void *clientdata) {
Printf(stdout,"::: Pragma\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," value = '%s'\n", Getvalue(node));
return 0;
}
/* %runtime %{ ... %} directive */
static int
emit_runtimeblock(DOH *obj, void *clientdata) {
Dump(Getattr(obj,"code"),runtime);
return 0;
}
/* ------ Basic C declarations ----- */
/* -----------------------------------------------------------------------------
* function
* ----------------------------------------------------------------------------- */
static int
emit_function(DOH *obj, void *clientdata) {
DOHString *name, *scriptname, *type, *storage;
DOHList *parms;
DOHHash *p;
Wrapper *wf;
int numarg = 0, numopt = 0;
int i, pn;
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 = NewWrapper();
Printv(wf->def,
"static PyObject *", Swig_name_wrapper(scriptname), "(PyObject *self, PyObject *args) {\n",
0);
/* Loop over all of the function arguments and build pieces of the wrapper function */
{
DOHString *parsestr; /* Format string for parsing arguments */
DOHString *argstr; /* List of arguments */
DOHString *inputstr;
DOHString *checkstr;
DOHString *initstr;
DOHString *targetstr;
parsestr = NewString("");
argstr = NewString("");
inputstr = NewString("");
checkstr = NewString("");
initstr = NewString("");
targetstr = NewString("");
p = parms;
pn = 0;
while (p) {
int nmatch = 0;
DOHHash *map;
DOHHash *rules;
char suffix[32];
sprintf(suffix,"_%d", pn);
map = Swig_map_match(Rules, "argument", p, &nmatch);
if (!map) {
Printf(stderr,"%s:%d. No argument rule for %S\n", Getfile(p),Getline(p),SwigType_cstr(Getattr(p,"type"),Getattr(p,"name")));
return;
}
/* Pull out the rules */
rules = Getattr(map,"rules");
if (rules) {
DOH *linit;
DOH *lparse;
DOH *linput;
DOH *lcheck;
DOH *largstr;
DOH *ltarget;
linit = Copy(Getattr(rules,"init"));
lparse = Copy(Getattr(rules,"parse"));
linput = Copy(Getattr(rules,"input"));
lcheck = Copy(Getattr(rules,"check"));
ltarget = Copy(Getattr(rules,"target"));
largstr = 0;
/* Construct the parse and argument strings */
if (lparse) {
DOHList *sp;
DOHString *pstr;
int i;
Seek(lparse,0,SEEK_SET);
sp = DohSplit(lparse,",",-1);
pstr = Getitem(sp,0);
if (pstr) {
char *c = Char(pstr);
while (*c && (*c != '\"')) c++;
c++;
while (*c && (*c != '\"')) {
Putc(*c, parsestr);
c++;
}
}
largstr = NewString("");
for (i = 1; i < Len(sp); i++) {
Printf(largstr,",%s",Getitem(sp,i));
}
Delete(sp);
}
/* Variable substitution. We're going to walk down the map's children and perform variable name
replacements */
{
DOH *c = Getattr(map,"child");
while (c) {
if (Cmp(Getattr(c,"tag"),"variable") == 0) {
DOH *vname;
DOH *rname;
DOH *vtype;
DOH *vvalue;
DOH *storage;
DOH *local;
storage = Getattr(c,"storage");
vname = Getattr(c,"name");
vtype = Getattr(c,"type");
vvalue = Getattr(c,"value");
rname = NewStringf("%s_%d",vname,pn);
if (largstr) Replace(largstr,vname,rname,DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
if (linit) Replace(linit,vname,rname,DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
if (linput) Replace(linput,vname,rname,DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
if (lcheck) Replace(lcheck,vname,rname,DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
if (ltarget) Replace(ltarget,vname,rname, DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
/* Declare as local to wrapper function */
local = NewString("");
Printf(local,"%S", SwigType_cstr(vtype,rname));
if (vvalue) {
Printf(local," = %s", vvalue);
}
Wrapper_add_local(wf,rname,local);
Delete(local);
Delete(rname);
}
c = Swig_next(c);
}
}
if (largstr) Append(argstr, largstr);
if (linput) Append(inputstr,linput);
if (lcheck) Append(checkstr,lcheck);
if (linit) Append(initstr,linit);
if (ltarget) Printf(targetstr,"%s,", ltarget);
Delete(largstr);
Delete(linput);
Delete(lcheck);
Delete(linit);
Delete(ltarget);
}
while (nmatch > 0) {
p = Swig_next(p);
nmatch--;
pn++;
}
int test_typemap(DOH *node, void *clientdata) {
Printf(stdout,"::: Typemap\n");
Printf(stdout," type = '%s'\n", Gettype(node));
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," code = '%s'\n", Getattr(node,"code"));
Printf(stdout," srcname = '%s'\n", Getattr(node,"srcname"));
Printf(stdout," srctype = '%s'\n", Getattr(node,"srctype"));
{
DOH *p = Getattr(node,"parms");
if (p) {
Printf(stdout," parms = '%s'\n", ParmList_protostr(p));
}
/* Dump out the wrapper code */
if (pn > 0)
Delitem(targetstr,DOH_END);
Printv(wf->code,
initstr,
"if (PyParse_Args(\"", parsestr, "\"", argstr, ") == NULL) return NULL;\n",
inputstr,
checkstr,
"result = ", name, "(", targetstr, ");\n",
0);
}
Printf(wf->code,"}\n");
Wrapper_print(wf,wrappers);
function_exit:
Delete(NewName);
NewName = 0;
return 0;
}
/* -----------------------------------------------------------------------------
* variable
* ----------------------------------------------------------------------------- */
static int
emit_variable(DOH *obj, void *clientdata) {
Printf(stdout,"variable\n");
int test_apply(DOH *node, void *clientdata) {
Printf(stdout,"::: Apply\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," type = '%s'\n", Gettype(node));
Printf(stdout," parms = (%s)\n", ParmList_protostr(Getattr(node,"parms")));
return 0;
}
/* -----------------------------------------------------------------------------
* constant
* ----------------------------------------------------------------------------- */
static int
emit_constant(DOH *obj, void *clientdata) {
Printf(stdout,"constant\n");
int test_exception(DOH *node, void *clientdata) {
Printf(stdout,"::: Exception\n");
Printf(stdout," code = '%s'\n", Getattr(node,"code"));
return 0;
}
static int
emit_typedef(DOH *obj, void *clientdata) {
Printf(stdout,"typedef\n");
int test_clear(DOH *node, void *clientdata) {
Printf(stdout,"::: Clear\n");
Printf(stdout," parms = (%s)\n", ParmList_protostr(Getattr(node,"parms")));
return 0;
}
static int
emit_enum(DOH *obj, void *clientdata) {
int test_constant(DOH *node, void *clientdata) {
Printf(stdout,"::: Constant\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," type = '%s'\n", Gettype(node));
Printf(stdout," value = '%s'\n", Getvalue(node));
return 0;
}
int test_function(DOH *node, void *clientdata) {
Printf(stdout,"::: Function\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," type = '%s'\n", Gettype(node));
Printf(stdout," parms = (%s)\n", ParmList_protostr(Getattr(node,"parms")));
Printf(stdout," storage = '%s'\n", Getattr(node,"storage"));
Printf(stdout," code = '%s'\n", Getattr(node,"code"));
return 0;
}
int test_variable(DOH *node, void *clientdata) {
Printf(stdout,"::: Variable\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," type = '%s'\n", Gettype(node));
Printf(stdout," storage = '%s'\n", Getattr(node,"storage"));
Printf(stdout," value = '%s'\n", Getattr(node,"value"));
return 0;
}
int test_typedef(DOH *node, void *clientdata) {
Printf(stdout,"::: Typedef\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," type = '%s'\n", Gettype(node));
return 0;
}
int test_enum(DOH *node, void *clientdata) {
DOH *c;
Printf(stdout,"enum\n");
c = Getattr(obj,"child");
if (c) {
Swig_emit(c,clientdata);
}
Printf(stdout,"::: Enum\n");
Printf(stdout," name = '%s'\n", Getname(node));
c = Getchild(node);
Swig_emit_all(c,clientdata);
return 0;
}
static int
emit_enumvalue(DOH *obj, void *clientdata) {
Printf(stdout,"enumvalue\n");
int test_enumvalue(DOH *node, void *clientdata) {
Printf(stdout,"::: Enumvalue\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," value = '%s'\n", Getvalue(node));
return 0;
}
/* ------ C++ stuff ------ */
static int
emit_class(DOH *obj, void *clientdata) {
int test_class(DOH *node, void *clientdata) {
DOH *c;
Printf(stdout,"class\n");
c = Getattr(obj, "child");
if (c) {
int ic = InClass;
InClass = 1;
Swig_emit(c,clientdata);
InClass = ic;
}
Printf(stdout,"::: Class\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," bases = %s\n", Getattr(node,"bases"));
Printf(stdout," altname = '%s'\n", Getattr(node,"altname"));
Printf(stdout," classtype = '%s'\n", Getattr(node,"classtype"));
c = Getchild(node);
Swig_emit_all(c,clientdata);
return 0;
}
static int
emit_destructor(DOH *obj, void *clientdata) {
Printf(stdout,"destructor\n");
int test_classdecl(DOH *node, void *clientdata) {
Printf(stdout,"::: Classdecl\n");
Printf(stdout," name = '%s'\n", Getname(node));
return 0;
}
static int
emit_classdecl(DOH *obj, void *clientdata) {
Printf(stdout,"classdecl\n");
return 0;
}
static int
emit_private(DOH *obj, void *clientdata) {
CPlusMode = CPLUS_PRIVATE;
return 0;
}
static int
emit_protected(DOH *obj, void *clientdata) {
CPlusMode = CPLUS_PROTECTED;
return 0;
}
static int
emit_public(DOH *obj, void *clientdata) {
CPlusMode = CPLUS_PUBLIC;
return 0;
}
static int
emit_addmethods(DOH *obj, void *clientdata) {
int test_addmethods(DOH *node, void *clientdata) {
DOH *c;
Printf(stdout,"addmethods\n");
c = Getattr(obj, "child");
if (c) {
Swig_emit(c,clientdata);
}
Printf(stdout,"::: Addmethods\n");
Printf(stdout," name = '%s'\n", Getname(node));
c = Getchild(node);
Swig_emit_all(c,clientdata);
return 0;
}
/* ------ SWIG directives ------ */
static int
emit_moduledirective(DOH *obj, void *clientdata) {
if (!ModuleName) {
ModuleName = Getattr(obj,"name");
DohIncref(ModuleName);
}
int test_destructor(DOH *node, void *clientdata) {
Printf(stdout,"::: Destructor\n");
Printf(stdout," name = '%s'\n", Getname(node));
Printf(stdout," code = '%s'\n", Getattr(node,"code"));
return 0;
}
static int
emit_renamedirective(DOH *obj, void *clientdata) {
DOHString *name, *rename;
name = Getattr(obj,"oldname");
rename = Getattr(obj,"newname");
if (name && rename)
Setattr(RenameHash,name,rename);
int test_access(DOH *node, void *clientdata) {
Printf(stdout,"::: AccessSpecifier\n");
Printf(stdout," name = '%s'\n", Getname(node));
return 0;
}
static int
emit_readonlydirective(DOH *obj, void *clientdata) {
ReadOnly = 1;
return 0;
}
static int
emit_readwritedirective(DOH *obj, void *clientdata) {
ReadOnly = 0;
return 0;
}
static int
emit_namedirective(DOH *obj, void *clientdata) {
if (NewName) Delete(NewName);
NewName = Getattr(obj,"name");
if (NewName) DohIncref(NewName);
return 0;
}
static int
emit_newdirective(DOH *obj, void *clientdata) {
NewMode = 1;
return 0;
}
static int
emit_exceptiondirective(DOH *obj, void *clientdata) {
Printf(stdout,"exceptiondirective\n");
return 0;
}
static int
emit_pragmadirective(DOH *obj, void *clientdata) {
Printf(stdout,"pragmadirective\n");
return 0;
}
static int
emit_nativedirective(DOH *obj, void *clientdata) {
DOH *c;
int oldnative = NativeMode;
NativeMode = 1;
c = Getattr(obj, "child");
if (c) {
Swig_emit(c,clientdata);
}
NativeMode = oldnative;
return 0;
}
static int
emit_typemap(DOH *obj, void *clientdata) {
Printf(stdout,"typemap\n");
return 0;
}
static int
emit_typemapcopy(DOH *obj, void *clientdata) {
Printf(stdout,"typemapcopy\n");
return 0;
}
static int
emit_applydirective(DOH *obj, void *clientdata) {
Printf(stdout,"applydirective\n");
return 0;
}
static int
emit_cleardirective(DOH *obj, void *clientdata) {
Printf(stdout,"cleardirective\n");
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,obj);
}
/* -------- 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) {
/* Initialization */
runtime = NewString(runtime_banner);
headers = NewString(header_banner);
wrappers = NewString(wrapper_banner);
init = NewString(init_banner);
Rules = NewHash();
RenameHash = NewHash();
if (config_top)
Swig_emit(config_top, clientdata);
Swig_emit(top, clientdata);
Swig_banner(stdout);
Dump(runtime,stdout);
Dump(headers,stdout);
Dump(wrappers,stdout);
Dump(init, stdout);
Delete(runtime);
Delete(headers);
Delete(wrappers);
Delete(init);
Delete(RenameHash);
}
static SwigRule rules[] = {
"includefile", emit_includefile,
"externfile", emit_externfile,
"importfile", emit_importfile,
"headerblock", emit_headerblock,
"wrapperblock", emit_wrapperblock,
"initblock", emit_initblock,
"runtimeblock", emit_runtimeblock,
"scope", emit_scope,
"function", emit_function,
"variable", emit_variable,
"constant", emit_constant,
"typedef", emit_typedef,
"class", emit_class,
"destructor", emit_destructor,
"enum", emit_enum,
"enumvalue", emit_enumvalue,
"classdecl", emit_classdecl,
"private", emit_private,
"protected", emit_protected,
"public", emit_public,
"addmethods", emit_addmethods,
"moduledirective", emit_moduledirective,
"renamedirective", emit_renamedirective,
"readonlydirective", emit_readonlydirective,
"readwritedirective", emit_readwritedirective,
"namedirective", emit_namedirective,
"newdirective", emit_newdirective,
"exceptiondirective", emit_exceptiondirective,
"pragmadirective", emit_pragmadirective,
"nativedirective", emit_nativedirective,
"typemap", emit_typemap,
"typemapcopy", emit_typemapcopy,
"applydirective", emit_applydirective,
"cleardirective", emit_cleardirective,
"map", emit_map,
NULL, NULL
{ "file", test_file},
{ "module", test_module},
{ "insert", test_insert},
{ "pragma", test_pragma},
{ "typemap", test_typemap},
{ "apply", test_apply},
{ "exception", test_exception},
{ "clear", test_clear},
{ "addmethods", test_addmethods},
{ "constant", test_constant},
{ "function", test_function},
{ "variable", test_variable},
{ "typedef", test_typedef},
{ "enum", test_enum},
{ "enumvalue", test_enumvalue},
{ "class", test_class},
{ "classdecl", test_classdecl},
{ "destructor", test_destructor},
{ "access", test_access},
{ "*", test_unknown},
{ 0 }
};
/* Initialize the module */
void test_init() {
DOHString *config;
DOHString *pconfig;
Swig_add_rules(rules);
/* Try to get the language specific configuration */
config = Swig_include("pyconf.swg");
if (!config) {
Printf(stderr,"*** Fatal error. Unable to find pyconf.swg\n");
exit(0);
}
/* Run the preprocessor on the configuration file and parse it */
Seek(config,0,SEEK_SET);
Setline(config,1);
pconfig = Preprocessor_parse(config);
Seek(pconfig,0,SEEK_SET);
config_top = LParse_parse(pconfig);
static
int test_init(int argc, char **argv) {
Printf(stdout,"test_init:\n");
return 0;
}
#endif
static
DOH *test_run(DOH *node) {
DOH *c;
Printf(stdout,"test_run:\n");
Swig_add_rules(rules);
c = Getattr(node,"child");
Swig_emit_all(c,0);
return 0;
}
void testmodule() {
Swig_register_module("test","swig:top", test_init, test_run);
}

View file

@ -6,9 +6,9 @@ srcdir = @srcdir@
VPATH = @srcdir@
SRCS = map.c wrapfunc.c naming.c tree.c stype.c scanner.c include.c getopt.c misc.c \
parms.c cwrap.c typemap.c
parms.c cwrap.c typemap.c module.c
OBJS = map.o wrapfunc.o naming.o tree.o stype.o scanner.o include.o getopt.o misc.o \
parms.o cwrap.o typemap.o
parms.o cwrap.o typemap.o module.o
prefix = @prefix@
exec_prefix = @exec_prefix@

View file

@ -60,6 +60,18 @@ Swig_mark_arg(int n) {
marked[n] = 1;
}
/* -----------------------------------------------------------------------------
* Swig_check_marked()
*
* Checks to see if argument has been picked up.
* ----------------------------------------------------------------------------- */
int
Swig_check_marked(int n) {
assert((n>=0) && (n < numargs));
return marked[n];
}
/* -----------------------------------------------------------------------------
* Swig_check_options()
*

View file

@ -21,6 +21,26 @@ static List *directories = 0; /* List of include directories */
static String *lastpath = 0; /* Last file that was included */
static int bytes_read = 0; /* Bytes read */
static String *swiglib = 0; /* Location of SWIG library */
/* -----------------------------------------------------------------------------
* Swig_swiglib_set()
* Swig_swiglib_get()
*
* Set the location of the SWIG library. This isn't really used, by the
* include mechanism, but rather as a query interface for language modules.
* ----------------------------------------------------------------------------- */
void
Swig_swiglib_set(const String_or_char *sl) {
swiglib = NewString(sl);
}
String *
Swig_swiglib_get() {
return swiglib;
}
/* -----------------------------------------------------------------------------
* Swig_add_directory()
*

166
Source/Swig/module.c Normal file
View file

@ -0,0 +1,166 @@
/* -----------------------------------------------------------------------------
* module.c
*
* This file implements the SWIG module system. Modules are simply
* pieces of code that manipulate tree objects. Each module is defined
* by 4 quantities:
*
* - Module name (used to select the module on the command line)
* - init function (called with the SWIG command line options).
* - start function (called to launch the module)
* - start tag (starting tag expected by the module)
*
* Currently modules must be statically linked with SWIG. However, it
* is anticipated that the module system may eventually support
* dynamic loading.
*
* 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"
static char cvsroot[] = "$Header$";
struct Module {
String *modname;
int (*initfunc)(int argc, char **argv);
DOH *(*startfunc)(DOH *);
String *starttag;
struct Module *next;
};
static Module *Modules = 0;
static Hash *LoadedModules = 0;
/* -----------------------------------------------------------------------------
* Swig_register_module()
*
* Register a new module with the system
* ----------------------------------------------------------------------------- */
void
Swig_register_module(const String_or_char *modname, const String_or_char *starttag,
int (*initfunc)(int argc, char **argv),
DOH *(*startfunc)(DOH *))
{
Module *m;
m = (Module *) malloc(sizeof(Module));
m->modname = NewString(modname);
m->starttag = NewString(starttag);
m->initfunc = initfunc;
m->startfunc = startfunc;
m->next = Modules;
Modules = m;
}
/* -----------------------------------------------------------------------------
* Swig_load_module()
*
* Load a module. Returns the module object.
* ----------------------------------------------------------------------------- */
Module *
Swig_load_module(const String_or_char *modname) {
Module *m;
m = Modules;
while (m) {
if (Cmp(m->modname, modname) == 0) {
/* Create a new entry in the loaded modules table */
List *ml;
if (!LoadedModules) LoadedModules = NewHash();
ml = Getattr(LoadedModules,m->starttag);
if (!ml) {
ml = NewList();
Setattr(LoadedModules,m->starttag,ml);
}
Append(ml,NewVoid(m,0));
return m;
}
m = m->next;
}
return 0;
}
/* -----------------------------------------------------------------------------
* Swig_init_module()
*
* Initialize a module
* ----------------------------------------------------------------------------- */
int Swig_init_module(Module *m, int argc, char **argv) {
return (*m->initfunc)(argc,argv);
}
/* -----------------------------------------------------------------------------
* Swig_start_module()
*
* Start a module
* ----------------------------------------------------------------------------- */
DOH *
Swig_start_module(Module *m, DOH *obj) {
return (*m->startfunc)(obj);
}
/* -----------------------------------------------------------------------------
* Swig_run_modules()
*
* Given a tree node. This function tries to run it through all of the loaded
* modules. This works by looking at the "tag" attribute of the node and
* searching for a loaded module that can handle that tag. If no module can be
* found, processing stops and an error is generated.
*
* If more than one module can work on a given tag, those modules will be
* executed one after the other. Caveat: if one of those modules outputs
* a different type of tree, processing immediately stops.
* ----------------------------------------------------------------------------- */
DOH *Swig_run_modules(DOH *node) {
String *tag;
List *ml;
DOH *newnode;
String *newtag;
int i;
tag = Getattr(node,"tag");
if (!tag) {
Printf(stderr,"Whoa. No tag attribute on node passed to Swig_module_run.\n");
exit(EXIT_FAILURE);
}
/* Get the set of modules that can respond to this node */
while (node) {
if (!LoadedModules) {
Printf(stderr,"No modules loaded.\n");
return 0;
}
ml = Getattr(LoadedModules,tag);
if ((!ml) || (Len(ml) == 0)) {
Printf(stderr,"No module for object '%s'\n", tag);
return 0;
}
newnode = 0;
newtag = 0;
for (i = 0; i < Len(ml); i++) {
Module *m;
m = (Module *) Data(Getitem(ml,i));
assert(m);
newnode = (*m->startfunc)(node);
if (!newnode) return 0; /* Done */
newtag = Getattr(newnode,"tag");
if (!newtag) {
Printf(stderr,"Fatal error. Module '%s' returns untagged object.\n", m->modname);
exit(EXIT_FAILURE);
}
if (Cmp(newtag,tag)) break; /* Tag is different. Oh well */
}
if (Cmp(newtag,tag) == 0) break; /* Hmmm. The tag is the same but we already did everything */
node = newnode;
tag = newtag;
}
return 0;
}

View file

@ -68,6 +68,8 @@ extern int Swig_insert_file(const String_or_char *name, File *outfile);
extern int Swig_bytes_read();
extern void Swig_register_filebyname(const String_or_char *name, File *outfile);
extern File *Swig_filebyname(const String_or_char *name);
extern void Swig_swiglib_set(const String_or_char *name);
extern String *Swig_swiglib_get();
#define OUTFILE(x) Swig_filebyname(x)
@ -77,6 +79,7 @@ extern File *Swig_filebyname(const String_or_char *name);
extern void Swig_init_args(int argc, char **argv);
extern void Swig_mark_arg(int n);
extern int Swig_check_marked(int n);
extern void Swig_check_options();
extern void Swig_arg_error();
@ -221,19 +224,39 @@ extern String *ParmList_protostr(ParmList *);
/* --- Parse tree support --- */
typedef struct {
char *name;
const char *name;
int (*action)(DOH *obj, void *clientdata);
} SwigRule;
extern void Swig_dump_tags(DOH *obj, DOH *root);
extern void Swig_add_rule(String_or_char *, int (*action)(DOH *, void *));
#define SWIG_OK 1
#define SWIG_NORULE 0
#define SWIG_ERROR -1
extern void Swig_add_rule(const String_or_char *, int (*action)(DOH *, void *));
extern void Swig_add_rules(SwigRule ruleset[]);
extern void Swig_clear_rules();
extern int Swig_tag_check(DOH *obj, String_or_char *tagname);
extern int Swig_emit(DOH *obj, void *clientdata);
extern void Swig_cut_node(DOH *obj);
extern int Swig_emit_all(DOH *obj, void *clientdata);
extern void Swig_set_callback(DOH *obj, void (*cb)(void *clientdata), void *clientdata);
extern void (*Swig_set_trace(DOH *obj, void (*cb)(DOH *, DOH *), DOH *arg))(DOH *, DOH *);
extern void Swig_remove_trace(DOH *obj);
extern void Swig_node_cut(DOH *obj);
extern void Swig_node_insert(DOH *node, DOH *newnode);
extern void Swig_node_temporary(DOH *node);
extern void Swig_node_ignore(DOH *node);
extern int Swig_count_nodes(DOH *node);
extern DOH *Swig_next(DOH *obj);
extern DOH *Swig_prev(DOH *obj);
/* Debugging of parse trees */
extern void Swig_debug_emit(int);
extern void Swig_dump_tags(DOH *obj, DOH *root);
extern void Swig_dump_tree(DOH *obj);
extern void Swig_dump_rules();
/* -- Wrapper function Object */
typedef struct {
@ -349,6 +372,18 @@ extern Wrapper *Swig_cvarget_wrapper(String_or_char *varname,
String_or_char *code);
/* --- Module loader and handler --- */
typedef struct Module Module;
extern void Swig_register_module(const String_or_char *modname, const String_or_char *starttag,
int (*initfunc)(int, char **),
DOH *(*startfunc)(DOH *));
extern Module *Swig_load_module(const String_or_char *modname);
extern int Swig_init_module(Module *m, int argc, char **argv);
extern DOH *Swig_start_module(Module *m, DOH *obj);
extern DOH *Swig_run_modules(DOH *node);
/* --- Legacy Typemap API (somewhat simplified) --- */
extern void Swig_typemap_init();
@ -385,6 +420,9 @@ extern void Swig_except_clear();
#define Getnext(x) Getattr(x,"next")
#define Setnext(x,n) Setattr(x,"next",n)
#define Getchild(x) Getattr(x,"child")
extern int Swig_main(int argc, char *argv[]);
#endif

View file

@ -14,7 +14,9 @@
static char cvsroot[] = "$Header$";
/* Hash table mapping tag names to handler functions */
static Hash *rules = 0;
static int debug_emit = 0;
/* -----------------------------------------------------------------------------
* Swig_next()
@ -31,6 +33,10 @@ DOH *Swig_prev(DOH *obj) {
return Getattr(obj,"prev");
}
void Swig_debug_emit(int n) {
debug_emit = n;
}
/* -----------------------------------------------------------------------------
* Swig_dump_tags()
*
@ -46,10 +52,10 @@ Swig_dump_tags(DOH *obj, DOH *root) {
else croot = root;
while (obj) {
Printf(stdout,"%s.%s\n", croot, Getattr(obj,"tag"));
Printf(stdout,"%s . %s\n", croot, Getattr(obj,"tag"));
cobj = Getattr(obj,"child");
if (cobj) {
newroot = NewStringf("%s.%s",croot,Getattr(obj,"tag"));
newroot = NewStringf("%s . %s",croot,Getattr(obj,"tag"));
Swig_dump_tags(cobj,newroot);
Delete(newroot);
}
@ -59,6 +65,72 @@ Swig_dump_tags(DOH *obj, DOH *root) {
Delete(croot);
}
/* -----------------------------------------------------------------------------
* Swig_dump_tree()
*
* Dump the tree structure of a parse tree to standard output
* ----------------------------------------------------------------------------- */
static int indent_level = 0;
static void print_indent(int l) {
int i;
for (i = 0; i < indent_level; i++) {
fputc(' ', stdout);
}
if (l) {
fputc('|', stdout);
fputc(' ', stdout);
}
}
void
Swig_dump_tree(DOH *obj) {
DOH *k;
DOH *cobj;
while (obj) {
print_indent(0);
Printf(stdout,"+++ %s ----------------------------------------\n", Getattr(obj,"tag"));
k = Firstkey(obj);
while (k) {
if ((Cmp(k,"tag") == 0) || (Cmp(k,"child") == 0) ||
(Cmp(k,"parent") == 0) || (Cmp(k,"next") == 0) ||
(Cmp(k,"prev") == 0)) {
/* Do nothing */
} else if (Cmp(k,"parms") == 0) {
print_indent(2);
Printf(stdout,"%-12s - %s\n", k, ParmList_protostr(Getattr(obj,k)));
} else {
DOH *o;
char *trunc = "";
print_indent(2);
o = Str(Getattr(obj,k));
if (Len(o) > 40) {
trunc = "...";
}
Printf(stdout,"%-12s - \"%(escape)-0.40s%s\"\n", k, o, trunc);
Delete(o);
}
k = Nextkey(obj);
}
cobj = Getattr(obj,"child");
if (cobj) {
indent_level += 6;
Printf(stdout,"\n");
Swig_dump_tree(cobj);
indent_level -= 6;
} else {
print_indent(1);
Printf(stdout,"\n");
}
obj = Swig_next(obj);
}
}
/* -----------------------------------------------------------------------------
* Swig_add_rule()
*
@ -66,13 +138,17 @@ Swig_dump_tags(DOH *obj, DOH *root) {
* ----------------------------------------------------------------------------- */
void
Swig_add_rule(String_or_char *name, int (*action)(DOH *node, void *clientdata))
Swig_add_rule(const String_or_char *name, int (*action)(DOH *node, void *clientdata))
{
if (!rules) rules = NewHash();
if (action)
Setattr(rules,name,NewVoid((void *) action,0));
else
Delattr(rules,name);
if (debug_emit) {
Printf(stderr,"Swig_add_rule : '%s' -> %x\n", name, action);
}
}
/* -----------------------------------------------------------------------------
@ -101,48 +177,234 @@ Swig_clear_rules()
{
if (rules) Delete(rules);
rules = NewHash();
if (debug_emit) {
Printf(stderr,"Swig_clear_rules :\n");
}
}
/* -----------------------------------------------------------------------------
* Swig_dump_rules()
*
* Print out debugging information for the rules
* ----------------------------------------------------------------------------- */
void
Swig_dump_rules() {
String *key;
Printf(stdout,"SWIG emit rules:::\n");
if (!rules) {
Printf(stdout," No rules defined.\n");
return;
}
key = Firstkey(rules);
while (key) {
Printf(stdout," '%-15s' -> %x\n", key, GetVoid(rules,key));
key = Nextkey(rules);
}
}
/* -----------------------------------------------------------------------------
* Swig_tag_check()
*
* Checks the tag name of an object taking into account namespace issues.
* For example, a check of "function" will match any object with a tag
* of the form "xxx:function" whereas a check of "c:function" will check
* for a more exact match. Returns 1 if a match is found, 0 otherwise
* ----------------------------------------------------------------------------- */
int
Swig_tag_check(DOH *obj, String_or_char *tagname) {
String *tag;
char *tc;
char *tnc;
tag = Getattr(obj,"tag");
assert(tag);
tc = Char(tag);
tnc = Char(tagname);
while (tnc) {
if (strcmp(tc,tnc) == 0) return 1;
tnc = strchr(tnc,':');
if (tnc) tnc++;
}
return 0;
}
/* -----------------------------------------------------------------------------
* Swig_set_callback()
*
* Sets a parser callback function for a node.
* ----------------------------------------------------------------------------- */
void
Swig_set_callback(DOH *obj, void (*cb)(void *clientdata), void *clientdata) {
SetVoid(obj,"-callback-",(void *)cb);
if (clientdata)
SetVoid(obj,"-callbackarg-", clientdata);
}
/* -----------------------------------------------------------------------------
* Swig_set_trace()
*
* Sets a tracing function on a parse tree node. Returns the old tracing
* function (if any).
* ----------------------------------------------------------------------------- */
void (*Swig_set_trace(DOH *obj, void (*cb)(DOH *, DOH *), DOH *arg))(DOH *, DOH *) {
void (*old)(DOH *,DOH *);
old = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-");
SetVoid(obj,"-trace-", (void *) cb);
if (arg)
Setattr(obj,"-tracearg-", arg);
return old;
}
/* -----------------------------------------------------------------------------
* Swig_remove_trace()
*
* Removes the tracing function from a parse tree node
* ----------------------------------------------------------------------------- */
void
Swig_remove_trace(DOH *obj) {
Delattr(obj,"-trace-");
Delattr(obj,"-tracearg-");
}
/* -----------------------------------------------------------------------------
* Swig_node_temporary()
*
* Sets a node as being temporary (deleted immediately after it is emitted)
* ----------------------------------------------------------------------------- */
void Swig_node_temporary(DOH *obj) {
SetInt(obj,"-temp-",1);
}
/* -----------------------------------------------------------------------------
* Swig_node_ignore()
*
* Causes a node to be ignored
* ----------------------------------------------------------------------------- */
void Swig_node_ignore(DOH *obj) {
SetInt(obj,"-ignore-",1);
}
/* -----------------------------------------------------------------------------
* int Swig_emit()
*
* Emit an action for a specific object
* This function calls the handler function (if any) for an object.
* ----------------------------------------------------------------------------- */
int
Swig_emit(DOH *obj, void *clientdata) {
DOH *tag;
DOH *actionobj;
char *tc;
int (*action)(DOH *obj, void *clientdata);
void (*callback)(void *clientdata);
void (*tracefunc)(DOH *obj, DOH *arg);
int ret;
assert(obj);
if (!rules) return -1;
while (obj) {
if (!rules) {
Printf(stderr,"No rules defined in Swig_emit()!\n");
return SWIG_ERROR;
}
if (obj) {
if (Getattr(obj,"-ignore-")) return SWIG_OK;
tag = Getattr(obj,"tag");
actionobj = Getattr(rules,tag);
assert(tag);
tc = Char(tag);
while(tc) {
actionobj = Getattr(rules,tc);
if (actionobj) {
if (debug_emit) {
Printf(stderr,"Swig_emit : Matched tag '%s' -> rule '%s'\n", tag, tc);
}
/* Check for user tracing -- traces occur before any handlers are called */
tracefunc = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-");
if (tracefunc) {
DOH *tobj = Getattr(obj,"-tracearg-");
(*tracefunc)(obj,tobj);
}
action = (int (*)(DOH *, void *)) Data(actionobj);
ret = (*action)(obj,clientdata);
/* Check for a parser callback */
callback = (void (*)(void *clientdata)) GetVoid(obj,"-callback-");
if (callback) {
void *cbarg;
cbarg = GetVoid(obj,"-callbackarg-");
(*callback)(cbarg);
Delattr(obj,"-callback-");
Delattr(obj,"-callbackarg-");
}
return ret;
} else {
tc = strchr(tc,':');
if (tc) tc++;
}
}
actionobj = Getattr(rules,"*");
if (actionobj) {
if (debug_emit) {
Printf(stderr,"Swig_emit : Matched tag '%s' -> rule '*'\n", tag);
}
/* Check for user tracing -- traces occur before any handlers are called */
tracefunc = (void (*)(DOH *, DOH *)) GetVoid(obj,"-trace-");
if (tracefunc) {
DOH *tobj = Getattr(obj,"-tracearg-");
(*tracefunc)(obj,tobj);
}
action = (int (*)(DOH *, void *)) Data(actionobj);
ret = (*action)(obj,clientdata);
if (ret < 0) return -1;
} else {
Printf(stderr,"warning: no action defined for '%s'\n", tag);
/* Check for a parser callback */
callback = (void (*)(void *clientdata)) GetVoid(obj,"-callback-");
if (callback) {
void *cbarg;
cbarg = GetVoid(obj,"-callbackarg-");
(*callback)(cbarg);
Delattr(obj,"-callback-");
Delattr(obj,"-callbackarg-");
}
return ret;
}
if (debug_emit) {
Printf(stderr,"Swig_emit : No rule defined for tag '%s'\n", tag);
}
obj = Swig_next(obj);
}
return 0;
return SWIG_NORULE;
}
/* -----------------------------------------------------------------------------
* Swig_cut_node(DOH *obj)
* Swig_emit_all()
*
* Emit all of the nodes at this level.
* ----------------------------------------------------------------------------- */
int
Swig_emit_all(DOH *obj, void *clientdata) {
int ret;
while (obj) {
ret = Swig_emit(obj,clientdata);
if (ret < 0) return ret;
obj = Swig_next(obj);
}
return SWIG_OK;
}
/* -----------------------------------------------------------------------------
* Swig_node_cut()
*
* 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) {
void Swig_node_cut(DOH *obj) {
DOH *parent;
DOH *next;
DOH *prev;
@ -156,7 +418,7 @@ void Swig_cut_node(DOH *obj) {
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 */
/* Well, this is a single child. Guess we'll just tell the parent that their child is gone */
Delattr(parent,"child");
return;
}
@ -184,8 +446,43 @@ void Swig_cut_node(DOH *obj) {
return;
}
/* -----------------------------------------------------------------------------
* Swig_node_insert()
*
* Inserts a node after a given node. The node to be inserted should be
* isolated (no parent, no siblings, etc...).
* ----------------------------------------------------------------------------- */
void
Swig_node_insert(DOH *node, DOH *newnode) {
DOH *next;
next = Getattr(node,"next");
if (next) {
Setattr(newnode,"next", next);
Setattr(next,"prev", newnode);
}
Setattr(node,"next",newnode);
Setattr(newnode,"prev", node);
Setattr(newnode,"parent", Getattr(node,"parent"));
}
/* -----------------------------------------------------------------------------
* Swig_count_nodes()
*
* Count number of nodes at this level
* ----------------------------------------------------------------------------- */
int Swig_count_nodes(DOH *node) {
int n = 0;
while (node) {
n++;
node = Getnext(node);
}
return n;
}