Substantial changes for new module system.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@908 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
44f72308da
commit
5c39b4bc22
12 changed files with 1007 additions and 845 deletions
|
|
@ -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
SWIG/Source/Swig/module.c
Normal file
166
SWIG/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