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:
Dave Beazley 2003-08-17 21:19:27 +00:00
commit 9040f3a579
2 changed files with 240 additions and 6 deletions

View file

@ -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;
}

View file

@ -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");
}