A lot of work on the type system. Experimental language module.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@516 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
33c9ebbdc8
commit
765ad025b9
8 changed files with 609 additions and 96 deletions
|
|
@ -5,8 +5,8 @@
|
|||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
SRCS = naming.c tree.c stype.c scanner.c include.c getopt.c misc.c
|
||||
OBJS = naming.o tree.o stype.o scanner.o include.o getopt.o misc.o
|
||||
SRCS = map.c wrapfunc.c naming.c tree.c stype.c scanner.c include.c getopt.c misc.c
|
||||
OBJS = map.o wrapfunc.o naming.o tree.o stype.o scanner.o include.o getopt.o misc.o
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
|
|
|||
200
Source/Swig/map.c
Normal file
200
Source/Swig/map.c
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* map.c
|
||||
*
|
||||
* This file provides support for defining %map rules that match lists of
|
||||
* parameters to objects defining code generation rules.
|
||||
*
|
||||
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||
*
|
||||
* Copyright (C) 1999-2000. The University of Chicago
|
||||
* See the file LICENSE for information on usage and redistribution.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
#include "swig.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Synopsis
|
||||
*
|
||||
* One of the biggest problems in wrapper generation is that of defining
|
||||
* the handling of various datatypes and function parameters. This module
|
||||
* provides support for a generic object known as a 'mapping rule' that is
|
||||
* defined using the %map directive like this:
|
||||
*
|
||||
* %map rulename(typelist) {
|
||||
* vars;
|
||||
* rule1 { ... }
|
||||
* rule2 { ... }
|
||||
* rule3 { ... }
|
||||
* rule4 { ... }
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* A mapping rule is somewhat similar to a class or structure definition. The
|
||||
* "vars" field is a list of variable declarations that will be local to the
|
||||
* mapping rule when it is used. The "rulen" fields simply define code
|
||||
* fragments and other information that language specific modules can examine
|
||||
* for their own nefarious purposes.
|
||||
*
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_map_add()
|
||||
*
|
||||
* Adds a new mapping rule. The parms input to this function should be a
|
||||
* properly constructed parameter list with associated attributes. The rules
|
||||
* field can technically be any valid object.
|
||||
*
|
||||
* The structure of how data is stored is as follows:
|
||||
*
|
||||
* ruleset (hash)
|
||||
* --------------
|
||||
* rulename ------> nameset (hash)
|
||||
* --------------
|
||||
* parm1 ---------> rule (hash)
|
||||
* -------------
|
||||
* parm2 -----------> rule (hash)
|
||||
* *obj* --> obj
|
||||
*
|
||||
*
|
||||
* For multiple arguments, we end up building a large tree of hash tables.
|
||||
* The object will be stored in the *obj* attribute of the last hash table.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
Swig_map_add(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, DOH *obj)
|
||||
{
|
||||
|
||||
DOHHash *nameset;
|
||||
DOHHash *p, *n;
|
||||
/* Locate the appropriate nameset */
|
||||
|
||||
nameset = Getattr(ruleset,rulename);
|
||||
if (!nameset) {
|
||||
/* Hmmm. First time we've seen this. Let's add it to our mapping table */
|
||||
nameset = NewHash();
|
||||
Setattr(ruleset,rulename,nameset);
|
||||
}
|
||||
|
||||
/* Now, we walk down the parms list and create a series of hash tables */
|
||||
|
||||
p = parms;
|
||||
n = nameset;
|
||||
while (p) {
|
||||
DOHString *ty, *name, *key;
|
||||
DOHHash *nn;
|
||||
ty = Getattr(p,"type");
|
||||
name = Getattr(p,"name");
|
||||
|
||||
/* Create a hash table key */
|
||||
|
||||
key = NewStringf("%s-%s",name,ty);
|
||||
|
||||
/* See if there is already a entry with this type in the table */
|
||||
nn = Getattr(n,key);
|
||||
if (!nn) {
|
||||
/* No. Go ahead and create it */
|
||||
nn = NewHash();
|
||||
Setattr(n,key,nn);
|
||||
}
|
||||
Delete(key);
|
||||
n = nn;
|
||||
p = Swig_next(p);
|
||||
}
|
||||
|
||||
/* No more parameters. At this point, n points to the very last hash table in our search.
|
||||
We'll stick our object there */
|
||||
|
||||
Setattr(n,"*obj*",obj);
|
||||
return;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_map_match()
|
||||
*
|
||||
* Perform a longest map for a list of parameters and a set of mapping rules.
|
||||
* Returns the corresponding rule object and the number of parameters that
|
||||
* were matched.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Internal function used for recursively searching rulesets */
|
||||
static DOH *
|
||||
Swig_map_match_internal(DOHHash *nameset, DOHHash *parms, int *nmatch) {
|
||||
DOHHash *nn1, *nn2;
|
||||
DOHString *ty;
|
||||
DOHString *name;
|
||||
DOHString *key;
|
||||
int mlen1 = 0, mlen2 = 0, bestlen = 0;
|
||||
DOH *obj1 = 0, *obj2 = 0;
|
||||
DOH *bestobj, *bestn;
|
||||
DOHHash *nextp;
|
||||
|
||||
if (!parms) {
|
||||
bestobj = Getattr(nameset,"*obj*");
|
||||
if (bestobj) *nmatch++;
|
||||
return bestobj;
|
||||
}
|
||||
|
||||
ty = Getattr(parms,"type");
|
||||
name = Getattr(parms,"name");
|
||||
key = NewStringf("%s-%s",name,ty);
|
||||
|
||||
/* See if there is an exact name match */
|
||||
nn1 = Getattr(nameset,key);
|
||||
if (nn1) {
|
||||
mlen1++;
|
||||
obj1 = Swig_map_match_internal(nn1,Swig_next(parms), &mlen1);
|
||||
}
|
||||
|
||||
/* See if there is a generic name match */
|
||||
Clear(key);
|
||||
Printf(key,"-%s",ty);
|
||||
nn2 = Getattr(nameset,key);
|
||||
if (nn2) {
|
||||
mlen2++;
|
||||
obj2 = Swig_map_match_internal(nn2, Swig_next(parms), &mlen2);
|
||||
}
|
||||
/* Pick the best match. Note: an exact name match is preferred */
|
||||
if (obj1 && obj2) {
|
||||
if (mlen2 > mlen1) {
|
||||
bestlen = mlen2;
|
||||
bestobj = obj2;
|
||||
} else {
|
||||
bestlen = mlen1;
|
||||
bestobj = obj1;
|
||||
}
|
||||
} else if (obj1) {
|
||||
bestobj = obj1;
|
||||
bestlen = mlen1;
|
||||
} else if (obj2) {
|
||||
bestobj = obj2;
|
||||
bestlen = mlen2;
|
||||
}
|
||||
if (!bestobj) {
|
||||
bestobj = Getattr(nameset,"*obj*");
|
||||
if (bestobj) bestlen = 1;
|
||||
}
|
||||
Delete(key);
|
||||
*nmatch = *nmatch + bestlen;
|
||||
return bestobj;
|
||||
}
|
||||
|
||||
DOH *
|
||||
Swig_map_match(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, int *nmatch)
|
||||
{
|
||||
DOHHash *nameset;
|
||||
int mlen = 0;
|
||||
DOH *best;
|
||||
|
||||
/* Get the nameset */
|
||||
nameset = Getattr(ruleset,rulename);
|
||||
if (!nameset) return 0;
|
||||
|
||||
best = Swig_map_match_internal(nameset,parms,&mlen);
|
||||
*nmatch = mlen;
|
||||
return best;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -418,6 +418,40 @@ DOHString *SwigType_prefix(DOHString *t) {
|
|||
return NewString("");
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_array_ndim()
|
||||
*
|
||||
* Returns the number of dimensions of an array.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
int SwigType_array_ndim(DOHString_or_char *id) {
|
||||
int ndim = 0;
|
||||
char *c = Char(id);
|
||||
|
||||
while (c && SwigType_isarray(c)) {
|
||||
c = strchr(c,'.');
|
||||
ndim++;
|
||||
}
|
||||
return ndim;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_array_getdim()
|
||||
*
|
||||
* Get the value of the nth dimension.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
DOHString *SwigType_array_getdim(DOHString_or_char *id, int n) {
|
||||
|
||||
char *c = Char(id);
|
||||
while (c && SwigType_isarray(c) && (n > 0)) {
|
||||
c = strchr(c,'.');
|
||||
n--;
|
||||
}
|
||||
if (n == 0) return SwigType_parm(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* SwigType_cstr(DOH *s, DOH *id)
|
||||
*
|
||||
|
|
@ -705,25 +739,3 @@ int SwigType_cmp(DOHString_or_char *tpat, DOHString_or_char *type) {
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
int main() {
|
||||
DOHString *a,*b,*c,*d;
|
||||
|
||||
a = NewString("int");
|
||||
SwigType_add_pointer(a);
|
||||
|
||||
SwigType_typedef(a,"IntPtr");
|
||||
|
||||
b = NewString("IntPtr");
|
||||
SwigType_add_array(b,"1000");
|
||||
|
||||
Printf(stdout,"b = '%s'\n", b);
|
||||
c = SwigType_typedef_resolve(b);
|
||||
Printf(stdout,"c = '%s'\n", c);
|
||||
|
||||
Printf(stdout,"cmp = %d\n", SwigType_cmp("a(1000).p.p.int",b));
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ extern DOHHash *SwigType_pop_scope();
|
|||
extern DOHString *SwigType_typedef_resolve(DOHString_or_char *t);
|
||||
extern int SwigType_istypedef(DOHString_or_char *t);
|
||||
extern int SwigType_cmp(DOHString_or_char *pat, DOHString_or_char *t);
|
||||
extern int SwigType_array_ndim(DOHString_or_char *t);
|
||||
extern DOHString *SwigType_array_getdim(DOHString_or_char *t, int n);
|
||||
|
||||
/* --- Parse tree support --- */
|
||||
|
||||
|
|
@ -159,6 +161,9 @@ extern void Swig_add_rule(DOHString_or_char *, int (*action)(DOH *, void *));
|
|||
extern void Swig_add_rules(SwigRule ruleset[]);
|
||||
extern void Swig_clear_rules();
|
||||
extern int Swig_emit(DOH *obj, void *clientdata);
|
||||
extern void Swig_cut_node(DOH *obj);
|
||||
extern DOH *Swig_next(DOH *obj);
|
||||
extern DOH *Swig_prev(DOH *obj);
|
||||
|
||||
/* -- Wrapper function Object */
|
||||
|
||||
|
|
@ -186,6 +191,11 @@ extern char *Swig_name_set(DOHString_or_char *vname);
|
|||
extern char *Swig_name_construct(DOHString_or_char *classname);
|
||||
extern char *Swig_name_destroy(DOHString_or_char *classname);
|
||||
|
||||
/* --- Mapping interface --- */
|
||||
|
||||
extern void Swig_map_add(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, DOH *obj);
|
||||
extern DOH *Swig_map_match(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, int *nmatch);
|
||||
|
||||
/* --- Misc --- */
|
||||
extern char *Swig_copy_string(const char *c);
|
||||
extern void Swig_banner(DOHFile *f);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* tree.c
|
||||
*
|
||||
* This file provides some general purpose functions for walking through
|
||||
* This file provides some general purpose functions for manipulating
|
||||
* parse trees.
|
||||
*
|
||||
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
|
||||
|
|
@ -16,6 +16,21 @@ static char cvsroot[] = "$Header$";
|
|||
|
||||
static DOHHash *rules = 0;
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_next()
|
||||
* Swig_prev()
|
||||
*
|
||||
* Return next/prev node in a parse tree
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
DOH *Swig_next(DOH *obj) {
|
||||
return Getattr(obj,"next");
|
||||
}
|
||||
|
||||
DOH *Swig_prev(DOH *obj) {
|
||||
return Getattr(obj,"prev");
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_dump_tags()
|
||||
*
|
||||
|
|
@ -38,7 +53,7 @@ Swig_dump_tags(DOH *obj, DOH *root) {
|
|||
Swig_dump_tags(cobj,newroot);
|
||||
Delete(newroot);
|
||||
}
|
||||
obj = Getattr(obj,"sibling");
|
||||
obj = Swig_next(obj);
|
||||
}
|
||||
if (!root)
|
||||
Delete(croot);
|
||||
|
|
@ -115,10 +130,62 @@ Swig_emit(DOH *obj, void *clientdata) {
|
|||
} else {
|
||||
Printf(stderr,"warning: no action defined for '%s'\n", tag);
|
||||
}
|
||||
obj = Getattr(obj,"sibling");
|
||||
obj = Swig_next(obj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_cut_node(DOH *obj)
|
||||
*
|
||||
* This function cuts an object out of a parse tree. To do this, the object
|
||||
* MUST be properly initialized with "next", "prev", and "parent" attributes.
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
void Swig_cut_node(DOH *obj) {
|
||||
DOH *parent;
|
||||
DOH *next;
|
||||
DOH *prev;
|
||||
|
||||
parent = Getattr(obj,"parent");
|
||||
assert(parent);
|
||||
next = Getattr(obj,"next");
|
||||
prev = Getattr(obj,"prev");
|
||||
|
||||
DohIncref(obj); /* Make sure object doesn't go away */
|
||||
Delattr(obj,"parent"); /* Disassociate from my parent */
|
||||
|
||||
if (!next && !prev) {
|
||||
/* Well, this is a single child. Guess we'll just update the parent their child is gone */
|
||||
Delattr(parent,"child");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If no next node, then this must be at the end of a list */
|
||||
if (!next) {
|
||||
Delattr(prev,"next"); /* Break the 'next' link in the previous node */
|
||||
Delattr(obj,"prev"); /* Break my link back to the previous object */
|
||||
return;
|
||||
}
|
||||
|
||||
/* No previous node. This must be the beginning of a list */
|
||||
if (!prev) {
|
||||
Delattr(next,"prev"); /* Break the 'prev' link of the next node */
|
||||
Setattr(parent,"child",next); /* Update parent to point at next node */
|
||||
Delattr(obj,"next"); /* Break my link to the next object */
|
||||
return;
|
||||
}
|
||||
|
||||
/* In the middle of a list someplace */
|
||||
Setattr(prev,"next",next); /* Update previous node to my next node */
|
||||
Setattr(next,"prev",prev); /* Update next node to my previous node */
|
||||
Delattr(obj,"next");
|
||||
Delattr(obj,"prev");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue