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:
parent
6456c13435
commit
28127aa9be
12 changed files with 1007 additions and 845 deletions
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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 : ;
|
||||
|
||||
%%
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
37
Source/Modules/init.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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@
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
166
Source/Swig/module.c
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue