Work on embedded typemaps. Highly experimental--probably broken
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5007 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
b2a9b214a8
commit
9040f3a579
2 changed files with 240 additions and 6 deletions
|
|
@ -847,7 +847,7 @@ Node *Swig_cparse(File *f) {
|
|||
%token <ivalue> TEMPLATE
|
||||
%token <str> OPERATOR
|
||||
%token <str> COPERATOR
|
||||
%token PARSETYPE
|
||||
%token PARSETYPE PARSEPARM
|
||||
|
||||
%left CAST
|
||||
%left LOR
|
||||
|
|
@ -940,6 +940,12 @@ program : interface {
|
|||
| PARSETYPE error {
|
||||
top = 0;
|
||||
}
|
||||
| PARSEPARM parm SEMI {
|
||||
top = $2;
|
||||
}
|
||||
| PARSEPARM error {
|
||||
top = 0;
|
||||
}
|
||||
;
|
||||
|
||||
interface : interface declaration {
|
||||
|
|
@ -4716,6 +4722,22 @@ SwigType *Swig_cparse_type(String *s) {
|
|||
}
|
||||
|
||||
|
||||
Parm *Swig_cparse_parm(String *s) {
|
||||
String *ns;
|
||||
extern void scanner_file(File *);
|
||||
extern int yyparse();
|
||||
extern void scanner_next_token(int);
|
||||
ns = NewStringf("%s;",s);
|
||||
Seek(ns,0,SEEK_SET);
|
||||
scanner_file(ns);
|
||||
top = 0;
|
||||
scanner_next_token(PARSEPARM);
|
||||
yyparse();
|
||||
/* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
|
||||
return top;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
char cvsroot_typemap_c[] = "$Header$";
|
||||
|
||||
#include "swig.h"
|
||||
#include <ctype.h>
|
||||
|
||||
void replace_embedded_typemap(String *s, Wrapper *f);
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Typemaps are stored in a collection of nested hash tables. Something like
|
||||
|
|
@ -38,6 +41,7 @@ char cvsroot_typemap_c[] = "$Header$";
|
|||
|
||||
#define MAX_SCOPE 32
|
||||
|
||||
|
||||
static Hash *typemaps[MAX_SCOPE];
|
||||
static int tm_scope = 0;
|
||||
|
||||
|
|
@ -704,6 +708,8 @@ void typemap_replace_vars(String *s, ParmList *locals, SwigType *type, String *p
|
|||
char *varname;
|
||||
SwigType *ftype;
|
||||
|
||||
Replaceall(s,"$typemap","$TYPEMAP");
|
||||
|
||||
ftype = SwigType_typedef_resolve_all(type);
|
||||
|
||||
if (!pname) pname = lname;
|
||||
|
|
@ -1064,16 +1070,22 @@ String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_
|
|||
if (locals && f) {
|
||||
typemap_locals(s,locals,f,-1);
|
||||
}
|
||||
|
||||
|
||||
replace_embedded_typemap(s,f);
|
||||
|
||||
/* Now perform character replacements */
|
||||
Replace(s,"$source",source,DOH_REPLACE_ANY);
|
||||
Replace(s,"$target",target,DOH_REPLACE_ANY);
|
||||
{
|
||||
|
||||
/* {
|
||||
String *tmname = Getattr(tm,"typemap");
|
||||
if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY);
|
||||
}
|
||||
*/
|
||||
|
||||
Replace(s,"$parmname",pname, DOH_REPLACE_ANY);
|
||||
/* Replace(s,"$name",pname,DOH_REPLACE_ANY); */
|
||||
|
||||
Delete(locals);
|
||||
Delete(mtype);
|
||||
return s;
|
||||
|
|
@ -1127,18 +1139,22 @@ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const Stri
|
|||
clname = SwigType_namestr((char *)lname);
|
||||
lname = clname;
|
||||
}
|
||||
|
||||
if (mtype && SwigType_isarray(mtype)) {
|
||||
typemap_replace_vars(s,locals,mtype,pname,(char *) lname,1);
|
||||
} else {
|
||||
typemap_replace_vars(s,locals,type,pname,(char *) lname,1);
|
||||
}
|
||||
|
||||
if (locals && f) {
|
||||
typemap_locals(s,locals,f,-1);
|
||||
}
|
||||
{
|
||||
replace_embedded_typemap(s,f);
|
||||
/* {
|
||||
String *tmname = Getattr(tm,"typemap");
|
||||
if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY);
|
||||
}
|
||||
}*/
|
||||
|
||||
Replace(s,"$name",pname,DOH_REPLACE_ANY);
|
||||
|
||||
symname = Getattr(node,"sym:name");
|
||||
|
|
@ -1312,13 +1328,14 @@ Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f)
|
|||
pname = Getattr(p,"name");
|
||||
lname = Getattr(p,"lname");
|
||||
mtype = Getattr(p,"tmap:match");
|
||||
|
||||
|
||||
if (mtype) {
|
||||
typemap_replace_vars(s,locals, mtype,pname,lname,i+1);
|
||||
Delattr(p,"tmap:match");
|
||||
} else {
|
||||
typemap_replace_vars(s,locals, type,pname,lname,i+1);
|
||||
}
|
||||
|
||||
if (checkAttribute(tm,"type","SWIGTYPE")) {
|
||||
sprintf(temp,"%s:SWIGTYPE", Char(op));
|
||||
Setattr(p,tmop_name(temp),"1");
|
||||
|
|
@ -1330,6 +1347,8 @@ Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f)
|
|||
typemap_locals(s,locals,f,argnum);
|
||||
}
|
||||
|
||||
replace_embedded_typemap(s,f);
|
||||
|
||||
/* Replace the argument number */
|
||||
sprintf(temp,"%d",argnum);
|
||||
Replace(s,"$argnum",temp, DOH_REPLACE_ANY);
|
||||
|
|
@ -1358,6 +1377,198 @@ Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f)
|
|||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* replace_embedded_typemap()
|
||||
*
|
||||
* This function replaces the special variable $typemap(....) with typemap
|
||||
* code. The general form of $typemap is as follows:
|
||||
*
|
||||
* $TYPEMAP(method, $var1=value, $var2=value, $var3=value,...)
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* $TYPEMAP(in, $1=int x, $input=y, ...)
|
||||
*
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* Splits the arguments of an embedded typemap */
|
||||
static List *split_embedded(String *s) {
|
||||
List *args = 0;
|
||||
char *c,*start;
|
||||
int level=0;
|
||||
int leading = 1;
|
||||
args = NewList();
|
||||
|
||||
c = Strstr(s,"(");
|
||||
c++;
|
||||
|
||||
start = c;
|
||||
while (*c) {
|
||||
if (*c == '\"') {
|
||||
c++;
|
||||
while (*c) {
|
||||
if (*c == '\\') {
|
||||
c++;
|
||||
} else {
|
||||
if (*c == '\"') break;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
if ((level == 0) && ((*c == ',') || (*c == ')'))) {
|
||||
String *tmp = NewStringWithSize(start,c-start);
|
||||
Append(args,tmp);
|
||||
Delete(tmp);
|
||||
start = c+1;
|
||||
leading = 1;
|
||||
if (*c == ')') break;
|
||||
c++;
|
||||
continue;
|
||||
}
|
||||
if (*c == '(') level++;
|
||||
if (*c == ')') level--;
|
||||
if (isspace(*c) && leading) start++;
|
||||
if (!isspace(*c)) leading = 0;
|
||||
c++;
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
static void split_var(String *s, String **name, String **value) {
|
||||
char *eq;
|
||||
char *c;
|
||||
extern Parm *Swig_cparse_parm(String *s);
|
||||
|
||||
eq = Strstr(s,"=");
|
||||
if (!eq) {
|
||||
*name = 0;
|
||||
*value = 0;
|
||||
return;
|
||||
}
|
||||
c = Char(s);
|
||||
*name = NewStringWithSize(c,eq-c);
|
||||
|
||||
/* Look for $n variables */
|
||||
if (isdigit(*(c))) {
|
||||
/* Parse the value as a type */
|
||||
String *v;
|
||||
Parm *p;
|
||||
v = NewString(eq+1);
|
||||
p = Swig_cparse_parm(v);
|
||||
Delete(v);
|
||||
*value = p;
|
||||
} else {
|
||||
*value = NewString(eq+1);
|
||||
}
|
||||
}
|
||||
|
||||
void replace_embedded_typemap(String *s, Wrapper *f) {
|
||||
while (Strstr(s,"$TYPEMAP(")) {
|
||||
|
||||
/* Gather the argument */
|
||||
char *start, *end=0,*c;
|
||||
int level = 0;
|
||||
String *tmp;
|
||||
start = Strstr(s,"$TYPEMAP(");
|
||||
c = start;
|
||||
while (*c) {
|
||||
if (*c == '(') level++;
|
||||
if (*c == ')') {
|
||||
level--;
|
||||
if (level == 0) {
|
||||
end = c+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
c++;
|
||||
}
|
||||
if (end) {
|
||||
tmp = NewStringWithSize(start,(end-start));
|
||||
} else {
|
||||
tmp = 0;
|
||||
}
|
||||
|
||||
/* Got a substitution. Split it apart into pieces */
|
||||
if (tmp) {
|
||||
List *l;
|
||||
Hash *vars;
|
||||
String *method;
|
||||
int i;
|
||||
|
||||
l = split_embedded(tmp);
|
||||
vars = NewHash();
|
||||
for (i = 1; i < Len(l); i++) {
|
||||
String *n, *v;
|
||||
split_var(Getitem(l,i),&n,&v);
|
||||
if (n && v) {
|
||||
Insert(n,0,"$");
|
||||
Setattr(vars,n,v);
|
||||
}
|
||||
}
|
||||
|
||||
method = Getitem(l,0);
|
||||
/* Generate the parameter list for matching typemaps */
|
||||
|
||||
{
|
||||
Parm *p = 0;
|
||||
Parm *first = 0;
|
||||
char temp[32];
|
||||
int n = 1;
|
||||
while (1) {
|
||||
Hash *v;
|
||||
sprintf(temp,"$%d",n);
|
||||
v = Getattr(vars,temp);
|
||||
if (v) {
|
||||
if (p) {
|
||||
set_nextSibling(p,v);
|
||||
set_previousSibling(v,p);
|
||||
}
|
||||
p = v;
|
||||
Setattr(p,"lname",Getattr(p,"name"));
|
||||
if (Getattr(p,"value")) {
|
||||
Setattr(p,"name",Getattr(p,"value"));
|
||||
}
|
||||
if (!first) first = p;
|
||||
DohIncref(p);
|
||||
Delattr(vars,temp);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
/* Perform a typemap search */
|
||||
if (first) {
|
||||
Swig_typemap_attach_parms(method,first,0);
|
||||
{
|
||||
String *tm;
|
||||
char attr[64];
|
||||
sprintf(attr,"tmap:%s",Char(method));
|
||||
|
||||
/* Look for the typemap code */
|
||||
tm = Getattr(first,attr);
|
||||
if (tm) {
|
||||
sprintf(attr,"tmap:%s:next",Char(method));
|
||||
if (!Getattr(first,attr)) {
|
||||
/* Should be no more matches. Hack??? */
|
||||
/* Replace all of the remaining variables */
|
||||
String *key;
|
||||
for (key = Firstkey(vars); key; key = Nextkey(vars)) {
|
||||
Replace(tm,key,Getattr(vars,key), DOH_REPLACE_ANY);
|
||||
}
|
||||
/* Do the replacement */
|
||||
Replace(s,tmp,tm, DOH_REPLACE_ANY);
|
||||
Delete(tm);
|
||||
Delete(vars);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Replace(s,tmp,"<embedded typemap>", DOH_REPLACE_ANY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Swig_typemap_debug()
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
|
@ -1375,3 +1586,4 @@ void Swig_typemap_debug() {
|
|||
Printf(stdout,"-----------------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue