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:
parent
bfb5a34ae0
commit
2cc9dbe7fd
5 changed files with 294 additions and 14 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 -------- */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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 --- */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue