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);
|
$$ = new_node("map", $1.filename, $1.line);
|
||||||
Setattr($$,ATTR_NAME,$2.text);
|
Setattr($$,ATTR_NAME,$2.text);
|
||||||
Setattr($$,ATTR_PARMS,$4);
|
Setattr($$,ATTR_PARMS,$4);
|
||||||
if ($7) {
|
|
||||||
Setattr($$,ATTR_CHILD,$7);
|
/* Uh. Okay, this is a little nasty. We're going to take the
|
||||||
setparent($$,$7);
|
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);
|
Setattr(o2,ATTR_NEXT,$2);
|
||||||
}
|
}
|
||||||
| function_decl map_element {
|
| function_decl map_element {
|
||||||
DOH *o, *o2;
|
DOH *o, *o2;
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
o = $1;
|
o = $1;
|
||||||
|
|
@ -839,7 +872,7 @@ map_element : variable_decl map_element {
|
||||||
}
|
}
|
||||||
| STRING COLON LBRACE {
|
| STRING COLON LBRACE {
|
||||||
DOH *text = LParse_skip_balanced('{','}');
|
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($$,ATTR_NAME,$1.text);
|
||||||
Setattr($$,"code",text);
|
Setattr($$,"code",text);
|
||||||
$1.text = $$;
|
$1.text = $$;
|
||||||
|
|
@ -848,6 +881,16 @@ map_element : variable_decl map_element {
|
||||||
if ($5)
|
if ($5)
|
||||||
Setattr($$,ATTR_NEXT,$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 {
|
| empty {
|
||||||
$$ = 0;
|
$$ = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ emit_function(DOH *obj, void *clientdata) {
|
||||||
int nd;
|
int nd;
|
||||||
nd = SwigType_array_ndim(ptype);
|
nd = SwigType_array_ndim(ptype);
|
||||||
for (i = 0; i < nd; i++) {
|
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");
|
parms = Getattr(obj,"parms");
|
||||||
rules = Getattr(obj,"child");
|
rules = Getattr(obj,"child");
|
||||||
|
|
||||||
Swig_map_add(Rules,rulename,parms,rules);
|
Swig_map_add(Rules,rulename,parms,obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------- Entry point -------- */
|
/* -------- Entry point -------- */
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ Swig_map_add(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, DOH
|
||||||
DOHHash *nameset;
|
DOHHash *nameset;
|
||||||
DOHHash *p, *n;
|
DOHHash *p, *n;
|
||||||
/* Locate the appropriate nameset */
|
/* Locate the appropriate nameset */
|
||||||
|
|
||||||
nameset = Getattr(ruleset,rulename);
|
nameset = Getattr(ruleset,rulename);
|
||||||
if (!nameset) {
|
if (!nameset) {
|
||||||
/* Hmmm. First time we've seen this. Let's add it to our mapping table */
|
/* 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;
|
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()
|
* Swig_map_match()
|
||||||
*
|
*
|
||||||
|
|
@ -194,6 +393,7 @@ Swig_map_match(DOHHash *ruleset, DOHString_or_char *rulename, DOHHash *parms, in
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -424,12 +424,13 @@ DOHString *SwigType_prefix(DOHString *t) {
|
||||||
* Returns the number of dimensions of an array.
|
* 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;
|
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 = strchr(c,'.');
|
||||||
|
c++;
|
||||||
ndim++;
|
ndim++;
|
||||||
}
|
}
|
||||||
return ndim;
|
return ndim;
|
||||||
|
|
@ -441,17 +442,52 @@ int SwigType_array_ndim(DOHString_or_char *id) {
|
||||||
* Get the value of the nth dimension.
|
* 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);
|
char *c = Char(t);
|
||||||
while (c && SwigType_isarray(c) && (n > 0)) {
|
while (c && (strncmp(c,"a(",2) == 0) && (n > 0)) {
|
||||||
c = strchr(c,'.');
|
c = strchr(c,'.');
|
||||||
|
c++;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
if (n == 0) return SwigType_parm(c);
|
if (n == 0) return SwigType_parm(c);
|
||||||
return 0;
|
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)
|
* 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_cmp(DOHString_or_char *pat, DOHString_or_char *t);
|
||||||
extern int SwigType_array_ndim(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 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 --- */
|
/* --- Parse tree support --- */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue