The great merge
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@4141 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
6fcc22a1f8
commit
516036631c
1508 changed files with 125983 additions and 44037 deletions
|
|
@ -11,40 +11,19 @@
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swig.h"
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
static char cvsroot[] = "$Header$";
|
||||
|
||||
/* Hash table mapping tag names to handler functions */
|
||||
static Hash *rules = 0;
|
||||
static int debug_emit = 0;
|
||||
char cvsroot_tree_c[] = "$Header$";
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_next()
|
||||
* Swig_prev()
|
||||
*
|
||||
* Return next/prev node in a parse tree
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
DOH *Swig_next(DOH *obj) {
|
||||
return Getnext(obj);
|
||||
}
|
||||
|
||||
DOH *Swig_prev(DOH *obj) {
|
||||
return Getprev(obj);
|
||||
}
|
||||
|
||||
void Swig_debug_emit(int n) {
|
||||
debug_emit = n;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_dump_tags()
|
||||
* Swig_print_tags()
|
||||
*
|
||||
* Dump the tag structure of a parse tree to standard output
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
Swig_dump_tags(DOH *obj, DOH *root) {
|
||||
Swig_print_tags(DOH *obj, DOH *root) {
|
||||
DOH *croot, *newroot;
|
||||
DOH *cobj;
|
||||
|
||||
|
|
@ -52,22 +31,21 @@ Swig_dump_tags(DOH *obj, DOH *root) {
|
|||
else croot = root;
|
||||
|
||||
while (obj) {
|
||||
Printf(stdout,"%s . %s (%s:%d)\n", croot, Getattr(obj,"tag"), Getfile(obj), Getline(obj));
|
||||
cobj = Getattr(obj,"child");
|
||||
Printf(stdout,"%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj));
|
||||
cobj = firstChild(obj);
|
||||
if (cobj) {
|
||||
newroot = NewStringf("%s . %s",croot,Getattr(obj,"tag"));
|
||||
Swig_dump_tags(cobj,newroot);
|
||||
newroot = NewStringf("%s . %s",croot,nodeType(obj));
|
||||
Swig_print_tags(cobj,newroot);
|
||||
Delete(newroot);
|
||||
}
|
||||
obj = Swig_next(obj);
|
||||
obj = nextSibling(obj);
|
||||
}
|
||||
if (!root)
|
||||
Delete(croot);
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_dump_tree()
|
||||
* Swig_print_tree()
|
||||
*
|
||||
* Dump the tree structure of a parse tree to standard output
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -85,429 +63,339 @@ static void print_indent(int l) {
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_dump_node(Node *n)
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
Swig_print_node(Node *obj) {
|
||||
String *k;
|
||||
Node *cobj;
|
||||
|
||||
print_indent(0);
|
||||
Printf(stdout,"+++ %s ----------------------------------------\n", nodeType(obj));
|
||||
k = Firstkey(obj);
|
||||
while (k) {
|
||||
if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) ||
|
||||
(Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) ||
|
||||
(Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) {
|
||||
/* 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);
|
||||
if (DohIsString(Getattr(obj,k))) {
|
||||
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()
|
||||
*
|
||||
* Adds a new rule to the tree walking code.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_add_rules()
|
||||
*
|
||||
* Add a complete set of rules to the rule system
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
Swig_add_rules(SwigRule ruleset[]) {
|
||||
int i = 0;
|
||||
while (ruleset[i].name) {
|
||||
Swig_add_rule(ruleset[i].name, ruleset[i].action);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_clear_rules()
|
||||
*
|
||||
* Clears all of the existing rules
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
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, const String_or_char *tagname) {
|
||||
String *tag;
|
||||
char *tc;
|
||||
char *tnc;
|
||||
tag = Getattr(obj,"tag");
|
||||
assert(tag);
|
||||
|
||||
tnc = Char(tag);
|
||||
tc = 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()
|
||||
*
|
||||
* 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) {
|
||||
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");
|
||||
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++;
|
||||
Printf(stdout,"%-12s - 0x%x\n", k, Getattr(obj,k));
|
||||
}
|
||||
}
|
||||
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);
|
||||
/* 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);
|
||||
}
|
||||
k = Nextkey(obj);
|
||||
}
|
||||
cobj = firstChild(obj);
|
||||
if (cobj) {
|
||||
indent_level += 6;
|
||||
Printf(stdout,"\n");
|
||||
Swig_print_tree(cobj);
|
||||
indent_level -= 6;
|
||||
} else {
|
||||
print_indent(1);
|
||||
Printf(stdout,"\n");
|
||||
}
|
||||
return SWIG_NORULE;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_emit_all()
|
||||
*
|
||||
* Emit all of the nodes at this level.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
Swig_emit_all(DOH *obj, void *clientdata) {
|
||||
int ret;
|
||||
void
|
||||
Swig_print_tree(DOH *obj) {
|
||||
while (obj) {
|
||||
ret = Swig_emit(obj,clientdata);
|
||||
if (ret < 0) return ret;
|
||||
obj = Swig_next(obj);
|
||||
Swig_print_node(obj);
|
||||
obj = nextSibling(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_node_cut(DOH *obj) {
|
||||
DOH *parent;
|
||||
DOH *next;
|
||||
DOH *prev;
|
||||
|
||||
parent = Getattr(obj,"parent");
|
||||
assert(parent);
|
||||
next = Getattr(obj,"next");
|
||||
prev = Getattr(obj,"prev");
|
||||
|
||||
DohIncref(obj); /* Make sure object doesn't go away */
|
||||
Delattr(obj,"parent"); /* Disassociate from my parent */
|
||||
|
||||
if (!next && !prev) {
|
||||
/* Well, this is a single child. Guess we'll just tell the parent that their child is gone */
|
||||
Delattr(parent,"child");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no next node, then this must be at the end of a list */
|
||||
if (!next) {
|
||||
Delattr(prev,"next"); /* Break the 'next' link in the previous node */
|
||||
Delattr(obj,"prev"); /* Break my link back to the previous object */
|
||||
return;
|
||||
}
|
||||
|
||||
/* No previous node. This must be the beginning of a list */
|
||||
if (!prev) {
|
||||
Delattr(next,"prev"); /* Break the 'prev' link of the next node */
|
||||
Setattr(parent,"child",next); /* Update parent to point at next node */
|
||||
Delattr(obj,"next"); /* Break my link to the next object */
|
||||
return;
|
||||
}
|
||||
|
||||
/* In the middle of a list someplace */
|
||||
Setattr(prev,"next",next); /* Update previous node to my next node */
|
||||
Setattr(next,"prev",prev); /* Update next node to my previous node */
|
||||
Delattr(obj,"next");
|
||||
Delattr(obj,"prev");
|
||||
return;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* 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_node_append_child()
|
||||
* appendChild()
|
||||
*
|
||||
* Appends a new child to a node
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
Swig_node_append_child(DOH *node, DOH *chd) {
|
||||
DOH *c;
|
||||
DOH *pc;
|
||||
c = Getattr(node,"child");
|
||||
if (!c) {
|
||||
Setattr(node,"child",chd);
|
||||
Setattr(chd,"parent",node);
|
||||
return;
|
||||
appendChild(Node *node, Node *chd) {
|
||||
Node *lc;
|
||||
|
||||
if (!chd) return;
|
||||
|
||||
lc = lastChild(node);
|
||||
if (!lc) {
|
||||
set_firstChild(node,chd);
|
||||
} else {
|
||||
set_nextSibling(lc,chd);
|
||||
set_previousSibling(chd,lc);
|
||||
}
|
||||
while (c) {
|
||||
pc = c;
|
||||
c = Getnext(c);
|
||||
while (chd) {
|
||||
lc = chd;
|
||||
set_parentNode(chd,node);
|
||||
chd = nextSibling(chd);
|
||||
}
|
||||
Setattr(pc,"next",chd);
|
||||
Setattr(chd,"prev",pc);
|
||||
Setattr(chd,"parent",node);
|
||||
set_lastChild(node,lc);
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_count_nodes()
|
||||
* deleteNode()
|
||||
*
|
||||
* Count number of nodes at this level
|
||||
* Deletes a node.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int Swig_count_nodes(DOH *node) {
|
||||
int n = 0;
|
||||
while (node) {
|
||||
n++;
|
||||
node = Getnext(node);
|
||||
void
|
||||
deleteNode(Node *n) {
|
||||
Node *parent;
|
||||
Node *prev;
|
||||
Node *next;
|
||||
|
||||
parent = parentNode(n);
|
||||
prev = previousSibling(n);
|
||||
next = nextSibling(n);
|
||||
if (prev) {
|
||||
set_nextSibling(prev,next);
|
||||
} else {
|
||||
if (parent) {
|
||||
set_firstChild(parent,next);
|
||||
}
|
||||
}
|
||||
if (next) {
|
||||
set_previousSibling(next,prev);
|
||||
} else {
|
||||
if (parent) {
|
||||
set_lastChild(parent,prev);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* copyNode()
|
||||
*
|
||||
* Copies a node, but only copies simple attributes (no lists, hashes).
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
Node *
|
||||
copyNode(Node *n) {
|
||||
String *key;
|
||||
DOH *v;
|
||||
Node *c = NewHash();
|
||||
for (key = Firstkey(n); key; key = Nextkey(n)) {
|
||||
v = Getattr(n,key);
|
||||
if (DohIsString(v)) {
|
||||
Setattr(c,key,Copy(v));
|
||||
}
|
||||
}
|
||||
Setfile(c,Getfile(n));
|
||||
Setline(c,Getline(n));
|
||||
return c;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_tag_nodes()
|
||||
*
|
||||
* Tags a collection of nodes with an attribute. Used by the parser to mark
|
||||
* subtypes with extra information.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
Swig_tag_nodes(Node *n, const String_or_char *attrname, DOH *value) {
|
||||
while (n) {
|
||||
Setattr(n,attrname,value);
|
||||
Swig_tag_nodes(firstChild(n),attrname, value);
|
||||
n = nextSibling(n);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
checkAttribute(Node *n, const String_or_char *name, const String_or_char *value) {
|
||||
String *v;
|
||||
v = Getattr(n,name);
|
||||
if (!v) return 0;
|
||||
if (Cmp(v,value) == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_require()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#define MAX_SWIG_STACK 256
|
||||
static Hash *attr_stack[MAX_SWIG_STACK];
|
||||
static Node **nodeptr_stack[MAX_SWIG_STACK];
|
||||
static Node *node_stack[MAX_SWIG_STACK];
|
||||
static int stackp = 0;
|
||||
static int stack_direction = 0;
|
||||
|
||||
static void set_direction(int n, int *x) {
|
||||
if (n == 1) {
|
||||
set_direction(0,&n);
|
||||
} else {
|
||||
if (&n < x) {
|
||||
stack_direction = -1; /* Stack grows down */
|
||||
} else {
|
||||
stack_direction = 1; /* Stack grows up */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
Swig_require(Node **nptr, ...) {
|
||||
va_list ap;
|
||||
char *name;
|
||||
DOH *obj;
|
||||
DOH *frame = 0;
|
||||
Node *n = *nptr;
|
||||
va_start(ap, nptr);
|
||||
name = va_arg(ap, char *);
|
||||
while (name) {
|
||||
int newref = 0;
|
||||
int opt = 0;
|
||||
if (*name == '*') {
|
||||
newref = 1;
|
||||
name++;
|
||||
} else if (*name == '?') {
|
||||
newref = 1;
|
||||
opt = 1;
|
||||
name++;
|
||||
}
|
||||
obj = Getattr(n,name);
|
||||
if (!opt && !obj) {
|
||||
Printf(stderr,"%s:%d. Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n",
|
||||
Getfile(n), Getline(n), name, nodeType(n));
|
||||
assert(obj);
|
||||
}
|
||||
if (!obj) obj = DohNone;
|
||||
if (newref) {
|
||||
if (!attr_stack[stackp]) {
|
||||
attr_stack[stackp]= NewHash();
|
||||
}
|
||||
frame = attr_stack[stackp];
|
||||
if (Setattr(frame,name,obj)) {
|
||||
Printf(stderr,"Swig_require('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name);
|
||||
}
|
||||
}
|
||||
name = va_arg(ap, char *);
|
||||
}
|
||||
va_end(ap);
|
||||
if (frame) {
|
||||
/* This is a sanity check to make sure no one is saving data, but not restoring it */
|
||||
if (stackp > 0) {
|
||||
int e = 0;
|
||||
if (!stack_direction) set_direction(1,0);
|
||||
|
||||
if (stack_direction < 0) {
|
||||
if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
|
||||
} else {
|
||||
if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
|
||||
}
|
||||
if (e) {
|
||||
Printf(stderr,
|
||||
"Swig_require('%s'): Fatal memory management error. If you are seeing this\n\
|
||||
message. It means that the target language module is not managing its memory\n\
|
||||
correctly. A handler for '%s' probably forgot to call Swig_restore().\n\
|
||||
Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
nodeptr_stack[stackp] = nptr;
|
||||
node_stack[stackp] = n;
|
||||
stackp++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Swig_save(Node **nptr, ...) {
|
||||
va_list ap;
|
||||
char *name;
|
||||
DOH *obj;
|
||||
DOH *frame;
|
||||
Node *n = *nptr;
|
||||
|
||||
if ((stackp > 0) && (nodeptr_stack[stackp-1] == nptr)) {
|
||||
frame = attr_stack[stackp-1];
|
||||
} else {
|
||||
if (stackp > 0) {
|
||||
int e = 0;
|
||||
if (!stack_direction) set_direction(1,0);
|
||||
if (stack_direction < 0) {
|
||||
if ((((char *) nptr) >= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
|
||||
} else {
|
||||
if ((((char *) nptr) <= ((char *) nodeptr_stack[stackp-1])) && (n != node_stack[stackp-1])) e = 1;
|
||||
}
|
||||
if (e) {
|
||||
Printf(stderr,
|
||||
"Swig_save('%s'): Fatal memory management error. If you are seeing this\n\
|
||||
message. It means that the target language module is not managing its memory\n\
|
||||
correctly. A handler for '%s' probably forgot to call Swig_restore().\n\
|
||||
Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
attr_stack[stackp] = NewHash();
|
||||
nodeptr_stack[stackp] = nptr;
|
||||
node_stack[stackp] = n;
|
||||
frame = attr_stack[stackp];
|
||||
stackp++;
|
||||
}
|
||||
va_start(ap, nptr);
|
||||
name = va_arg(ap, char *);
|
||||
while (name) {
|
||||
if (*name == '*') {
|
||||
name++;
|
||||
} else if (*name == '?') {
|
||||
name++;
|
||||
}
|
||||
obj = Getattr(n,name);
|
||||
if (!obj) {
|
||||
obj = DohNone;
|
||||
}
|
||||
if (Setattr(frame,name,obj)) {
|
||||
Printf(stderr,"Swig_save('%s'): Warning, attribute '%s' was already saved.\n", nodeType(n), name);
|
||||
}
|
||||
name = va_arg(ap, char *);
|
||||
}
|
||||
va_end(ap);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
Swig_restore(Node **nptr) {
|
||||
String *key;
|
||||
Hash *frame;
|
||||
Node *n = *nptr;
|
||||
assert(stackp > 0);
|
||||
if (!(nptr==nodeptr_stack[stackp-1])) {
|
||||
Printf(stderr,
|
||||
"Swig_restore('%s'): Fatal memory management error. If you are seeing this\n\
|
||||
message. It means that the target language module is not managing its memory\n\
|
||||
correctly. A handler for '%s' probably forgot to call Swig_restore().\n\
|
||||
Please report this problem to swig-dev@cs.uchicago.edu.\n", nodeType(n), nodeType(node_stack[stackp-1]));
|
||||
assert(0);
|
||||
}
|
||||
stackp--;
|
||||
frame = attr_stack[stackp];
|
||||
nodeptr_stack[stackp] = 0;
|
||||
node_stack[stackp] = 0;
|
||||
for (key = Firstkey(frame); key; key = Nextkey(frame)) {
|
||||
DOH *obj = Getattr(frame,key);
|
||||
if (obj != DohNone) {
|
||||
Setattr(n,key,obj);
|
||||
} else {
|
||||
Delattr(n,key);
|
||||
}
|
||||
Delattr(frame,key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue