More improvements to types and related code

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@521 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2000-07-06 04:20:33 +00:00
commit 2cc9dbe7fd
5 changed files with 294 additions and 14 deletions

View file

@ -810,9 +810,42 @@ 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);
if ($7) {
Setattr($$,ATTR_CHILD,$7);
setparent($$,$7);
/* 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);
}
}
}
;
@ -827,7 +860,7 @@ map_element : variable_decl map_element {
}
Setattr(o2,ATTR_NEXT,$2);
}
| function_decl map_element {
| function_decl map_element {
DOH *o, *o2;
$$ = $1;
o = $1;
@ -839,7 +872,7 @@ map_element : variable_decl map_element {
}
| STRING COLON LBRACE {
DOH *text = LParse_skip_balanced('{','}');
$$ = new_node("mapelement",$1.filename, $1.line);
$$ = new_node("maprule",$1.filename, $1.line);
Setattr($$,ATTR_NAME,$1.text);
Setattr($$,"code",text);
$1.text = $$;
@ -848,6 +881,16 @@ map_element : variable_decl map_element {
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;
}

View file

@ -174,7 +174,7 @@ emit_function(DOH *obj, void *clientdata) {
int nd;
nd = SwigType_array_ndim(ptype);
for (i = 0; i < nd; i++) {
Printf(stdout,"array[%d] = %s\n", i, SwigType_array_getdim(ptype,i));
Printf(stdout,"array[%d] = %S\n", i, SwigType_array_getdim(ptype,i));
}
}
@ -417,7 +417,7 @@ emit_map(DOH *obj, void *clientdata) {
parms = Getattr(obj,"parms");
rules = Getattr(obj,"child");
Swig_map_add(Rules,rulename,parms,rules);
Swig_map_add(Rules,rulename,parms,obj);
}
/* -------- Entry point -------- */

View file

@ -67,7 +67,7 @@ Swig_map_add(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, DOH
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 */
@ -108,6 +108,205 @@ Swig_map_add(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, DOH
return;
}
typedef struct MatchObject {
DOH *ruleset; /* Hash table of rules */
DOHHash *p; /* Parameter on which checking starts */
int depth; /* Depth of the match */
struct MatchObject *next; /* Next match object */
} MatchObject;
static MatchObject *matchstack = 0;
/* -----------------------------------------------------------------------------
* Swig_map_match()
*
* Perform a longest map match for a list of parameters and a set of mapping rules.
* Returns the corresponding rule object and the number of parameters that were
* matched.
* ----------------------------------------------------------------------------- */
DOH *
Swig_map_match(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, int *nmatch)
{
DOHHash *nameset;
MatchObject *mo;
DOH *bestobj = 0;
int bestdepth = -1;
/* Get the nameset */
nameset = Getattr(ruleset,rulename);
if (!nameset) return 0;
mo = (MatchObject *) malloc(sizeof(MatchObject));
mo->ruleset = nameset;
mo->depth = 0;
mo->p = parms;
mo->next = 0;
matchstack = mo;
/* Loop over all candidates until we find the best one */
while (matchstack) {
DOHHash *rs;
DOHHash *p;
int depth = 0;
DOH *obj;
DOHString *key;
DOHString *ty;
DOHString *name;
DOHString *nm;
int matched = 0;
mo = matchstack;
/* See if there is a match at this level */
rs = mo->ruleset;
obj = Getattr(rs,"*obj*");
if (obj) {
if (mo->depth > bestdepth) {
bestdepth = mo->depth;
bestobj = obj;
}
}
p = mo->p;
/* No more parameters. Oh well */
if (!p) {
matchstack = mo->next;
free(mo);
continue;
}
/* Generate some keys for checking the next parameter */
depth = mo->depth;
name = Getattr(p,"name");
ty = Getattr(p,"type");
if (!SwigType_isarray(ty)) {
key = NewStringf("-%s",ty);
/* See if there is a generic name match for this type */
nm = Getattr(rs,key);
if (nm) {
/* Yes! Add to our stack. Just reuse mo for this */
mo->ruleset = nm;
mo->p = Swig_next(p);
mo->depth++;
mo = 0;
matched++;
}
/* See if there is a specific name match for this type */
Clear(key);
Printf(key,"%s-%s",name,ty);
nm = Getattr(rs,key);
if (nm) {
if (!mo) {
mo = (MatchObject *) malloc(sizeof(MatchObject));
mo->next = matchstack;
matchstack = mo;
}
mo->ruleset = nm;
mo->p = Swig_next(p);
mo->depth = depth+1;
matched++;
}
Delete(key);
} else {
/* The next parameter is an array. This is pretty nasty because we have to do a bunch of checks
related to array indices */
int ndim;
int i, j, k, n;
int ncheck;
DOHString *ntype;
key = NewString("");
/* Drop the mo record. This is too complicated */
matchstack = mo->next;
free(mo);
mo = 0;
/* Get the number of array dimensions */
ndim = SwigType_array_ndim(ty);
/* First, we test all of the generic-unnamed parameters */
ncheck = 1 << ndim;
j = ncheck-1;
for (i = 0; i < ncheck; i++, j--) {
int k = j;
ntype = Copy(ty);
for (n = 0; n < ndim; n++, k = k >> 1) {
if (k & 1) {
SwigType_array_setdim(ntype,n,"");
}
}
Clear(key);
Printf(key,"-%s",ntype);
Printf(stdout,"matcharray : %s\n", key);
nm = Getattr(rs,key);
if (nm) {
mo = (MatchObject *) malloc(sizeof(MatchObject));
mo->ruleset = nm;
mo->p = Swig_next(p);
mo->depth = depth+1;
mo->next = matchstack;
matchstack = mo;
matched++;
mo = 0;
}
Delete(ntype);
}
/* Next check all of the named parameters */
ncheck = 1 << ndim;
j = ncheck-1;
for (i = 0; i < ncheck; i++, j--) {
int k = j;
ntype = Copy(ty);
for (n = 0; n < ndim; n++, k = k >> 1) {
if (k & 1) {
SwigType_array_setdim(ntype,n,"");
}
}
Clear(key);
Printf(key,"%s-%s",name,ntype);
Printf(stdout,"matcharray : %s\n", key);
nm = Getattr(rs,key);
if (nm) {
mo = (MatchObject *) malloc(sizeof(MatchObject));
mo->ruleset = nm;
mo->p = Swig_next(p);
mo->depth = depth+1;
mo->next = matchstack;
matchstack = mo;
matched++;
mo = 0;
}
Delete(ntype);
}
Delete(key);
}
if ((!matched) && mo) {
matchstack = mo->next;
free(mo);
}
}
if (bestobj) {
*nmatch = bestdepth;
}
return bestobj;
}
#ifdef OLD
/* -----------------------------------------------------------------------------
* Swig_map_match()
*
@ -194,6 +393,7 @@ Swig_map_match(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, in
return best;
}
#endif

View file

@ -424,12 +424,13 @@ DOHString *SwigType_prefix(DOHString *t) {
* Returns the number of dimensions of an array.
* ----------------------------------------------------------------------------- */
int SwigType_array_ndim(DOHString_or_char *id) {
int SwigType_array_ndim(DOHString_or_char *t) {
int ndim = 0;
char *c = Char(id);
char *c = Char(t);
while (c && SwigType_isarray(c)) {
while (c && (strncmp(c,"a(",2) == 0)) {
c = strchr(c,'.');
c++;
ndim++;
}
return ndim;
@ -441,17 +442,52 @@ int SwigType_array_ndim(DOHString_or_char *id) {
* Get the value of the nth dimension.
* ----------------------------------------------------------------------------- */
DOHString *SwigType_array_getdim(DOHString_or_char *id, int n) {
DOHString *SwigType_array_getdim(DOHString_or_char *t, int n) {
char *c = Char(id);
while (c && SwigType_isarray(c) && (n > 0)) {
char *c = Char(t);
while (c && (strncmp(c,"a(",2) == 0) && (n > 0)) {
c = strchr(c,'.');
c++;
n--;
}
if (n == 0) return SwigType_parm(c);
return 0;
}
/* -----------------------------------------------------------------------------
* SwigType_array_setdim()
*
* Replace the nth dimension of an array to a new value.
* ----------------------------------------------------------------------------- */
void SwigType_array_setdim(DOHString_or_char *t, int n, DOHString_or_char *rep) {
DOHString *result = 0;
char temp;
char *start;
char *c = Char(t);
start = c;
if (strncmp(c,"a(",2)) abort;
while (c && (strncmp(c,"a(",2) == 0) && (n > 0)) {
c = strchr(c,'.');
c++;
n--;
}
if (n == 0) {
temp = *c;
*c = 0;
result = NewString(start);
Printf(result,"a(%s)",rep);
*c = temp;
c = strchr(c,'.');
Append(result,c);
}
Clear(t);
Append(t,result);
Delete(result);
}
/* -----------------------------------------------------------------------------
* SwigType_cstr(DOH *s, DOH *id)
*

View file

@ -148,6 +148,7 @@ 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);
extern void SwigType_array_setdim(DOHString_or_char *t, int n, DOHString_or_char *rep);
/* --- Parse tree support --- */