Skeleton of the new types system is in place and compiles
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@158 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
89a2de4614
commit
2f8d8b22d5
2 changed files with 509 additions and 27 deletions
|
|
@ -145,7 +145,6 @@ static DohObjInfo SuperType =
|
|||
Super_str, /* doh_str */
|
||||
Super_data, /* doh_data */
|
||||
Super_dump, /* doh_dump */
|
||||
0, /* doh_load */
|
||||
Super_len, /* doh_len */
|
||||
Super_hash, /* doh_hash */
|
||||
Super_cmp, /* doh_cmp */
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
* complex, as it uses a tree structure internally to cache
|
||||
* already-represented types and avoid the need to allocate an
|
||||
* entire DOH object every time a type object is created.
|
||||
*
|
||||
* While this library is designed to handle C types, it should be
|
||||
* sufficiently general to handle most system-level langages.
|
||||
*
|
||||
* Author(s) : Dustin Mitchell (djmitche@cs.uchicago.edu)
|
||||
*
|
||||
|
|
@ -71,26 +74,35 @@ static char cvstag[] = "$Header$";
|
|||
/* Base types
|
||||
|
||||
Base types have no parent (with one exception; see *), and can be
|
||||
const or volatile. Width specifies the length in bits of an
|
||||
integral type, and the length in bits of the mantissa of a Float.
|
||||
Exp_width specifies the width of the exponent in a float type.
|
||||
Name specifies the name of a Name type, as well as the optional tag
|
||||
for an Enum or Struct. Attributes specifies the indirect
|
||||
attributes of a type. For Enums, this is the optional list of
|
||||
defined names and their values. For Structs, this is an optional
|
||||
list of the types and names of the members.
|
||||
const or volatile (that is, 'is_const' and 'is_volatile' are
|
||||
relevant). 'width' specifies the length in bits of an integral or
|
||||
character (e.g. wchar) type, and the length in bits of the mantissa
|
||||
of a Float. 'exp_width' specifies the width of the exponent in a
|
||||
float type. Only ints can be signed or unsigned (i.e. their
|
||||
'is_signed' and 'is_unsigned' are relevant) (N.B.: the axiom of the
|
||||
excluded middle does not apply here: an integer, an unsigned
|
||||
integer, and a signed integer are distinct types). 'name' specifies
|
||||
the name of a Name type, as well as the optional tag for an Enum or
|
||||
Struct. 'attributes' specifies the indirect attributes of a type.
|
||||
For Enums, this is the optional list of defined names and their
|
||||
values. For Structs, this is an optional list of the types and
|
||||
names of the members. Structs also have a 'subtype' to
|
||||
differentiate structs from unions.
|
||||
|
||||
Note: it is up to the parser to distinguish character types
|
||||
(i.e. those containing ASCII data) from 8-bit integer types, most
|
||||
likely using some simple heuristics.
|
||||
|
||||
(*) If a Name's underlying type is known, then its child field
|
||||
points to that type. */
|
||||
|
||||
#define Swig_Type_Int 1
|
||||
#define Swig_Type_UInt 2
|
||||
#define Swig_Type_Float 3
|
||||
#define Swig_Type_Void 4
|
||||
#define Swig_Type_Char 5
|
||||
#define Swig_Type_Name 6
|
||||
#define Swig_Type_Enum 7
|
||||
#define Swig_Type_Struct 8
|
||||
#define Swig_Type_Float 2
|
||||
#define Swig_Type_Void 3
|
||||
#define Swig_Type_Char 4
|
||||
#define Swig_Type_Name 5
|
||||
#define Swig_Type_Enum 6
|
||||
#define Swig_Type_Struct 7
|
||||
|
||||
/* Constructors
|
||||
|
||||
|
|
@ -109,26 +121,50 @@ static char cvstag[] = "$Header$";
|
|||
A Struct may either be a Struct or a Union -- since SWIG handles
|
||||
them similarly, this is considered a subtype. */
|
||||
|
||||
#define Swig_Subtype_Struct 81
|
||||
#define Swig_Subtype_Union 82
|
||||
#define Swig_Subtype_Struct 1
|
||||
#define Swig_Subtype_Union 2
|
||||
|
||||
/* (for results of comparisons) */
|
||||
|
||||
#define TAGS_EQ 0
|
||||
#define TAGS_NEQ 1
|
||||
|
||||
/* =========================================================================
|
||||
* structure definitions
|
||||
* ========================================================================= */
|
||||
/* These are both DOH types so that we can hash them. The first
|
||||
(Swig_Type_tag) is a completely internal DOH type, while the second
|
||||
is the publicly exported DOH type. */
|
||||
|
||||
typedef struct Swig_Type_tag
|
||||
{
|
||||
short type, subtype;
|
||||
DOH *name, *attributes;
|
||||
DOHCOMMON;
|
||||
|
||||
short type;
|
||||
short subtype;
|
||||
DOH *name;
|
||||
DOH **attributes;
|
||||
short width;
|
||||
short exp_width;
|
||||
int is_const : 1;
|
||||
int is_volatile : 1;
|
||||
int is_signed : 1;
|
||||
int is_unsigned : 1;
|
||||
|
||||
int hashkey;
|
||||
} Swig_Type_tag;
|
||||
|
||||
typedef DOH *Swig_Type_children;
|
||||
typedef DOH *Swig_Type_children; /* a DOH Hash */
|
||||
|
||||
typedef struct Swig_Type_node
|
||||
{
|
||||
Swig_Type_tag type;
|
||||
DOHCOMMON;
|
||||
|
||||
Swig_Type_tag *tag;
|
||||
struct Swig_Type_node *parent;
|
||||
Swig_Type_hash children;
|
||||
Swig_Type_children children;
|
||||
|
||||
int hashkey;
|
||||
} Swig_Type_node;
|
||||
|
||||
/* =========================================================================
|
||||
|
|
@ -140,15 +176,93 @@ typedef struct Swig_Type_node
|
|||
static Swig_Type_children Swig_Type_root;
|
||||
|
||||
/* =========================================================================
|
||||
* utility function prototypes
|
||||
* utility function declarations
|
||||
* ========================================================================= */
|
||||
|
||||
/* Take one step down into the children, creating a new node if
|
||||
necessary. */
|
||||
static Swig_Type_node *
|
||||
Swig_Type_step(Swig_Type_hash children, Swig_Type_tag *tag);
|
||||
Swig_Type_step(Swig_Type_node *parent, Swig_Type_children children,
|
||||
Swig_Type_tag *tag);
|
||||
|
||||
/* Functions to support hashing on Swig_Type_tag objects */
|
||||
/* Make sure that this is a real DOH string, not a (char *). */
|
||||
static DOH *
|
||||
Swig_Type_make_string(DOH *in);
|
||||
|
||||
/* the smallest n such that i < 2**n */
|
||||
static int Swig_Type_bit_count(unsigned int i);
|
||||
|
||||
/* =========================================================================
|
||||
* Swig_Type_tag DOH type declaration
|
||||
* ========================================================================= */
|
||||
|
||||
static DOH *
|
||||
Swig_Type_tag_new(short type, short subtype,
|
||||
DOH *name, DOH *attributes,
|
||||
int width, int exp_width,
|
||||
int is_const, int is_volatile,
|
||||
int is_signed, int is_unsigned);
|
||||
|
||||
static DOH *Swig_Type_tag_str(DOH *o); /* e.g. 'pointer to' */
|
||||
static int Swig_Type_tag_hash(DOH *o);
|
||||
static int Swig_Type_tag_cmp(DOH *o1, DOH *o2);
|
||||
#define TagData(x) ((Swig_Type_tag *)(x))
|
||||
|
||||
static DohObjInfo Swig_Type_tag_Type =
|
||||
{
|
||||
"TypeTag", /* objname */
|
||||
sizeof(Swig_Type_tag), /* objsize */
|
||||
0, /* doh_del -- will never happen */
|
||||
0, /* doh_copy */
|
||||
0, /* doh_clear */
|
||||
0, /* doh_scope */
|
||||
Swig_Type_tag_str, /* doh_str */
|
||||
0, /* doh_data */
|
||||
0, /* doh_dump */
|
||||
0, /* doh_len */
|
||||
Swig_Type_tag_hash, /* doh_hash */
|
||||
Swig_Type_tag_cmp, /* doh_cmp */
|
||||
0, /* doh_mapping */
|
||||
0, /* doh_sequence */
|
||||
0, /* doh_file */
|
||||
0, /* doh_string */
|
||||
0, /* doh_callable */
|
||||
0, /* doh_position */
|
||||
};
|
||||
|
||||
/* =========================================================================
|
||||
* Swig_Type_node DOH type declaration
|
||||
* ========================================================================= */
|
||||
|
||||
static DOH *Swig_Type_node_new(DOH *tag, DOH *parent);
|
||||
|
||||
static DOH *Swig_Type_node_str(DOH *o); /* e.g. 'pointer to array (10)
|
||||
of pointer to char'' */
|
||||
static int Swig_Type_node_hash(DOH *o);
|
||||
static int Swig_Type_node_cmp(DOH *o, DOH *o2);
|
||||
#define NodeData(x) ((Swig_Type_node *)(x))
|
||||
|
||||
static DohObjInfo Swig_Type_node_Type =
|
||||
{
|
||||
"Type", /* objname */
|
||||
sizeof(Swig_Type_node), /* objsize */
|
||||
0, /* doh_del -- will never happen */
|
||||
0, /* doh_copy */
|
||||
0, /* doh_clear */
|
||||
0, /* doh_scope */
|
||||
Swig_Type_node_str, /* doh_str */
|
||||
0, /* doh_data */
|
||||
0, /* doh_dump */
|
||||
0, /* doh_len */
|
||||
Swig_Type_node_hash, /* doh_hash */
|
||||
Swig_Type_node_cmp, /* doh_cmp */
|
||||
0, /* doh_mapping */
|
||||
0, /* doh_sequence */
|
||||
0, /* doh_file */
|
||||
0, /* doh_string */
|
||||
0, /* doh_callable */
|
||||
0, /* doh_position */
|
||||
};
|
||||
|
||||
/* =========================================================================
|
||||
* utility functions
|
||||
|
|
@ -156,8 +270,377 @@ Swig_Type_step(Swig_Type_hash children, Swig_Type_tag *tag);
|
|||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static Swig_Type_node *
|
||||
* Swig_Type_step(Swig_Type_hash children, Swig_Type_tag *tag);
|
||||
* Swig_Type_step(Swig_Type_children children, Swig_Type_tag *tag);
|
||||
* -------------------------------------------------------------------------
|
||||
* Take a step down the tree, creating a new node if necessary, and
|
||||
* return a pointer to the node we arrive at.
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static Swig_Type_node *
|
||||
Swig_Type_step(Swig_Type_node *parent, Swig_Type_children children,
|
||||
Swig_Type_tag *tag)
|
||||
{
|
||||
DOH *subnode = Getattr(children, tag);
|
||||
if (!subnode) {
|
||||
subnode = Swig_Type_node_new(tag, parent);
|
||||
Setattr(children, tag, subnode);
|
||||
}
|
||||
|
||||
return NodeData(subnode);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static DOH *
|
||||
* Swig_Type_make_string(DOH *in);
|
||||
* -------------------------------------------------------------------------
|
||||
* Make sure that this is a real DOH string, not a (char *).
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static DOH *
|
||||
Swig_Type_make_string(DOH *in)
|
||||
{
|
||||
if (String_check(in) || SuperString_check(in))
|
||||
return in;
|
||||
|
||||
/* assume (char *) */
|
||||
if (in)
|
||||
return NewString(in);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static int Swig_Type_bit_count(unsigned int i);
|
||||
* -------------------------------------------------------------------------
|
||||
/* The smallest n such that i < 2**n
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static int Swig_Type_bit_count(unsigned int i)
|
||||
{
|
||||
int n = 0;
|
||||
while (i)
|
||||
n++, i >>= 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* =========================================================================
|
||||
* Swig_Type_tag DOH type implementation
|
||||
* ========================================================================= */
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static DOH *
|
||||
* Swig_Type_tag_new( ... );
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static DOH *
|
||||
Swig_Type_tag_new(short type, short subtype,
|
||||
DOH *name, DOH *attributes,
|
||||
int width, int exp_width,
|
||||
int is_const, int is_volatile,
|
||||
int is_signed, int is_unsigned)
|
||||
{
|
||||
Swig_Type_tag *t;
|
||||
|
||||
t = (Swig_Type_tag *)DohObjMalloc(sizeof(Swig_Type_tag));
|
||||
t->objinfo = &Swig_Type_tag_Type;
|
||||
t->hashkey = -1;
|
||||
t->type = type;
|
||||
t->subtype = subtype;
|
||||
t->name = Swig_Type_make_string(name); if (t->name) Incref(t->name);
|
||||
t->attributes = attributes; if (t->attributes) Incref(t->attributes);
|
||||
t->width = width;
|
||||
t->exp_width = exp_width;
|
||||
t->is_const = is_const;
|
||||
t->is_volatile = is_volatile;
|
||||
t->is_signed = is_signed;
|
||||
t->is_unsigned = is_unsigned;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static DOH *
|
||||
* Swig_Type_tag_str(DOH *o);
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static DOH *Swig_Type_tag_str(DOH *o)
|
||||
{
|
||||
return o, "tag_str";
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static int
|
||||
* Swig_Type_tag_hash(DOH *o);
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static int Swig_Type_tag_hash(DOH *o)
|
||||
{
|
||||
Swig_Type_tag *tag = TagData(o);
|
||||
if (tag->hashkey != -1) return tag->hashkey;
|
||||
|
||||
/* barring the use of any sub-object's Hashval, we assign a
|
||||
different integer to each of our types. */
|
||||
switch (tag->type)
|
||||
{
|
||||
/* base types are assigned certain numbers */
|
||||
case Swig_Type_Int:
|
||||
tag->hashkey =
|
||||
Swig_Type_bit_count(tag->width) +
|
||||
(tag->is_const << 4) +
|
||||
(tag->is_volatile << 5) +
|
||||
(tag->is_signed << 6) +
|
||||
(tag->is_unsigned << 7); /* I wonder what the optimizer will
|
||||
do with this.. */
|
||||
break;
|
||||
case Swig_Type_Float:
|
||||
tag->hashkey =
|
||||
Swig_Type_bit_count(tag->width) +
|
||||
(Swig_Type_bit_count(tag->exp_width) << 4) +
|
||||
(tag->is_const << 8) +
|
||||
(tag->is_volatile << 9) +
|
||||
1 << 10;
|
||||
break;
|
||||
case Swig_Type_Void:
|
||||
tag->hashkey =
|
||||
Swig_Type_bit_count(tag->width) +
|
||||
(tag->is_const << 4) +
|
||||
(tag->is_volatile << 5) +
|
||||
(tag->is_signed << 6) +
|
||||
(tag->is_unsigned << 7) +
|
||||
2 << 10;
|
||||
break;
|
||||
case Swig_Type_Char:
|
||||
tag->hashkey =
|
||||
Swig_Type_bit_count(tag->width) +
|
||||
(tag->is_const << 4) +
|
||||
(tag->is_volatile << 5) +
|
||||
(tag->is_signed << 6) +
|
||||
(tag->is_unsigned << 7) +
|
||||
3 << 10;
|
||||
break;
|
||||
case Swig_Type_Name:
|
||||
tag->hashkey =
|
||||
Hashval(tag->name);
|
||||
break;
|
||||
case Swig_Type_Enum:
|
||||
tag->hashkey =
|
||||
(tag->name) ? Hashval(tag->name) : 0 +
|
||||
(tag->attributes) ? Hashval(tag->attributes) : 0 +
|
||||
5 << 10;
|
||||
break;
|
||||
case Swig_Type_Struct:
|
||||
tag->hashkey =
|
||||
(tag->name) ? Hashval(tag->name) : 0 +
|
||||
(tag->attributes) ? Hashval(tag->attributes) : 0 +
|
||||
6 << 10 +
|
||||
tag->subtype << 20;
|
||||
break;
|
||||
case Swig_Type_Array:
|
||||
tag->hashkey =
|
||||
(tag->attributes) ? Hashval(tag->attributes) : 0 +
|
||||
7 << 10;
|
||||
break;
|
||||
case Swig_Type_Function:
|
||||
tag->hashkey =
|
||||
(tag->attributes) ? Hashval(tag->attributes) : 0 +
|
||||
8 << 10;
|
||||
break;
|
||||
case Swig_Type_Pointer:
|
||||
tag->hashkey =
|
||||
(tag->is_const << 8) +
|
||||
(tag->is_volatile << 9) +
|
||||
9 << 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
tag->hashkey =
|
||||
tag->type;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tag->hashkey == -1) tag->hashkey = 1;
|
||||
return tag->hashkey;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static int
|
||||
* Swig_Type_tag_cmp(DOH *o1, DOH *o2);
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static int Swig_Type_tag_cmp(DOH *o1, DOH *o2)
|
||||
{
|
||||
Swig_Type_tag *t1, *t2;
|
||||
t1 = TagData(o1);
|
||||
t2 = TagData(o2);
|
||||
|
||||
/* we define only equal or not equal, as that's all we need to hash
|
||||
types. */
|
||||
|
||||
if (t1 == t2)
|
||||
return TAGS_EQ;
|
||||
|
||||
if (t1->type != t2->type)
|
||||
return TAGS_NEQ;
|
||||
|
||||
switch (t1->type)
|
||||
{
|
||||
case Swig_Type_Int:
|
||||
if (t1->width != t2->width ||
|
||||
t1->is_const != t2->is_const ||
|
||||
t1->is_volatile != t2->is_volatile ||
|
||||
t1->is_unsigned != t2->is_unsigned ||
|
||||
t1->is_signed != t2->is_signed)
|
||||
return TAGS_NEQ;
|
||||
break;
|
||||
case Swig_Type_Float:
|
||||
if (t1->width != t2->width ||
|
||||
t1->exp_width != t2->exp_width ||
|
||||
t1->is_const != t2->is_const ||
|
||||
t1->is_volatile != t2->is_volatile)
|
||||
return TAGS_NEQ;
|
||||
break;
|
||||
case Swig_Type_Void:
|
||||
break; /* nothing to it.. */
|
||||
case Swig_Type_Char:
|
||||
if (t1->width != t2->width ||
|
||||
t1->is_const != t2->is_const ||
|
||||
t1->is_volatile != t2->is_volatile)
|
||||
return TAGS_NEQ;
|
||||
break;
|
||||
case Swig_Type_Name:
|
||||
return Cmp(t1->name, t2->name);
|
||||
case Swig_Type_Struct:
|
||||
if (t1->subtype != t2->subtype)
|
||||
return TAGS_NEQ;
|
||||
/* fall through */
|
||||
case Swig_Type_Enum:
|
||||
/* do the names differ? */
|
||||
if (t1->name && t2->name)
|
||||
{
|
||||
if (Cmp(t1->name, t2->name))
|
||||
return TAGS_NEQ;
|
||||
else if (t1->attributes && t2->attributes)
|
||||
return Cmp(t1->attributes, t2->attributes);
|
||||
else if (t1->attributes || t2->attributes)
|
||||
/* both named, only one has attributes... */
|
||||
return TAGS_NEQ;
|
||||
else
|
||||
/* both named, neither has attributes */
|
||||
return TAGS_EQ;
|
||||
}
|
||||
else if (t1->name || t2->name)
|
||||
/* one named, one not */
|
||||
return TAGS_NEQ;
|
||||
else
|
||||
{
|
||||
/* neither named -- structural equivalence */
|
||||
if (t1->attributes && t2->attributes)
|
||||
return Cmp(t1->attributes, t2->attributes);
|
||||
else
|
||||
/* this should never happen .. */
|
||||
return TAGS_NEQ;
|
||||
}
|
||||
case Swig_Type_Array:
|
||||
if (t1->attributes && t2->attributes)
|
||||
return Cmp(t1->attributes, t2->attributes);
|
||||
else if (t1->attributes || t2->attributes)
|
||||
return TAGS_NEQ;
|
||||
else
|
||||
return TAGS_EQ;
|
||||
case Swig_Type_Function:
|
||||
return Cmp(t1->attributes, t2->attributes);
|
||||
case Swig_Type_Pointer:
|
||||
if (t1->is_volatile != t2->is_volatile ||
|
||||
t1->is_const != t2->is_const)
|
||||
return TAGS_NEQ;
|
||||
break;
|
||||
default:
|
||||
return TAGS_NEQ;
|
||||
}
|
||||
|
||||
/* fall through -> equal */
|
||||
return TAGS_EQ;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static DOH *
|
||||
* Swig_Type_node_new(DOH *tag, DOH *parent);
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static DOH *
|
||||
Swig_Type_node_new(DOH *tag, DOH *parent)
|
||||
{
|
||||
Swig_Type_node *n;
|
||||
|
||||
n = (Swig_Type_node *)DohObjMalloc(sizeof(Swig_Type_node));
|
||||
n->objinfo = &Swig_Type_node_Type;
|
||||
|
||||
n->parent = parent;
|
||||
n->tag = tag;
|
||||
n->children = NewHash();
|
||||
n->hashkey = -1;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static DOH *
|
||||
* Swig_Type_node_str(DOH *o);
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static DOH *
|
||||
Swig_Type_node_str(DOH *o)
|
||||
{
|
||||
Swig_Type_node *n = (Swig_Type_node *)o;
|
||||
DOH *s = NewString("");
|
||||
if (n->parent)
|
||||
Printf(s, "%s %s", n->tag, n->parent);
|
||||
else
|
||||
return Str(n->tag);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static int
|
||||
* Swig_Type_node_hash(DOH *o);
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
Swig_Type_node_hash(DOH *o)
|
||||
{
|
||||
Swig_Type_node *n = (Swig_Type_node *)o;
|
||||
if (n->hashkey != -1) return n->hashkey;
|
||||
|
||||
n->hashkey = Hashval(n->tag);
|
||||
if (n->parent)
|
||||
n->hashkey += Hashval(n->parent);
|
||||
|
||||
if (n->hashkey == -1) n->hashkey = 1;
|
||||
|
||||
return n->hashkey;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* static int
|
||||
* Swig_Type_node_cmp(DOH *o1, DOH *o2);
|
||||
* ------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
Swig_Type_node_cmp(DOH *o1, DOH *o2)
|
||||
{
|
||||
Swig_Type_node *n1 = (Swig_Type_node *)o1;
|
||||
Swig_Type_node *n2 = (Swig_Type_node *)o1;
|
||||
|
||||
/* we call the comparison functions directly just to shave a hair
|
||||
off the execution time */
|
||||
|
||||
if (Swig_Type_tag_cmp(n1->tag, n2->tag))
|
||||
return TAGS_NEQ;
|
||||
|
||||
else if (n1->parent && n2->parent)
|
||||
return Swig_Type_node_cmp(n1->parent, n2->parent);
|
||||
|
||||
else if (n1->parent || n2->parent)
|
||||
return TAGS_NEQ;
|
||||
else
|
||||
return TAGS_EQ;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue