Ejemplo n.º 1
0
static void mangle_namestr(String *mangled, SwigType *t) {
  int length = Len(t);
  if (SwigType_isqualifier(t)) {
    Append(mangled, "q_");
    mangle_stringcopy(mangled, Char(t)+2, length-4);
    Append(mangled, "__");
  } else if (SwigType_ismemberpointer(t)) {
    Append(mangled, "m_");
    mangle_stringcopy(mangled, Char(t)+2, length-4);
    Append(mangled, "__");
  } else if (SwigType_isarray(t)) {
    Append(mangled, "a_");
    mangle_stringcopy(mangled, Char(t)+2, length-4);
    Append(mangled, "__");
  } else if (SwigType_isfunction(t)) {
    List *p = SwigType_parmlist(t);
    int sz = Len(p);
    int i;
    Append(mangled, "f_");
    for (i = 0; i < sz; i++) {
      mangle_subtype(mangled, Getitem(p, i));
      Putc('_', mangled);
    }
    Append(mangled, (sz > 0) ? "_" : "__");
  } else if (SwigType_isvarargs(t)) {
    Append(mangled, "___");
  } else {
    char *d = Char(t);
    char *c = strstr(d, "<(");
    if (!c || !strstr(c + 2, ")>")) {
      /* not a template type */
      mangle_stringcopy(mangled, Char(t), Len(t));
    } else {
      /* a template type */
      String *suffix;
      List *p;
      int i, sz;
      mangle_stringcopy(mangled, d, c-d);
      Putc('T', mangled);
      Putc('_', mangled);

      p = SwigType_parmlist(c + 1);
      sz = Len(p);
      for (i = 0; i < sz; i++) {
	mangle_subtype(mangled, Getitem(p, i));
	Putc('_', mangled);
      }
      Putc('t', mangled);
      suffix = SwigType_templatesuffix(t);
      if (Len(suffix) > 0) {
	mangle_namestr(mangled, suffix);
      } else {
	Append(mangled, suffix);
      }
      Delete(suffix);
      Delete(p);
    }
  }
}
Ejemplo n.º 2
0
FILE *
Swig_open(const String_or_char *name) {
    FILE        *f;
    String   *filename;
    List     *spath = 0;
    char        *cname;
    int          i;

    if (!directories) directories = NewList();
    assert(directories);

    cname = Char(name);
    filename = NewString(cname);
    assert(filename);
    f = fopen(Char(filename),"r");
    if (!f) {
        spath = Swig_search_path();
        for (i = 0; i < Len(spath); i++) {
            Clear(filename);
            Printf(filename,"%s%s", Getitem(spath,i), cname);
            f = fopen(Char(filename),"r");
            if (f) break;
        }
        Delete(spath);
    }
    if (f) {
        Delete(lastpath);
        lastpath = Copy(filename);
    }
    Delete(filename);
    return f;
}
Ejemplo n.º 3
0
List *
Swig_search_path() {
    String *filename;
    String *dirname;
    List   *slist;
    int i;

    slist = NewList();
    assert(slist);
    filename = NewString("");
    assert(filename);
#ifdef MACSWIG
    Printf(filename,"%s",SWIG_FILE_DELIMETER);
#else
    Printf(filename,".%s", SWIG_FILE_DELIMETER);
#endif
    Append(slist,filename);
    for (i = 0; i < Len(directories); i++) {
        dirname =  Getitem(directories,i);
        filename = NewString("");
        assert(filename);
        Printf(filename, "%s%s", dirname, SWIG_FILE_DELIMETER);
        Append(slist,filename);
    }
    return slist;
}
Ejemplo n.º 4
0
static FILE *Swig_open_file(const_String_or_char_ptr name, int sysfile, int use_include_path) {
  FILE *f;
  String *filename;
  List *spath = 0;
  char *cname;
  int i, ilen;

  if (!directories)
    directories = NewList();
  assert(directories);

  cname = Char(name);
  filename = NewString(cname);
  assert(filename);
  f = fopen(Char(filename), "r");
  if (!f && use_include_path) {
    spath = Swig_search_path_any(sysfile);
    ilen = Len(spath);
    for (i = 0; i < ilen; i++) {
      Clear(filename);
      Printf(filename, "%s%s", Getitem(spath, i), cname);
      f = fopen(Char(filename), "r");
      if (f)
	break;
    }
    Delete(spath);
  }
  if (f) {
    Delete(lastpath);
    lastpath = filename;
  }
  return f;
}
Ejemplo n.º 5
0
int Swig_name_match_nameobj(Hash *rn, Node *n) {
  int match = 1;
  List *matchlist = Getattr(rn, "matchlist");
#ifdef SWIG_DEBUG
  Printf(stdout, "Swig_name_match_nameobj: %s\n", Getattr(n, "name"));
#endif
  if (matchlist) {
    int ilen = Len(matchlist);
    int i;
    for (i = 0; match && (i < ilen); ++i) {
      Node *mi = Getitem(matchlist, i);
      List *lattr = Getattr(mi, "attrlist");
      String *nval = Swig_get_lattr(n, lattr);
      int notmatch = GetFlag(mi, "notmatch");
      int regexmatch = GetFlag(mi, "regexmatch");
      match = 0;
      if (nval) {
	String *kwval = Getattr(mi, "value");
	match = regexmatch ? Swig_name_regexmatch_value(n, kwval, nval)
	    : Swig_name_match_value(kwval, nval);
#ifdef SWIG_DEBUG
	Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen);
#endif
      }
      if (notmatch)
	match = !match;
    }
  }
#ifdef SWIG_DEBUG
  Printf(stdout, "Swig_name_match_nameobj: %d\n", match);
#endif
  return match;
}
Ejemplo n.º 6
0
/* -----------------------------------------------------------------------------
 * brackets_count()
 *
 * Returns the number of brackets at the current depth.
 * A syntax error with unbalanced ) brackets will result in a NULL pointer return.
 * ----------------------------------------------------------------------------- */
static int *brackets_count(Scanner *s) {
  int *count;
  if (Len(s->brackets) > 0)
    count = (int *)Data(Getitem(s->brackets, 0));
  else
    count = 0;
  return count;
}
Ejemplo n.º 7
0
static List *Swig_search_path_any(int syspath) {
  String *filename;
  List   *slist;
  int     i, ilen;

  slist = NewList();
  assert(slist);
  filename = NewStringEmpty();
  assert(filename);
#ifdef MACSWIG
  Printf(filename, "%s", SWIG_FILE_DELIMITER);
#else
  Printf(filename, ".%s", SWIG_FILE_DELIMITER);
#endif
  Append(slist, filename);
  Delete(filename);
  
  /* If there are any pushed directories.  Add them first */
  if (pdirectories) {
    ilen = Len(pdirectories);
    for (i = 0; i < ilen; i++) {
      filename = NewString(Getitem(pdirectories,i));
      Append(filename,SWIG_FILE_DELIMITER);
      Append(slist,filename);
      Delete(filename);
    }
  }
  /* Add system directories next */
  ilen = Len(directories);
  for (i = 0; i < ilen; i++) {
    filename = NewString(Getitem(directories,i));
    Append(filename,SWIG_FILE_DELIMITER);
    if (syspath) {
      /* If doing a system include, put the system directories first */
      Insert(slist,i,filename);
    } else {
      /* Otherwise, just put the system directories after the pushed directories (if any) */
      Append(slist,filename);
    }
    Delete(filename);
  }
  return slist;
}
Ejemplo n.º 8
0
SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) {
  List *qlist;
  String *allq, *newq;
  int i, sz;
  const char *cqprev = 0;
  const char *c = Char(t);
  const char *cqual = Char(qual);

  /* if 't' has no qualifiers and 'qual' is a single qualifier, simply add it */
  if ((strncmp(c, "q(", 2) != 0) && (strstr(cqual, " ") == 0)) {
    String *temp = NewStringf("q(%s).", cqual);
    Insert(t, 0, temp);
    Delete(temp);
    return t;
  }

  /* create string of all qualifiers */
  if (strncmp(c, "q(", 2) == 0) {
    allq = SwigType_parm(t);
    Append(allq, " ");
    SwigType_del_element(t);     /* delete old qualifier list from 't' */
  } else {
    allq = NewStringEmpty();
  }
  Append(allq, qual);

  /* create list of all qualifiers from string */
  qlist = Split(allq, ' ', INT_MAX);
  Delete(allq);

  /* sort in alphabetical order */
  SortList(qlist, Strcmp);

  /* create new qualifier string from unique elements of list */
  sz = Len(qlist);
  newq = NewString("q(");
  for (i = 0; i < sz; ++i) {
    String *q = Getitem(qlist, i);
    const char *cq = Char(q);
    if (cqprev == 0 || strcmp(cqprev, cq) != 0) {
      if (i > 0) {
        Append(newq, " ");
      }
      Append(newq, q);
      cqprev = cq;
    }
  }
  Append(newq, ").");
  Delete(qlist);

  /* replace qualifier string with new one */
  Insert(t, 0, newq);
  Delete(newq);
  return t;
}
Ejemplo n.º 9
0
Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) {
  Hash *res = 0;
  if (namelist) {
    int len = Len(namelist);
    int i;
    int match = 0;
    for (i = 0; !match && (i < len); i++) {
      Hash *rn = Getitem(namelist, i);
      String *rdecl = Getattr(rn, "decl");
      if (rdecl && (!decl || !Equal(rdecl, decl))) {
	continue;
      } else if (Swig_name_match_nameobj(rn, n)) {
	String *tname = Getattr(rn, "targetname");
	if (tname) {
	  String *sfmt = Getattr(rn, "sourcefmt");
	  String *sname = 0;
	  int fullname = GetFlag(rn, "fullname");
	  int regextarget = GetFlag(rn, "regextarget");
	  if (sfmt) {
	    if (fullname && prefix) {
	      String *pname = NewStringf("%s::%s", prefix, name);
	      sname = NewStringf(sfmt, pname);
	      Delete(pname);
	    } else {
	      sname = NewStringf(sfmt, name);
	    }
	  } else {
	    if (fullname && prefix) {
	      sname = NewStringf("%s::%s", prefix, name);
	    } else {
	      sname = name;
	      DohIncref(name);
	    }
	  }
	  match = regextarget ? Swig_name_regexmatch_value(n, tname, sname)
	    : Swig_name_match_value(tname, sname);
	  Delete(sname);
	} else {
	  /* Applying the renaming rule may fail if it contains a %(regex)s expression that doesn't match the given name. */
	  String *sname = NewStringf(Getattr(rn, "name"), name);
	  if (sname) {
	    if (Len(sname))
	      match = 1;
	    Delete(sname);
	  }
	}
      }
      if (match) {
	res = rn;
	break;
      }
    }
  }
  return res;
}
Ejemplo n.º 10
0
static void mangle_subtype(String *mangled, SwigType *s) {
  List *elements;
  int nelements, i;

  assert(s);
  elements = SwigType_split(s);
  nelements = Len(elements);
  for (i = 0; i < nelements; i++) {
    SwigType *element = Getitem(elements, i);
    mangle_namestr(mangled, element);
  }
  Delete(elements);
}
Ejemplo n.º 11
0
SwigType *SwigType_strip_single_qualifier(const SwigType *t) {
  static Hash *memoize_stripped = 0;
  SwigType *r = 0;
  List *l;
  int numitems;

  if (!memoize_stripped)
    memoize_stripped = NewHash();
  r = Getattr(memoize_stripped, t);
  if (r)
    return Copy(r);

  l = SwigType_split(t);

  numitems = Len(l);
  if (numitems >= 2) {
    int item;
    /* iterate backwards from last but one item */
    for (item = numitems - 2; item >= 0; --item) {
      String *subtype = Getitem(l, item);
      if (SwigType_isqualifier(subtype)) {
	Iterator it;
	Delitem(l, item);
	r = NewStringEmpty();
	for (it = First(l); it.item; it = Next(it)) {
	  Append(r, it.item);
	}
	break;
      }
    }
  }
  if (!r)
    r = Copy(t);

  Delete(l);
  {
    String *key, *value;
    key = Copy(t);
    value = Copy(r);
    Setattr(memoize_stripped, key, value);
    Delete(key);
    Delete(value);
  }
  return r;
}
Ejemplo n.º 12
0
static DOH *Swig_get_lattr(Node *n, List *lattr) {
  DOH *res = 0;
  int ilen = Len(lattr);
  int i;
  for (i = 0; n && (i < ilen); ++i) {
    String *nattr = Getitem(lattr, i);
    res = Getattr(n, nattr);
#ifdef SWIG_DEBUG
    if (!res) {
      Printf(stdout, "missing %s %s %s\n", nattr, Getattr(n, "name"), Getattr(n, "member"));
    } else {
      Printf(stdout, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, "name"));
    }
#endif
    n = res;
  }
  return res;
}
Ejemplo n.º 13
0
SwigType *SwigType_default_create(const SwigType *ty) {
  SwigType *r = 0;
  List *l;
  Iterator it;
  int numitems;

  if (!SwigType_isvarargs(ty)) {
    SwigType *t = SwigType_typedef_resolve_all(ty);
    r = NewStringEmpty();
    l = SwigType_split(t);
    numitems = Len(l);

    if (numitems >= 1) {
      String *last_subtype = Getitem(l, numitems-1);
      if (SwigType_isenum(last_subtype))
	Setitem(l, numitems-1, NewString("enum SWIGTYPE"));
      else
	Setitem(l, numitems-1, NewString("SWIGTYPE"));
    }

    for (it = First(l); it.item; it = Next(it)) {
      String *subtype = it.item;
      if (SwigType_isarray(subtype)) {
	if (Equal(subtype, "a()."))
	  Append(r, NewString("a()."));
	else
	  Append(r, NewString("a(ANY)."));
      } else if (SwigType_isfunction(subtype)) {
	Append(r, NewString("f(ANY).SWIGTYPE"));
	break;
      } else if (SwigType_ismemberpointer(subtype)) {
	Append(r, NewString("m(CLASS).SWIGTYPE"));
	break;
      } else {
	Append(r, subtype);
      }
    }

    Delete(l);
    Delete(t);
  }

  return r;
}
Ejemplo n.º 14
0
/* -----------------------------------------------------------------------------
 * nextchar()
 * 
 * Returns the next character from the scanner or 0 if end of the string.
 * ----------------------------------------------------------------------------- */
static char nextchar(Scanner *s) {
  int nc;
  if (!s->str)
    return 0;
  while ((nc = Getc(s->str)) == EOF) {
    Delete(s->str);
    s->str = 0;
    Delitem(s->scanobjs, 0);
    if (Len(s->scanobjs) == 0)
      return 0;
    s->str = Getitem(s->scanobjs, 0);
    s->line = Getline(s->str);
    DohIncref(s->str);
  }
  if ((nc == '\n') && (!s->freeze_line)) 
    s->line++;
  Putc(nc,s->text);
  return (char)nc;
}
Ejemplo n.º 15
0
String *SwigType_namestr(const SwigType *t) {
  String *r;
  String *suffix;
  List *p;
  int i, sz;
  char *d = Char(t);
  char *c = strstr(d, "<(");

  if (!c || !strstr(c + 2, ")>"))
    return NewString(t);

  r = NewStringWithSize(d, c - d);
  if (*(c - 1) == '<')
    Putc(' ', r);
  Putc('<', r);

  p = SwigType_parmlist(c + 1);
  sz = Len(p);
  for (i = 0; i < sz; i++) {
    String *str = SwigType_str(Getitem(p, i), 0);
    /* Avoid creating a <: token, which is the same as [ in C++ - put a space after '<'. */
    if (i == 0 && Len(str))
      Putc(' ', r);
    Append(r, str);
    if ((i + 1) < sz)
      Putc(',', r);
    Delete(str);
  }
  Putc(' ', r);
  Putc('>', r);
  suffix = SwigType_templatesuffix(t);
  if (Len(suffix) > 0) {
    String *suffix_namestr = SwigType_namestr(suffix);
    Append(r, suffix_namestr);
    Delete(suffix_namestr);
  } else {
    Append(r, suffix);
  }
  Delete(suffix);
  Delete(p);
  return r;
}
Ejemplo n.º 16
0
/* -----------------------------------------------------------------------------
 * nextchar()
 * 
 * Returns the next character from the scanner or 0 if end of the string.
 * ----------------------------------------------------------------------------- */
static char
nextchar(SwigScanner *s)
{
  char c[2] = {0,0};
  int nc;
  if (!s->str) return 0;
  while ((nc = Getc(s->str)) == EOF) {
    Delete(s->str);
    s->str = 0;
    Delitem(s->scanobjs,0);
    if (Len(s->scanobjs) == 0) return 0;
    s->str = Getitem(s->scanobjs,0);
    if (s->str) {
      s->line = Getline(s->str);
      DohIncref(s->str);
    }
  }
  if (nc == '\n') s->line++;
  c[0] = (char) nc;
  c[1] = 0;
  Append(s->text,c);
  return c[0];
}
Ejemplo n.º 17
0
SwigType *SwigType_default_deduce(const SwigType *t) {
  SwigType *r = NewStringEmpty();
  List *l;
  Iterator it;
  int numitems;

  l = SwigType_split(t);

  numitems = Len(l);
  if (numitems >= 1) {
    String *last_subtype = Getitem(l, numitems-1);
    int is_enum = SwigType_isenum(last_subtype);

    if (numitems >=2 ) {
      String *subtype = Getitem(l, numitems-2); /* last but one */
      if (SwigType_isarray(subtype)) {
	if (is_enum) {
	  /* enum deduction, enum SWIGTYPE => SWIGTYPE */
	  Setitem(l, numitems-1, NewString("SWIGTYPE"));
	} else {
	  /* array deduction, a(ANY). => a(). => p. */
	  String *deduced_subtype = 0;
	  if (Strcmp(subtype, "a().") == 0) {
	    deduced_subtype = NewString("p.");
	  } else if (Strcmp(subtype, "a(ANY).") == 0) {
	    deduced_subtype = NewString("a().");
	  } else {
	    assert(0);
	  }
	  Setitem(l, numitems-2, deduced_subtype);
	}
      } else if (SwigType_ismemberpointer(subtype)) {
	/* member pointer deduction, m(CLASS). => p. */
	Setitem(l, numitems-2, NewString("p."));
      } else if (is_enum && !SwigType_isqualifier(subtype)) {
	/* enum deduction, enum SWIGTYPE => SWIGTYPE */
	Setitem(l, numitems-1, NewString("SWIGTYPE"));
      } else {
	/* simple type deduction, eg, r.p.p. => r.p. */
	/* also function pointers eg, p.f(ANY). => p. */
	Delitem(l, numitems-2);
      }
    } else {
      if (is_enum) {
	/* enum deduction, enum SWIGTYPE => SWIGTYPE */
	Setitem(l, numitems-1, NewString("SWIGTYPE"));
      } else {
	/* delete the only item, we are done with deduction */
	Delitem(l, 0);
      }
    }
  } else {
    assert(0);
  }

  for (it = First(l); it.item; it = Next(it)) {
    Append(r, it.item);
  }

  if (Len(r) == 0) {
    Delete(r);
    r = 0;
  }

  Delete(l);
  return r;
}
Ejemplo n.º 18
0
static int cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
  static int expanded = 0;
  int ret;
  String *nodeType;
  if (!n)
    return 0;
  nodeType = nodeType(n);
  if (Getattr(n, "error"))
    return 0;

  if (Equal(nodeType, "template")) {
    /* Change the node type back to normal */
    if (!expanded) {
      expanded = 1;
      set_nodeType(n, Getattr(n, "templatetype"));
      ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      expanded = 0;
      return ret;
    } else {
      /* Called when template appears inside another template */
      /* Member templates */

      set_nodeType(n, Getattr(n, "templatetype"));
      ret = cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      set_nodeType(n, "template");
      return ret;
    }
  } else if (Equal(nodeType, "cdecl")) {
    /* A simple C declaration */
    SwigType *t, *v, *d;
    String *code;
    t = Getattr(n, "type");
    v = Getattr(n, "value");
    d = Getattr(n, "decl");

    code = Getattr(n, "code");

    Append(typelist, t);
    Append(typelist, d);
    Append(patchlist, v);
    Append(cpatchlist, code);

    if (Getattr(n, "conversion_operator")) {
      Append(cpatchlist, Getattr(n, "name"));
      if (Getattr(n, "sym:name")) {
	Append(cpatchlist, Getattr(n, "sym:name"));
      }
    }

    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);

  } else if (Equal(nodeType, "class")) {
    /* Patch base classes */
    {
      int b = 0;
      for (b = 0; b < 3; ++b) {
	List *bases = Getattr(n, baselists[b]);
	if (bases) {
	  int i;
	  int ilen = Len(bases);
	  for (i = 0; i < ilen; i++) {
	    String *name = Copy(Getitem(bases, i));
	    Setitem(bases, i, name);
	    Append(typelist, name);
	  }
	}
      }
    }
    /* Patch children */
    {
      Node *cn = firstChild(n);
      while (cn) {
	cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
	cn = nextSibling(cn);
      }
    }
  } else if (Equal(nodeType, "constructor")) {
    String *name = Getattr(n, "name");
    if (!(Getattr(n, "templatetype"))) {
      String *symname;
      String *stripped_name = SwigType_templateprefix(name);
      if (Strstr(tname, stripped_name)) {
	Replaceid(name, stripped_name, tname);
      }
      Delete(stripped_name);
      symname = Getattr(n, "sym:name");
      if (symname) {
	stripped_name = SwigType_templateprefix(symname);
	if (Strstr(tname, stripped_name)) {
	  Replaceid(symname, stripped_name, tname);
	}
	Delete(stripped_name);
      }
      if (strchr(Char(name), '<')) {
	Append(patchlist, Getattr(n, "name"));
      } else {
	Append(name, templateargs);
      }
      name = Getattr(n, "sym:name");
      if (name) {
	if (strchr(Char(name), '<')) {
	  Clear(name);
	  Append(name, rname);
	} else {
	  String *tmp = Copy(name);
	  Replace(tmp, tname, rname, DOH_REPLACE_ANY);
	  Clear(name);
	  Append(name, tmp);
	  Delete(tmp);
	}
      }
      /* Setattr(n,"sym:name",name); */
    }
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
  } else if (Equal(nodeType, "destructor")) {
    String *name = Getattr(n, "name");
    if (name) {
      if (strchr(Char(name), '<'))
        Append(patchlist, Getattr(n, "name"));
      else
        Append(name, templateargs);
    }
    name = Getattr(n, "sym:name");
    if (name) {
      if (strchr(Char(name), '<')) {
        String *sn = Copy(tname);
        Setattr(n, "sym:name", sn);
        Delete(sn);
      } else {
        Replace(name, tname, rname, DOH_REPLACE_ANY);
      }
    }
    /* Setattr(n,"sym:name",name); */
    Append(cpatchlist, Getattr(n, "code"));
  } else if (Equal(nodeType, "using")) {
    String *uname = Getattr(n, "uname");
    if (uname && strchr(Char(uname), '<')) {
      Append(patchlist, uname);
    }
    if (Getattr(n, "namespace")) {
      /* Namespace link.   This is nasty.  Is other namespace defined? */

    }
  } else {
    /* Look for obvious parameters */
    Node *cn;
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "type"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "kwargs"), cpatchlist, typelist);
    add_parms(Getattr(n, "pattern"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
    cn = firstChild(n);
    while (cn) {
      cparse_template_expand(cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      cn = nextSibling(cn);
    }
  }
  return 0;
}
Ejemplo n.º 19
0
static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
  Node *n;
  String *tname, *rname = 0;
  Node *templ;
  List *mpartials = 0;
  Parm *p;
  Parm *parms;
  Parm *targs;
  ParmList *expandedparms;

  tname = Copy(name);
  parms = CopyParmList(tparms);

  /* Search for generic template */
  templ = Swig_symbol_clookup(name, 0);

  /* Add default values from generic template */
  if (templ) {
    Symtab *tsdecl = Getattr(templ, "sym:symtab");

    targs = Getattr(templ, "templateparms");
    expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, tsdecl);
  } else {
    expandedparms = parms;
  }


  /* reduce the typedef */
  p = expandedparms;
  while (p) {
    SwigType *ty = Getattr(p, "type");
    if (ty) {
      SwigType *nt = Swig_symbol_type_qualify(ty, tscope);
      Setattr(p, "type", nt);
      Delete(nt);
    }
    p = nextSibling(p);
  }

  SwigType_add_template(tname, expandedparms);

  if (template_debug) {
    Printf(stdout, "\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname);
  }

  /* Search for an exact specialization.
     Example: template<> class name<int> { ... } */
  {
    if (template_debug) {
      Printf(stdout, "    searching: '%s' (exact specialization)\n", tname);
    }
    n = Swig_symbol_clookup_local(tname, 0);
    if (!n) {
      SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope);
      if (!Equal(rname, tname)) {
	if (template_debug) {
	  Printf(stdout, "    searching: '%s' (exact specialization)\n", rname);
	}
	n = Swig_symbol_clookup_local(rname, 0);
      }
      Delete(rname);
    }
    if (n) {
      Node *tn;
      String *nodeType = nodeType(n);
      if (Equal(nodeType, "template"))
	goto success;
      tn = Getattr(n, "template");
      if (tn) {
	n = tn;
	goto success;		/* Previously wrapped by a template return that */
      }
      Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
      Delete(tname);
      Delete(parms);
      return 0;			/* Found a match, but it's not a template of any kind. */
    }
  }

  /* Search for partial specialization. 
     Example: template<typename T> class name<T *> { ... } */

  /* Generate reduced template name (stripped of extraneous pointers, etc.) */

  rname = NewStringf("%s<(", name);
  p = parms;
  while (p) {
    String *t;
    t = Getattr(p, "type");
    if (!t)
      t = Getattr(p, "value");
    if (t) {
      String *ty = Swig_symbol_typedef_reduce(t, tscope);
      String *tb = SwigType_base(ty);
      String *td = SwigType_default(ty);
      Replaceid(td, "enum SWIGTYPE", tb);
      Replaceid(td, "SWIGTYPE", tb);
      Append(rname, td);
      Delete(tb);
      Delete(ty);
      Delete(td);
    }
    p = nextSibling(p);
    if (p) {
      Append(rname, ",");
    }
  }
  Append(rname, ")>");

  mpartials = NewList();
  if (templ) {
    /* First, we search using an exact type prototype */
    Parm *p;
    char tmp[32];
    int i;
    List *partials;
    String *ss;
    Iterator pi;

    partials = Getattr(templ, "partials");
    if (partials) {
      for (pi = First(partials); pi.item; pi = Next(pi)) {
	ss = Copy(pi.item);
	p = parms;
	i = 1;
	while (p) {
	  String *t, *tn;
	  sprintf(tmp, "$%d", i);
	  t = Getattr(p, "type");
	  if (!t)
	    t = Getattr(p, "value");
	  if (t) {
	    String *ty = Swig_symbol_typedef_reduce(t, tscope);
	    tn = SwigType_base(ty);
	    Replaceid(ss, tmp, tn);
	    Delete(tn);
	    Delete(ty);
	  }
	  i++;
	  p = nextSibling(p);
	}
	if (template_debug) {
	  Printf(stdout, "    searching: '%s' (partial specialization - %s)\n", ss, pi.item);
	}
	if ((Equal(ss, tname)) || (Equal(ss, rname))) {
	  Append(mpartials, pi.item);
	}
	Delete(ss);
      }
    }
  }

  if (template_debug) {
    Printf(stdout, "    Matched partials: %s\n", mpartials);
  }

  if (Len(mpartials)) {
    String *s = Getitem(mpartials, 0);
    n = Swig_symbol_clookup_local(s, 0);
    if (Len(mpartials) > 1) {
      if (n) {
	Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname));
	Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), "  instantiation '%s' is used.\n", SwigType_namestr(Getattr(n, "name")));
      }
    }
  }

  if (!n) {
    n = templ;
  }
  if (!n) {
    Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
  } else if (n) {
    String *nodeType = nodeType(n);
    if (!Equal(nodeType, "template")) {
      Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType);
      n = 0;
    }
  }
success:
  Delete(tname);
  Delete(rname);
  Delete(mpartials);
  if ((template_debug) && (n)) {
    Printf(stdout, "Node: %p\n", n);
    Swig_print_node(n);
  }
  Delete(parms);
  return n;
}
Ejemplo n.º 20
0
int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope) {
  List *patchlist, *cpatchlist, *typelist;
  String *templateargs;
  String *tname;
  String *iname;
  String *tbase;
  patchlist = NewList();
  cpatchlist = NewList();
  typelist = NewList();

  {
    String *tmp = NewStringEmpty();
    if (tparms) {
      SwigType_add_template(tmp, tparms);
    }
    templateargs = Copy(tmp);
    Delete(tmp);
  }

  tname = Copy(Getattr(n, "name"));
  tbase = Swig_scopename_last(tname);

  /* Look for partial specialization matching */
  if (Getattr(n, "partialargs")) {
    Parm *p, *tp;
    ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs"));
    p = ptargs;
    tp = tparms;
    while (p && tp) {
      SwigType *ptype;
      SwigType *tptype;
      SwigType *partial_type;
      ptype = Getattr(p, "type");
      tptype = Getattr(tp, "type");
      if (ptype && tptype) {
	partial_type = partial_arg(tptype, ptype);
	/*      Printf(stdout,"partial '%s' '%s'  ---> '%s'\n", tptype, ptype, partial_type); */
	Setattr(tp, "type", partial_type);
	Delete(partial_type);
      }
      p = nextSibling(p);
      tp = nextSibling(tp);
    }
    assert(ParmList_len(ptargs) == ParmList_len(tparms));
    Delete(ptargs);
  }

  /*
    Parm *p = tparms;
    while (p) {
      Printf(stdout, "tparm: '%s' '%s' '%s'\n", Getattr(p, "name"), Getattr(p, "type"), Getattr(p, "value"));
      p = nextSibling(p);
    }
  */

  /*  Printf(stdout,"targs = '%s'\n", templateargs);
     Printf(stdout,"rname = '%s'\n", rname);
     Printf(stdout,"tname = '%s'\n", tname);  */
  cparse_template_expand(n, tname, rname, templateargs, patchlist, typelist, cpatchlist);

  /* Set the name */
  {
    String *name = Getattr(n, "name");
    if (name) {
      Append(name, templateargs);
    }
    iname = name;
  }

  /* Patch all of the types */
  {
    Parm *tp = Getattr(n, "templateparms");
    Parm *p = tparms;
    /*    Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */

    if (tp) {
      Symtab *tsdecl = Getattr(n, "sym:symtab");
      while (p && tp) {
	String *name, *value, *valuestr, *tydef, *tmp, *tmpr;
	int sz, i;
	String *dvalue = 0;
	String *qvalue = 0;

	name = Getattr(tp, "name");
	value = Getattr(p, "value");
	tydef = Getattr(p, "typedef");

	if (name) {
	  if (!value)
	    value = Getattr(p, "type");
	  qvalue = Swig_symbol_typedef_reduce(value, tsdecl);
	  dvalue = Swig_symbol_type_qualify(qvalue, tsdecl);
	  if (SwigType_istemplate(dvalue)) {
	    String *ty = Swig_symbol_template_deftype(dvalue, tscope);
	    Delete(dvalue);
	    dvalue = ty;
	  }

	  assert(dvalue);
	  valuestr = SwigType_str(dvalue, 0);
	  /* Need to patch default arguments */
	  {
	    Parm *rp = nextSibling(p);
	    while (rp) {
	      String *rvalue = Getattr(rp, "value");
	      if (rvalue) {
		Replace(rvalue, name, dvalue, DOH_REPLACE_ID);
	      }
	      rp = nextSibling(rp);
	    }
	  }
	  sz = Len(patchlist);
	  for (i = 0; i < sz; i++) {
	    String *s = Getitem(patchlist, i);
	    Replace(s, name, dvalue, DOH_REPLACE_ID);
	  }
	  sz = Len(typelist);
	  for (i = 0; i < sz; i++) {
	    String *s = Getitem(typelist, i);
	    /*      Replace(s,name,value, DOH_REPLACE_ID); */
	    /*      Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */
	    SwigType_typename_replace(s, name, dvalue);
	    SwigType_typename_replace(s, tbase, iname);
	    /*      Printf(stdout,"'%s'\n", s); */
	  }

	  if (!tydef) {
	    tydef = dvalue;
	  }
	  tmp = NewStringf("#%s", name);
	  tmpr = NewStringf("\"%s\"", valuestr);

	  sz = Len(cpatchlist);
	  for (i = 0; i < sz; i++) {
	    String *s = Getitem(cpatchlist, i);
	    Replace(s, tmp, tmpr, DOH_REPLACE_ID);
	    /*  Replace(s,name,tydef, DOH_REPLACE_ID); */
	    Replace(s, name, valuestr, DOH_REPLACE_ID);
	  }
	  Delete(tmp);
	  Delete(tmpr);
	  Delete(valuestr);
	  Delete(dvalue);
	  Delete(qvalue);
	}
	p = nextSibling(p);
	tp = nextSibling(tp);
	if (!p)
	  p = tp;
      }
    } else {
      /* No template parameters at all.  This could be a specialization */
      int i, sz;
      sz = Len(typelist);
      for (i = 0; i < sz; i++) {
	String *s = Getitem(typelist, i);
	SwigType_typename_replace(s, tbase, iname);
      }
    }
  }

  /* Patch bases */
  {
    List *bases = Getattr(n, "baselist");
    if (bases) {
      Iterator b;
      for (b = First(bases); b.item; b = Next(b)) {
	String *qn = Swig_symbol_type_qualify(b.item, tscope);
	Clear(b.item);
	Append(b.item, qn);
	Delete(qn);
      }
    }
  }
  Delete(patchlist);
  Delete(cpatchlist);
  Delete(typelist);
  Delete(tbase);
  Delete(tname);
  Delete(templateargs);

  /*  set_nodeType(n,"template"); */
  return 0;
}
Ejemplo n.º 21
0
Archivo: templ.c Proyecto: kkaempf/swig
static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
  static int expanded = 0;
  String *nodeType;
  if (!n)
    return;
  nodeType = nodeType(n);
  if (Getattr(n, "error"))
    return;

  if (Equal(nodeType, "template")) {
    /* Change the node type back to normal */
    if (!expanded) {
      expanded = 1;
      set_nodeType(n, Getattr(n, "templatetype"));
      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      expanded = 0;
      return;
    } else {
      /* Called when template appears inside another template */
      /* Member templates */

      set_nodeType(n, Getattr(n, "templatetype"));
      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      set_nodeType(n, "template");
      return;
    }
  } else if (Equal(nodeType, "cdecl")) {
    /* A simple C declaration */
    SwigType *t, *v, *d;
    String *code;
    t = Getattr(n, "type");
    v = Getattr(n, "value");
    d = Getattr(n, "decl");

    code = Getattr(n, "code");

    Append(typelist, t);
    Append(typelist, d);
    Append(patchlist, v);
    Append(cpatchlist, code);

    if (Getattr(n, "conversion_operator")) {
      Append(cpatchlist, Getattr(n, "name"));
      if (Getattr(n, "sym:name")) {
	Append(cpatchlist, Getattr(n, "sym:name"));
      }
    }
    if (checkAttribute(n, "storage", "friend")) {
      String *symname = Getattr(n, "sym:name");
      if (symname) {
	String *stripped_name = SwigType_templateprefix(symname);
	Setattr(n, "sym:name", stripped_name);
	Delete(stripped_name);
      }
      Append(typelist, Getattr(n, "name"));
    }

    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);

  } else if (Equal(nodeType, "class")) {
    /* Patch base classes */
    {
      int b = 0;
      for (b = 0; b < 3; ++b) {
	List *bases = Getattr(n, baselists[b]);
	if (bases) {
	  int i;
	  int ilen = Len(bases);
	  for (i = 0; i < ilen; i++) {
	    String *name = Copy(Getitem(bases, i));
	    Setitem(bases, i, name);
	    Append(typelist, name);
	  }
	}
      }
    }
    /* Patch children */
    {
      Node *cn = firstChild(n);
      while (cn) {
	cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
	cn = nextSibling(cn);
      }
    }
  } else if (Equal(nodeType, "constructor")) {
    String *name = Getattr(n, "name");
    if (!(Getattr(n, "templatetype"))) {
      String *symname;
      String *stripped_name = SwigType_templateprefix(name);
      if (Strstr(tname, stripped_name)) {
	Replaceid(name, stripped_name, tname);
      }
      Delete(stripped_name);
      symname = Getattr(n, "sym:name");
      if (symname) {
	stripped_name = SwigType_templateprefix(symname);
	if (Strstr(tname, stripped_name)) {
	  Replaceid(symname, stripped_name, tname);
	}
	Delete(stripped_name);
      }
      if (strchr(Char(name), '<')) {
	Append(patchlist, Getattr(n, "name"));
      } else {
	Append(name, templateargs);
      }
      name = Getattr(n, "sym:name");
      if (name) {
	if (strchr(Char(name), '<')) {
	  Clear(name);
	  Append(name, rname);
	} else {
	  String *tmp = Copy(name);
	  Replace(tmp, tname, rname, DOH_REPLACE_ANY);
	  Clear(name);
	  Append(name, tmp);
	  Delete(tmp);
	}
      }
      /* Setattr(n,"sym:name",name); */
    }
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
  } else if (Equal(nodeType, "destructor")) {
    /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root
     * template node, with the special exception for %extend which adds its methods under an intermediate node. */
    Node* parent = parentNode(n);
    if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) {
      String *name = Getattr(n, "name");
      if (name) {
	if (strchr(Char(name), '<'))
	  Append(patchlist, Getattr(n, "name"));
	else
	  Append(name, templateargs);
      }
      name = Getattr(n, "sym:name");
      if (name) {
	if (strchr(Char(name), '<')) {
	  String *sn = Copy(tname);
	  Setattr(n, "sym:name", sn);
	  Delete(sn);
	} else {
	  Replace(name, tname, rname, DOH_REPLACE_ANY);
	}
      }
      /* Setattr(n,"sym:name",name); */
      Append(cpatchlist, Getattr(n, "code"));
    }
  } else if (Equal(nodeType, "using")) {
    String *uname = Getattr(n, "uname");
    if (uname && strchr(Char(uname), '<')) {
      Append(patchlist, uname);
    }
    if (Getattr(n, "namespace")) {
      /* Namespace link.   This is nasty.  Is other namespace defined? */

    }
  } else {
    /* Look for obvious parameters */
    Node *cn;
    Append(cpatchlist, Getattr(n, "code"));
    Append(typelist, Getattr(n, "type"));
    Append(typelist, Getattr(n, "decl"));
    add_parms(Getattr(n, "parms"), cpatchlist, typelist);
    add_parms(Getattr(n, "kwargs"), cpatchlist, typelist);
    add_parms(Getattr(n, "pattern"), cpatchlist, typelist);
    add_parms(Getattr(n, "throws"), cpatchlist, typelist);
    cn = firstChild(n);
    while (cn) {
      cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
      cn = nextSibling(cn);
    }
  }
}
Ejemplo n.º 22
0
String *SwigType_str(SwigType *s, const String_or_char *id) {
  String *result;
  String *element = 0, *nextelement;
  List *elements;
  int nelements, i;

  if (id) {
    result = NewString(id);
  } else {
    result = NewStringEmpty();
  }

  elements = SwigType_split(s);
  nelements = Len(elements);

  if (nelements > 0) {
    element = Getitem(elements, 0);
  }
  /* Now, walk the type list and start emitting */
  for (i = 0; i < nelements; i++) {
    if (i < (nelements - 1)) {
      nextelement = Getitem(elements, i + 1);
    } else {
      nextelement = 0;
    }
    if (SwigType_isqualifier(element)) {
      DOH *q = 0;
      q = SwigType_parm(element);
      Insert(result, 0, " ");
      Insert(result, 0, q);
      Delete(q);
    } else if (SwigType_ispointer(element)) {
      Insert(result, 0, "*");
      if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
    } else if (SwigType_ismemberpointer(element)) {
      String *q;
      q = SwigType_parm(element);
      Insert(result, 0, "::*");
      Insert(result, 0, q);
      if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
      Delete(q);
    } else if (SwigType_isreference(element)) {
      Insert(result, 0, "&");
      if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
    } else if (SwigType_isarray(element)) {
      DOH *size;
      Append(result, "[");
      size = SwigType_parm(element);
      Append(result, size);
      Append(result, "]");
      Delete(size);
    } else if (SwigType_isfunction(element)) {
      DOH *parms, *p;
      int j, plen;
      Append(result, "(");
      parms = SwigType_parmlist(element);
      plen = Len(parms);
      for (j = 0; j < plen; j++) {
	p = SwigType_str(Getitem(parms, j), 0);
	Append(result, p);
	if (j < (plen - 1))
	  Append(result, ",");
      }
      Append(result, ")");
      Delete(parms);
    } else {
      if (strcmp(Char(element), "v(...)") == 0) {
	Insert(result, 0, "...");
      } else {
	String *bs = SwigType_namestr(element);
	Insert(result, 0, " ");
	Insert(result, 0, bs);
	Delete(bs);
      }
    }
    element = nextelement;
  }
  Delete(elements);
  Chop(result);
  return result;
}
Ejemplo n.º 23
0
static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
  Node *n = 0;
  String *tname = 0;
  Node *templ;
  Symtab *primary_scope = 0;
  List *possiblepartials = 0;
  Parm *p;
  Parm *parms = 0;
  Parm *targs;
  ParmList *expandedparms;
  int *priorities_matrix = 0;
  int max_possible_partials = 0;
  int posslen = 0;

  /* Search for primary (unspecialized) template */
  templ = Swig_symbol_clookup(name, 0);

  if (template_debug) {
    tname = Copy(name);
    SwigType_add_template(tname, tparms);
    Printf(stdout, "\n");
    Swig_diagnostic(cparse_file, cparse_line, "template_debug: Searching for match to: '%s'\n", tname);
    Delete(tname);
    tname = 0;
  }

  if (templ) {
    tname = Copy(name);
    parms = CopyParmList(tparms);

    /* All template specializations must be in the primary template's scope, store the symbol table for this scope for specialization lookups */
    primary_scope = Getattr(templ, "sym:symtab");

    /* Add default values from primary template */
    targs = Getattr(templ, "templateparms");
    expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, primary_scope);

    /* reduce the typedef */
    p = expandedparms;
    while (p) {
      SwigType *ty = Getattr(p, "type");
      if (ty) {
	SwigType *nt = Swig_symbol_type_qualify(ty, tscope);
	Setattr(p, "type", nt);
	Delete(nt);
      }
      p = nextSibling(p);
    }
    SwigType_add_template(tname, expandedparms);

    /* Search for an explicit (exact) specialization. Example: template<> class name<int> { ... } */
    {
      if (template_debug) {
	Printf(stdout, "    searching for : '%s' (explicit specialization)\n", tname);
      }
      n = Swig_symbol_clookup_local(tname, primary_scope);
      if (!n) {
	SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope);
	if (!Equal(rname, tname)) {
	  if (template_debug) {
	    Printf(stdout, "    searching for : '%s' (explicit specialization with typedef reduction)\n", rname);
	  }
	  n = Swig_symbol_clookup_local(rname, primary_scope);
	}
	Delete(rname);
      }
      if (n) {
	Node *tn;
	String *nodeType = nodeType(n);
	if (Equal(nodeType, "template")) {
	  if (template_debug) {
	    Printf(stdout, "    explicit specialization found: '%s'\n", Getattr(n, "name"));
	  }
	  goto success;
	}
	tn = Getattr(n, "template");
	if (tn) {
	  if (template_debug) {
	    Printf(stdout, "    previous instantiation found: '%s'\n", Getattr(n, "name"));
	  }
	  n = tn;
	  goto success;	  /* Previously wrapped by a template instantiation */
	}
	Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
	Delete(tname);
	Delete(parms);
	return 0;	  /* Found a match, but it's not a template of any kind. */
      }
    }

    /* Search for partial specializations.
     * Example: template<typename T> class name<T *> { ... } 

     * There are 3 types of template arguments:
     * (1) Template type arguments
     * (2) Template non type arguments
     * (3) Template template arguments
     * only (1) is really supported for partial specializations
     */

    /* Rank each template parameter against the desired template parameters then build a matrix of best matches */
    possiblepartials = NewList();
    {
      char tmp[32];
      List *partials;

      partials = Getattr(templ, "partials"); /* note that these partial specializations do not include explicit specializations */
      if (partials) {
	Iterator pi;
	int parms_len = ParmList_len(parms);
	int *priorities_row;
	max_possible_partials = Len(partials);
	priorities_matrix = (int *)malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */
	priorities_row = priorities_matrix;
	for (pi = First(partials); pi.item; pi = Next(pi)) {
	  Parm *p = parms;
	  int all_parameters_match = 1;
	  int i = 1;
	  Parm *partialparms = Getattr(pi.item, "partialparms");
	  Parm *pp = partialparms;
	  String *templcsymname = Getattr(pi.item, "templcsymname");
	  if (template_debug) {
	    Printf(stdout, "    checking match: '%s' (partial specialization)\n", templcsymname);
	  }
	  if (ParmList_len(partialparms) == parms_len) {
	    while (p && pp) {
	      SwigType *t;
	      sprintf(tmp, "$%d", i);
	      t = Getattr(p, "type");
	      if (!t)
		t = Getattr(p, "value");
	      if (t) {
		EMatch match = does_parm_match(t, Getattr(pp, "type"), tmp, tscope, priorities_row + i - 1);
		if (match < (int)PartiallySpecializedMatch) {
		  all_parameters_match = 0;
		  break;
		}
	      }
	      i++;
	      p = nextSibling(p);
	      pp = nextSibling(pp);
	    }
	    if (all_parameters_match) {
	      Append(possiblepartials, pi.item);
	      priorities_row += parms_len;
	    }
	  }
	}
      }
    }

    posslen = Len(possiblepartials);
    if (template_debug) {
      int i;
      if (posslen == 0)
	Printf(stdout, "    matched partials: NONE\n");
      else if (posslen == 1)
	Printf(stdout, "    chosen partial: '%s'\n", Getattr(Getitem(possiblepartials, 0), "templcsymname"));
      else {
	Printf(stdout, "    possibly matched partials:\n");
	for (i = 0; i < posslen; i++) {
	  Printf(stdout, "      '%s'\n", Getattr(Getitem(possiblepartials, i), "templcsymname"));
	}
      }
    }

    if (posslen > 1) {
      /* Now go through all the possibly matched partial specialization templates and look for a non-ambiguous match.
       * Exact matches rank the highest and deduced parameters are ranked by how specialized they are, eg looking for
       * a match to const int *, the following rank (highest to lowest):
       *   const int * (exact match)
       *   const T *
       *   T *
       *   T
       *
       *   An ambiguous example when attempting to match as either specialization could match: %template() X<int *, double *>;
       *   template<typename T1, typename T2> X class {};  // primary template
       *   template<typename T1> X<T1, double *> class {}; // specialization (1)
       *   template<typename T2> X<int *, T2> class {};    // specialization (2)
       */
      if (template_debug) {
	int row, col;
	int parms_len = ParmList_len(parms);
	Printf(stdout, "      parameter priorities matrix (%d parms):\n", parms_len);
	for (row = 0; row < posslen; row++) {
	  int *priorities_row = priorities_matrix + row*parms_len;
	  Printf(stdout, "        ");
	  for (col = 0; col < parms_len; col++) {
	    Printf(stdout, "%5d ", priorities_row[col]);
	  }
	  Printf(stdout, "\n");
	}
      }
      {
	int row, col;
	int parms_len = ParmList_len(parms);
	/* Printf(stdout, "      parameter priorities inverse matrix (%d parms):\n", parms_len); */
	for (col = 0; col < parms_len; col++) {
	  int *priorities_col = priorities_matrix + col;
	  int maxpriority = -1;
	  /* 
	     Printf(stdout, "max_possible_partials: %d col:%d\n", max_possible_partials, col);
	     Printf(stdout, "        ");
	     */
	  /* determine the highest rank for this nth parameter */
	  for (row = 0; row < posslen; row++) {
	    int *element_ptr = priorities_col + row*parms_len;
	    int priority = *element_ptr;
	    if (priority > maxpriority)
	      maxpriority = priority;
	    /* Printf(stdout, "%5d ", priority); */
	  }
	  /* Printf(stdout, "\n"); */
	  /* flag all the parameters which equal the highest rank */
	  for (row = 0; row < posslen; row++) {
	    int *element_ptr = priorities_col + row*parms_len;
	    int priority = *element_ptr;
	    *element_ptr = (priority >= maxpriority) ? 1 : 0;
	  }
	}
      }
      {
	int row, col;
	int parms_len = ParmList_len(parms);
	Iterator pi = First(possiblepartials);
	Node *chosenpartials = NewList();
	if (template_debug)
	  Printf(stdout, "      priority flags matrix:\n");
	for (row = 0; row < posslen; row++) {
	  int *priorities_row = priorities_matrix + row*parms_len;
	  int highest_count = 0; /* count of highest priority parameters */
	  for (col = 0; col < parms_len; col++) {
	    highest_count += priorities_row[col];
	  }
	  if (template_debug) {
	    Printf(stdout, "        ");
	    for (col = 0; col < parms_len; col++) {
	      Printf(stdout, "%5d ", priorities_row[col]);
	    }
	    Printf(stdout, "\n");
	  }
	  if (highest_count == parms_len) {
	    Append(chosenpartials, pi.item);
	  }
	  pi = Next(pi);
	}
	if (Len(chosenpartials) > 0) {
	  /* one or more best match found */
	  Delete(possiblepartials);
	  possiblepartials = chosenpartials;
	  posslen = Len(possiblepartials);
	} else {
	  /* no best match found */
	  Delete(chosenpartials);
	}
      }
    }

    if (posslen > 0) {
      String *s = Getattr(Getitem(possiblepartials, 0), "templcsymname");
      n = Swig_symbol_clookup_local(s, primary_scope);
      if (posslen > 1) {
	int i;
	if (n) {
	  Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname));
	  Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), "  instantiation '%s' used,\n", SwigType_namestr(Getattr(n, "name")));
	}
	for (i = 1; i < posslen; i++) {
	  String *templcsymname = Getattr(Getitem(possiblepartials, i), "templcsymname");
	  Node *ignored_node = Swig_symbol_clookup_local(templcsymname, primary_scope);
	  assert(ignored_node);
	  Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(ignored_node), Getline(ignored_node), "  instantiation '%s' ignored.\n", SwigType_namestr(Getattr(ignored_node, "name")));
	}
      }
    }

    if (!n) {
      if (template_debug) {
	Printf(stdout, "    chosen primary template: '%s'\n", Getattr(templ, "name"));
      }
      n = templ;
    }
  } else {
    if (template_debug) {
      Printf(stdout, "    primary template not found\n");
    }
    /* Give up if primary (unspecialized) template not found as specializations will only exist if there is a primary template */
    n = 0;
  }

  if (!n) {
    Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
  } else if (n) {
    String *nodeType = nodeType(n);
    if (!Equal(nodeType, "template")) {
      Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType);
      n = 0;
    }
  }
success:
  Delete(tname);
  Delete(possiblepartials);
  if ((template_debug) && (n)) {
    /*
    Printf(stdout, "Node: %p\n", n);
    Swig_print_node(n);
    */
    Printf(stdout, "    chosen template:'%s'\n", Getattr(n, "name"));
  }
  Delete(parms);
  free(priorities_matrix);
  return n;
}
Ejemplo n.º 24
0
String *SwigType_rcaststr(const SwigType *s, const_String_or_char_ptr name) {
  String *result, *cast;
  String *element = 0;
  String *nextelement;
  String *forwardelement;
  SwigType *td, *tc = 0;
  const SwigType *rs;
  List *elements;
  int nelements, i;
  int clear = 1;
  int firstarray = 1;
  int isreference = 0;
  int isfunction = 0;

  result = NewStringEmpty();

  if (SwigType_isconst(s)) {
    tc = Copy(s);
    Delete(SwigType_pop(tc));
    rs = tc;
  } else {
    rs = s;
  }

  if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs))) {
    td = 0;
  } else {
    td = SwigType_typedef_resolve(rs);
  }

  if (td) {
    if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
      elements = SwigType_split(td);
    } else {
      elements = SwigType_split(rs);
    }
    Delete(td);
  } else {
    elements = SwigType_split(rs);
  }
  nelements = Len(elements);
  if (nelements > 0) {
    element = Getitem(elements, 0);
  }
  /* Now, walk the type list and start emitting */
  for (i = 0; i < nelements; i++) {
    if (i < (nelements - 1)) {
      nextelement = Getitem(elements, i + 1);
      forwardelement = nextelement;
      if (SwigType_isqualifier(nextelement)) {
	if (i < (nelements - 2))
	  forwardelement = Getitem(elements, i + 2);
      }
    } else {
      nextelement = 0;
      forwardelement = 0;
    }
    if (SwigType_isqualifier(element)) {
      DOH *q = 0;
      q = SwigType_parm(element);
      Insert(result, 0, " ");
      Insert(result, 0, q);
      Delete(q);
      clear = 0;
    } else if (SwigType_ispointer(element)) {
      Insert(result, 0, "*");
      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
      firstarray = 0;
    } else if (SwigType_ismemberpointer(element)) {
      String *q;
      Insert(result, 0, "::*");
      q = SwigType_parm(element);
      Insert(result, 0, q);
      Delete(q);
      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
      firstarray = 0;
    } else if (SwigType_isreference(element)) {
      Insert(result, 0, "&");
      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
      if (!isfunction)
	isreference = 1;
    } else if (SwigType_isarray(element)) {
      DOH *size;
      if (firstarray && !isreference) {
	Append(result, "(*)");
	firstarray = 0;
      } else {
	Append(result, "[");
	size = SwigType_parm(element);
	Append(result, size);
	Append(result, "]");
	Delete(size);
	clear = 0;
      }
    } else if (SwigType_isfunction(element)) {
      DOH *parms, *p;
      int j, plen;
      Append(result, "(");
      parms = SwigType_parmlist(element);
      plen = Len(parms);
      for (j = 0; j < plen; j++) {
	p = SwigType_str(Getitem(parms, j), 0);
	Append(result, p);
	Delete(p);
	if (j < (plen - 1))
	  Append(result, ",");
      }
      Append(result, ")");
      Delete(parms);
      isfunction = 1;
    } else {
      String *bs = SwigType_namestr(element);
      Insert(result, 0, " ");
      Insert(result, 0, bs);
      Delete(bs);
    }
    element = nextelement;
  }
  Delete(elements);
  if (clear) {
    cast = NewStringEmpty();
  } else {
    cast = NewStringf("(%s)", result);
  }
  if (name) {
    if (isreference) {
      Append(cast, "*");
    }
    Append(cast, name);
  }
  Delete(result);
  Delete(tc);
  return cast;
}
Ejemplo n.º 25
0
SwigType *SwigType_ltype(const SwigType *s) {
  String *result;
  String *element;
  SwigType *td, *tc = 0;
  List *elements;
  int nelements, i;
  int firstarray = 1;
  int notypeconv = 0;

  result = NewStringEmpty();
  tc = Copy(s);
  /* Nuke all leading qualifiers */
  while (SwigType_isqualifier(tc)) {
    Delete(SwigType_pop(tc));
  }
  if (SwigType_issimple(tc)) {
    /* Resolve any typedef definitions */
    SwigType *tt = Copy(tc);
    td = 0;
    while ((td = SwigType_typedef_resolve(tt))) {
      if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
	/* We need to use the typedef type */
	Delete(tt);
	tt = td;
	break;
      } else if (td) {
	Delete(tt);
	tt = td;
      }
    }
    if (td) {
      Delete(tc);
      tc = td;
    }
  }
  elements = SwigType_split(tc);
  nelements = Len(elements);

  /* Now, walk the type list and start emitting */
  for (i = 0; i < nelements; i++) {
    element = Getitem(elements, i);
    /* when we see a function, we need to preserve the following types */
    if (SwigType_isfunction(element)) {
      notypeconv = 1;
    }
    if (SwigType_isqualifier(element)) {
      /* Do nothing. Ignore */
    } else if (SwigType_ispointer(element)) {
      Append(result, element);
      firstarray = 0;
    } else if (SwigType_ismemberpointer(element)) {
      Append(result, element);
      firstarray = 0;
    } else if (SwigType_isreference(element)) {
      if (notypeconv) {
	Append(result, element);
      } else {
	Append(result, "p.");
      }
      firstarray = 0;
    } else if (SwigType_isarray(element) && firstarray) {
      if (notypeconv) {
	Append(result, element);
      } else {
	Append(result, "p.");
      }
      firstarray = 0;
    } else if (SwigType_isenum(element)) {
      int anonymous_enum = (Cmp(element, "enum ") == 0);
      if (notypeconv || !anonymous_enum) {
	Append(result, element);
      } else {
	Append(result, "int");
      }
    } else {
      Append(result, element);
    }
  }
  Delete(elements);
  Delete(tc);
  return result;
}
Ejemplo n.º 26
0
String *SwigType_str(const SwigType *s, const_String_or_char_ptr id) {
  String *result;
  String *element = 0;
  String *nextelement;
  String *forwardelement;
  List *elements;
  int nelements, i;

  if (id) {
    /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */
    String *id_str = NewString(id); /* unfortunate copy due to current const limitations */
    result = SwigType_str(id_str, 0);
    Delete(id_str);
  } else {
    result = NewStringEmpty();
  }

  elements = SwigType_split(s);
  nelements = Len(elements);

  if (nelements > 0) {
    element = Getitem(elements, 0);
  }
  /* Now, walk the type list and start emitting */
  for (i = 0; i < nelements; i++) {
    if (i < (nelements - 1)) {
      nextelement = Getitem(elements, i + 1);
      forwardelement = nextelement;
      if (SwigType_isqualifier(nextelement)) {
	if (i < (nelements - 2))
	  forwardelement = Getitem(elements, i + 2);
      }
    } else {
      nextelement = 0;
      forwardelement = 0;
    }
    if (SwigType_isqualifier(element)) {
      DOH *q = 0;
      q = SwigType_parm(element);
      Insert(result, 0, " ");
      Insert(result, 0, q);
      Delete(q);
    } else if (SwigType_ispointer(element)) {
      Insert(result, 0, "*");
      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
    } else if (SwigType_ismemberpointer(element)) {
      String *q;
      q = SwigType_parm(element);
      Insert(result, 0, "::*");
      Insert(result, 0, q);
      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
      Delete(q);
    } else if (SwigType_isreference(element)) {
      Insert(result, 0, "&");
      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
	Insert(result, 0, "(");
	Append(result, ")");
      }
    } else if (SwigType_isarray(element)) {
      DOH *size;
      Append(result, "[");
      size = SwigType_parm(element);
      Append(result, size);
      Append(result, "]");
      Delete(size);
    } else if (SwigType_isfunction(element)) {
      DOH *parms, *p;
      int j, plen;
      Append(result, "(");
      parms = SwigType_parmlist(element);
      plen = Len(parms);
      for (j = 0; j < plen; j++) {
	p = SwigType_str(Getitem(parms, j), 0);
	Append(result, p);
	if (j < (plen - 1))
	  Append(result, ",");
      }
      Append(result, ")");
      Delete(parms);
    } else {
      if (strcmp(Char(element), "v(...)") == 0) {
	Insert(result, 0, "...");
      } else {
	String *bs = SwigType_namestr(element);
	Insert(result, 0, " ");
	Insert(result, 0, bs);
	Delete(bs);
      }
    }
    element = nextelement;
  }
  Delete(elements);
  Chop(result);
  return result;
}
Ejemplo n.º 27
0
void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
  String *nt;
  int i, ilen;
  List *elem;

  if (!Strstr(t, pat))
    return;

  if (Equal(t, pat)) {
    Replace(t, pat, rep, DOH_REPLACE_ANY);
    return;
  }
  nt = NewStringEmpty();
  elem = SwigType_split(t);
  ilen = Len(elem);
  for (i = 0; i < ilen; i++) {
    String *e = Getitem(elem, i);
    if (SwigType_issimple(e)) {
      if (Equal(e, pat)) {
	/* Replaces a type of the form 'pat' with 'rep<args>' */
	Replace(e, pat, rep, DOH_REPLACE_ANY);
      } else if (SwigType_istemplate(e)) {
	/* Replaces a type of the form 'pat<args>' with 'rep' */
	if (Equal(e, pat)) {
	  String *repbase = SwigType_templateprefix(rep);
	  Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
	  Delete(repbase);
	}
	{
	  String *tsuffix;
	  List *tparms = SwigType_parmlist(e);
	  int j, jlen;
	  String *nt = SwigType_templateprefix(e);
	  Append(nt, "<(");
	  jlen = Len(tparms);
	  for (j = 0; j < jlen; j++) {
	    SwigType_typename_replace(Getitem(tparms, j), pat, rep);
	    Append(nt, Getitem(tparms, j));
	    if (j < (jlen - 1))
	      Putc(',', nt);
	  }
	  tsuffix = SwigType_templatesuffix(e);
	  Printf(nt, ")>%s", tsuffix);
	  Delete(tsuffix);
	  Clear(e);
	  Append(e, nt);
	  Delete(nt);
	  Delete(tparms);
	}
      } else if (Swig_scopename_check(e)) {
	String *first, *rest;
	first = Swig_scopename_first(e);
	rest = Swig_scopename_suffix(e);
	SwigType_typename_replace(rest, pat, rep);
	SwigType_typename_replace(first, pat, rep);
	Clear(e);
	Printv(e, first, "::", rest, NIL);
	Delete(first);
	Delete(rest);
      }
    } else if (SwigType_isfunction(e)) {
      int j, jlen;
      List *fparms = SwigType_parmlist(e);
      Clear(e);
      Append(e, "f(");
      jlen = Len(fparms);
      for (j = 0; j < jlen; j++) {
	SwigType_typename_replace(Getitem(fparms, j), pat, rep);
	Append(e, Getitem(fparms, j));
	if (j < (jlen - 1))
	  Putc(',', e);
      }
      Append(e, ").");
      Delete(fparms);
    } else if (SwigType_isarray(e)) {
      Replace(e, pat, rep, DOH_REPLACE_ID);
    }
    Append(nt, e);
  }
  Clear(t);
  Append(t, nt);
  Delete(nt);
  Delete(elem);
}