[svn-r13451]

h5diff bug fix, attributes differences were not being count for total
differences

Revision of H5Ocopy call in h5repack
This commit is contained in:
Pedro Vicente Nunes 2007-03-05 11:26:50 -05:00
parent 44f312b183
commit bd01f34589
12 changed files with 976 additions and 1158 deletions

View File

@ -160,7 +160,7 @@ fi
# copy files (these files have no filters)
TOOLTEST $FILE0
TOOLTEST $FILE1
#TOOLTEST $FILE2
TOOLTEST $FILE2
TOOLTEST $FILE3
TOOLTEST $FILE4
TOOLTEST $FILE5

View File

@ -556,6 +556,10 @@ int do_copy_objects(hid_t fidin,
/* create property to pass copy options */
if ( (pid = H5Pcreate(H5P_OBJECT_COPY)) < 0)
goto error;
/* set options for object copy */
if(H5Pset_copy_object(pid, H5O_COPY_WITHOUT_ATTR_FLAG) < 0)
goto error;
/*-------------------------------------------------------------------------
* do the copy
@ -573,6 +577,23 @@ int do_copy_objects(hid_t fidin,
/* close property */
if (H5Pclose(pid)<0)
goto error;
/*-------------------------------------------------------------------------
* copy attrs manually
*-------------------------------------------------------------------------
*/
if ((dset_in=H5Dopen(fidin,travt->objs[i].name))<0)
goto error;
if ((dset_out=H5Dopen(fidout,travt->objs[i].name))<0)
goto error;
if (copy_attr(dset_in,dset_out,options)<0)
goto error;
if (H5Dclose(dset_in)<0)
goto error;
if (H5Dclose(dset_out)<0)
goto error;
} /* end do we have request for filter/chunking */
@ -978,812 +999,3 @@ static void print_dataset_info(hid_t dcpl_id,
#if 0
/*-------------------------------------------------------------------------
* Function: do_hardlinks
*
* Purpose: duplicate hard links
*
* Return: 0, ok, -1 no
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: December, 10, 2003
*
*-------------------------------------------------------------------------
*/
static
int do_hardlinks(hid_t fidout,trav_table_t *travt)
{
unsigned int i, j;
for ( i = 0; i < travt->nobjs; i++)
{
switch ( travt->objs[i].type )
{
case H5G_GROUP:
if (travt->objs[i].nlinks)
{
for ( j=0; j<travt->objs[i].nlinks; j++)
{
if (H5Glink(fidout,
H5L_TYPE_HARD,
travt->objs[i].name,
travt->objs[i].links[j].new_name)<0)
return -1;
}
}
break;
case H5G_DATASET:
if (travt->objs[i].nlinks)
{
for ( j=0; j<travt->objs[i].nlinks; j++){
if (H5Glink(fidout,
H5L_TYPE_HARD,
travt->objs[i].name,
travt->objs[i].links[j].new_name)<0)
return -1;
}
}
break;
case H5G_TYPE:
case H5G_LINK:
case H5G_UDLINK:
/*nothing to do */
break;
default:
break;
}
}
return 0;
}
/*-------------------------------------------------------------------------
* Function: do_copy_refobjs
*
* Purpose: duplicate all referenced HDF5 objects in the file in a second traversal
*
* Return: 0, ok, -1 no
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: December, 10, 2003
*
*-------------------------------------------------------------------------
*/
static
int do_copy_refobjs(hid_t fidin,
hid_t fidout,
trav_table_t *travt,
pack_opt_t *options) /* repack options */
{
hid_t grp_in=-1; /* read group ID */
hid_t grp_out=-1; /* write group ID */
hid_t dset_in=-1; /* read dataset ID */
hid_t dset_out=-1; /* write dataset ID */
hid_t type_in=-1; /* named type ID */
hid_t dcpl_id=-1; /* dataset creation property list ID */
hid_t space_id=-1; /* space ID */
hid_t ftype_id=-1; /* file type ID */
hid_t wtype_id=-1; /* read/write type ID */
size_t msize; /* size of type */
hsize_t nelmts; /* number of elements in dataset */
int rank; /* rank of dataset */
hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
int next; /* external files */
unsigned i;
int j;
/*-------------------------------------------------------------------------
* browse
*-------------------------------------------------------------------------
*/
for ( i = 0; i < travt->nobjs; i++)
{
switch ( travt->objs[i].type )
{
case H5G_GROUP:
break;
/*-------------------------------------------------------------------------
* H5G_DATASET
*-------------------------------------------------------------------------
*/
case H5G_DATASET:
if ((dset_in=H5Dopen(fidin,travt->objs[i].name))<0)
goto error;
if ((space_id=H5Dget_space(dset_in))<0)
goto error;
if ((ftype_id=H5Dget_type (dset_in))<0)
goto error;
if ((dcpl_id=H5Dget_create_plist(dset_in))<0)
goto error;
if ( (rank=H5Sget_simple_extent_ndims(space_id))<0)
goto error;
if ( H5Sget_simple_extent_dims(space_id,dims,NULL)<0)
goto error;
nelmts=1;
for (j=0; j<rank; j++)
nelmts*=dims[j];
if (options->use_native==1)
wtype_id = h5tools_get_native_type(ftype_id);
else
wtype_id = H5Tcopy(ftype_id);
if ((msize=H5Tget_size(wtype_id))==0)
goto error;
/*-------------------------------------------------------------------------
* check for external files
*-------------------------------------------------------------------------
*/
if ((next=H5Pget_external_count (dcpl_id))<0)
goto error;
/*-------------------------------------------------------------------------
* check if the dataset creation property list has filters that
* are not registered in the current configuration
* 1) the external filters GZIP and SZIP might not be available
* 2) the internal filters might be turned off
*-------------------------------------------------------------------------
*/
if (next==0 && h5tools_canreadf((NULL),dcpl_id)==1)
{
/*-------------------------------------------------------------------------
* test for a valid output dataset
*-------------------------------------------------------------------------
*/
dset_out = FAIL;
/*-------------------------------------------------------------------------
* object references are a special case
* we cannot just copy the buffers, but instead we recreate the reference
*-------------------------------------------------------------------------
*/
if (H5Tequal(wtype_id, H5T_STD_REF_OBJ))
{
H5G_obj_t obj_type;
hid_t refobj_id;
hobj_ref_t *refbuf=NULL; /* buffer for object references */
hobj_ref_t *buf=NULL;
const char* refname;
unsigned u;
/*-------------------------------------------------------------------------
* read to memory
*-------------------------------------------------------------------------
*/
if (nelmts)
{
buf=(void *) HDmalloc((unsigned)(nelmts*msize));
if ( buf==NULL){
error_msg(progname, "cannot read into memory\n" );
goto error;
}
if (H5Dread(dset_in,wtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf)<0)
goto error;
if ((obj_type = H5Rget_obj_type(dset_in,H5R_OBJECT,buf))<0)
goto error;
refbuf=HDmalloc((unsigned)nelmts*msize);
if ( refbuf==NULL){
error_msg(progname, "cannot allocate memory\n" );
goto error;
}
for ( u=0; u<nelmts; u++)
{
H5E_BEGIN_TRY {
if ((refobj_id = H5Rdereference(dset_in,H5R_OBJECT,&buf[u]))<0)
continue;
} H5E_END_TRY;
/* get the name. a valid name could only occur in the
second traversal of the file */
if ((refname=MapIdToName(refobj_id,travt))!=NULL)
{
/* create the reference, -1 parameter for objects */
if (H5Rcreate(&refbuf[u],fidout,refname,H5R_OBJECT,-1)<0)
goto error;
if (options->verbose)
printf("object <%s> object reference created to <%s>\n",
travt->objs[i].name,
refname);
}/*refname*/
close_obj(obj_type,refobj_id);
}/* u */
}/*nelmts*/
/*-------------------------------------------------------------------------
* create/write dataset/close
*-------------------------------------------------------------------------
*/
if ((dset_out=H5Dcreate(fidout,travt->objs[i].name,wtype_id,space_id,dcpl_id))<0)
goto error;
if (nelmts) {
if (H5Dwrite(dset_out,wtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,refbuf)<0)
goto error;
}
if (buf)
free(buf);
if (refbuf)
free(refbuf);
}/*H5T_STD_REF_OBJ*/
/*-------------------------------------------------------------------------
* dataset region references
*-------------------------------------------------------------------------
*/
else if (H5Tequal(wtype_id, H5T_STD_REF_DSETREG))
{
H5G_obj_t obj_type;
hid_t refobj_id;
hdset_reg_ref_t *refbuf=NULL; /* input buffer for region references */
hdset_reg_ref_t *buf=NULL; /* output buffer */
const char* refname;
unsigned u;
/*-------------------------------------------------------------------------
* read input to memory
*-------------------------------------------------------------------------
*/
if (nelmts)
{
buf=(void *) HDmalloc((unsigned)(nelmts*msize));
if ( buf==NULL){
error_msg(progname, "cannot read into memory\n" );
goto error;
}
if (H5Dread(dset_in,wtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,buf)<0)
goto error;
if ((obj_type = H5Rget_obj_type(dset_in,H5R_DATASET_REGION,buf))<0)
goto error;
/*-------------------------------------------------------------------------
* create output
*-------------------------------------------------------------------------
*/
refbuf=HDcalloc(sizeof(hdset_reg_ref_t),(size_t)nelmts); /*init to zero */
if ( refbuf==NULL){
error_msg(progname, "cannot allocate memory\n" );
goto error;
}
for ( u=0; u<nelmts; u++)
{
H5E_BEGIN_TRY {
if ((refobj_id = H5Rdereference(dset_in,H5R_DATASET_REGION,&buf[u]))<0)
continue;
} H5E_END_TRY;
/* get the name. a valid name could only occur in the
second traversal of the file */
if ((refname=MapIdToName(refobj_id,travt))!=NULL)
{
hid_t region_id; /* region id of the referenced dataset */
if ((region_id = H5Rget_region(dset_in,H5R_DATASET_REGION,&buf[u]))<0)
goto error;
/* create the reference, we need the space_id */
if (H5Rcreate(&refbuf[u],fidout,refname,H5R_DATASET_REGION,region_id)<0)
goto error;
if (H5Sclose(region_id)<0)
goto error;
if (options->verbose)
printf("object <%s> region reference created to <%s>\n",
travt->objs[i].name,
refname);
}/*refname*/
close_obj(obj_type,refobj_id);
}/* u */
}/*nelmts*/
/*-------------------------------------------------------------------------
* create/write dataset/close
*-------------------------------------------------------------------------
*/
if ((dset_out=H5Dcreate(fidout,travt->objs[i].name,wtype_id,space_id,dcpl_id))<0)
goto error;
if (nelmts) {
if (H5Dwrite(dset_out,wtype_id,H5S_ALL,H5S_ALL,H5P_DEFAULT,refbuf)<0)
goto error;
}
if (buf)
free(buf);
if (refbuf)
free(refbuf);
} /* H5T_STD_REF_DSETREG */
/*-------------------------------------------------------------------------
* not references, open previously created object in 1st traversal
*-------------------------------------------------------------------------
*/
else
{
if ((dset_out=H5Dopen(fidout,travt->objs[i].name))<0)
goto error;
}
assert(dset_out!=FAIL);
/*-------------------------------------------------------------------------
* copy referenced objects in attributes
*-------------------------------------------------------------------------
*/
if (copy_refs_attr(dset_in,dset_out,options,travt,fidout)<0)
goto error;
if (H5Dclose(dset_out)<0)
goto error;
}/*can_read*/
/*-------------------------------------------------------------------------
* close
*-------------------------------------------------------------------------
*/
if (H5Tclose(ftype_id)<0)
goto error;
if (H5Tclose(wtype_id)<0)
goto error;
if (H5Pclose(dcpl_id)<0)
goto error;
if (H5Sclose(space_id)<0)
goto error;
if (H5Dclose(dset_in)<0)
goto error;
break;
case H5G_TYPE:
case H5G_LINK:
case H5G_UDLINK:
/*nothing to do */
break;
default:
break;
}
}
/*-------------------------------------------------------------------------
* the root is a special case, we get an ID for the root group
* and copy its attributes using that ID
* it must be done last, because the attributes might contain references to
* objects in the object list
*-------------------------------------------------------------------------
*/
if ((grp_out = H5Gopen(fidout,"/"))<0)
goto error;
if ((grp_in = H5Gopen(fidin,"/"))<0)
goto error;
if (copy_refs_attr(grp_in,grp_out,options,travt,fidout)<0)
goto error;
if (H5Gclose(grp_out)<0)
goto error;
if (H5Gclose(grp_in)<0)
goto error;
return 0;
error:
H5E_BEGIN_TRY {
H5Gclose(grp_in);
H5Gclose(grp_out);
H5Pclose(dcpl_id);
H5Sclose(space_id);
H5Dclose(dset_in);
H5Dclose(dset_out);
H5Tclose(ftype_id);
H5Tclose(wtype_id);
H5Tclose(type_in);
} H5E_END_TRY;
return -1;
}
/*-------------------------------------------------------------------------
* Function: copy_refs_attr
*
* Purpose: duplicate all referenced HDF5 objects located in attributes
* relative to LOC_IN, which is obtained either from
* loc_id = H5Gopen( fid, name);
* loc_id = H5Dopen( fid, name);
* loc_id = H5Topen( fid, name);
*
* Return: 0, ok, -1 no
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: October, 28, 2003
*
*-------------------------------------------------------------------------
*/
static int copy_refs_attr(hid_t loc_in,
hid_t loc_out,
pack_opt_t *options,
trav_table_t *travt,
hid_t fidout /* for saving references */
)
{
hid_t attr_id=-1; /* attr ID */
hid_t attr_out=-1; /* attr ID */
hid_t space_id=-1; /* space ID */
hid_t ftype_id=-1; /* file type ID */
hid_t wtype_id=-1; /* read/write type ID */
size_t msize; /* size of type */
hsize_t nelmts; /* number of elements in dataset */
int rank; /* rank of dataset */
hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
char name[255];
int n, j;
unsigned u;
if ((n = H5Aget_num_attrs(loc_in))<0)
goto error;
for ( u = 0; u < (unsigned)n; u++)
{
/*-------------------------------------------------------------------------
* open
*-------------------------------------------------------------------------
*/
/* open attribute */
if ((attr_id = H5Aopen_idx(loc_in, u))<0)
goto error;
/* get name */
if (H5Aget_name( attr_id, 255, name )<0)
goto error;
/* get the file datatype */
if ((ftype_id = H5Aget_type( attr_id )) < 0 )
goto error;
/* get the dataspace handle */
if ((space_id = H5Aget_space( attr_id )) < 0 )
goto error;
/* get dimensions */
if ( (rank = H5Sget_simple_extent_dims(space_id, dims, NULL)) < 0 )
goto error;
/*-------------------------------------------------------------------------
* elements
*-------------------------------------------------------------------------
*/
nelmts=1;
for (j=0; j<rank; j++)
nelmts*=dims[j];
if (options->use_native==1)
wtype_id = h5tools_get_native_type(ftype_id);
else
wtype_id = H5Tcopy(ftype_id);
if ((msize=H5Tget_size(wtype_id))==0)
goto error;
/*-------------------------------------------------------------------------
* object references are a special case
* we cannot just copy the buffers, but instead we recreate the reference
*-------------------------------------------------------------------------
*/
if (H5Tequal(wtype_id, H5T_STD_REF_OBJ))
{
H5G_obj_t obj_type;
hid_t refobj_id;
hobj_ref_t *refbuf=NULL;
unsigned k;
const char* refname;
hobj_ref_t *buf=NULL;
/*-------------------------------------------------------------------------
* read input to memory
*-------------------------------------------------------------------------
*/
if (nelmts)
{
buf=(void *) HDmalloc((unsigned)(nelmts*msize));
if ( buf==NULL){
error_msg(progname, "cannot read into memory\n" );
goto error;
}
if (H5Aread(attr_id,wtype_id,buf)<0)
goto error;
if ((obj_type = H5Rget_obj_type(attr_id,H5R_OBJECT,buf))<0)
goto error;
refbuf=HDmalloc((unsigned)nelmts*msize);
if ( refbuf==NULL){
error_msg(progname, "cannot allocate memory\n" );
goto error;
}
for ( k=0; k<nelmts; k++)
{
H5E_BEGIN_TRY {
if ((refobj_id = H5Rdereference(attr_id,H5R_OBJECT,&buf[k]))<0)
goto error;
} H5E_END_TRY;
/* get the name. a valid name could only occur in the
second traversal of the file */
if ((refname=MapIdToName(refobj_id,travt))!=NULL)
{
/* create the reference */
if (H5Rcreate(&refbuf[k],fidout,refname,H5R_OBJECT,-1)<0)
goto error;
if (options->verbose)
printf("object <%s> reference created to <%s>\n",name,refname);
}
close_obj(obj_type,refobj_id);
}/* k */
}/*nelmts*/
/*-------------------------------------------------------------------------
* copy
*-------------------------------------------------------------------------
*/
if ((attr_out=H5Acreate(loc_out,name,ftype_id,space_id,H5P_DEFAULT))<0)
goto error;
if (nelmts) {
if(H5Awrite(attr_out,wtype_id,refbuf)<0)
goto error;
}
if (H5Aclose(attr_out)<0)
goto error;
if (refbuf)
free(refbuf);
if (buf)
free(buf);
}/*H5T_STD_REF_OBJ*/
/*-------------------------------------------------------------------------
* dataset region references
*-------------------------------------------------------------------------
*/
else if (H5Tequal(wtype_id, H5T_STD_REF_DSETREG))
{
H5G_obj_t obj_type;
hid_t refobj_id;
hdset_reg_ref_t *refbuf=NULL; /* input buffer for region references */
hdset_reg_ref_t *buf=NULL; /* output buffer */
const char* refname;
unsigned k;
/*-------------------------------------------------------------------------
* read input to memory
*-------------------------------------------------------------------------
*/
if (nelmts)
{
buf=(void *) HDmalloc((unsigned)(nelmts*msize));
if ( buf==NULL){
error_msg(progname, "cannot read into memory\n" );
goto error;
}
if (H5Aread(attr_id,wtype_id,buf)<0)
goto error;
if ((obj_type = H5Rget_obj_type(attr_id,H5R_DATASET_REGION,buf))<0)
goto error;
/*-------------------------------------------------------------------------
* create output
*-------------------------------------------------------------------------
*/
refbuf=HDcalloc(sizeof(hdset_reg_ref_t),(size_t)nelmts); /*init to zero */
if ( refbuf==NULL){
error_msg(progname, "cannot allocate memory\n" );
goto error;
}
for ( k=0; k<nelmts; k++)
{
H5E_BEGIN_TRY {
if ((refobj_id = H5Rdereference(attr_id,H5R_DATASET_REGION,&buf[k]))<0)
continue;
} H5E_END_TRY;
/* get the name. a valid name could only occur in the
second traversal of the file */
if ((refname=MapIdToName(refobj_id,travt))!=NULL)
{
hid_t region_id; /* region id of the referenced dataset */
if ((region_id = H5Rget_region(attr_id,H5R_DATASET_REGION,&buf[k]))<0)
goto error;
/* create the reference, we need the space_id */
if (H5Rcreate(&refbuf[k],fidout,refname,H5R_DATASET_REGION,region_id)<0)
goto error;
if (H5Sclose(region_id)<0)
goto error;
if (options->verbose)
printf("object <%s> region reference created to <%s>\n",name,refname);
}
close_obj(obj_type,refobj_id);
}/* k */
}/*nelmts */
/*-------------------------------------------------------------------------
* copy
*-------------------------------------------------------------------------
*/
if ((attr_out=H5Acreate(loc_out,name,ftype_id,space_id,H5P_DEFAULT))<0)
goto error;
if (nelmts) {
if(H5Awrite(attr_out,wtype_id,refbuf)<0)
goto error;
}
if (H5Aclose(attr_out)<0)
goto error;
if (refbuf)
free(refbuf);
if (buf)
free(buf);
} /* H5T_STD_REF_DSETREG */
/*-------------------------------------------------------------------------
* close
*-------------------------------------------------------------------------
*/
if (H5Tclose(ftype_id)<0) goto error;
if (H5Tclose(wtype_id)<0) goto error;
if (H5Sclose(space_id)<0) goto error;
if (H5Aclose(attr_id)<0) goto error;
} /* u */
return 0;
error:
H5E_BEGIN_TRY {
H5Tclose(ftype_id);
H5Tclose(wtype_id);
H5Sclose(space_id);
H5Aclose(attr_id);
H5Aclose(attr_out);
} H5E_END_TRY;
return -1;
}
/*-------------------------------------------------------------------------
* Function: close_obj
*
* Purpose: Auxiliary function to close an object
*
*-------------------------------------------------------------------------
*/
static void close_obj(H5G_obj_t obj_type, hid_t obj_id)
{
H5E_BEGIN_TRY
{
switch (obj_type)
{
case H5G_GROUP:
H5Gclose(obj_id);
break;
case H5G_DATASET:
H5Dclose(obj_id);
break;
case H5G_TYPE:
H5Tclose(obj_id);
break;
default:
break;
}
} H5E_END_TRY;
}
/*-------------------------------------------------------------------------
* Function: MapIdToName
*
* Purpose: map an object ID to a name
*
*-------------------------------------------------------------------------
*/
static const char* MapIdToName(hid_t refobj_id,
trav_table_t *travt)
{
hid_t id;
hid_t fid;
H5G_stat_t refstat; /* Stat for the refobj id */
H5G_stat_t objstat; /* Stat for objects in the file */
unsigned int i;
/* obtain information to identify the referenced object uniquely */
if(H5Gget_objinfo(refobj_id, ".", 0, &refstat) <0)
return NULL;
/* obtains the file ID given an object ID. This ID must be closed */
if ((fid = H5Iget_file_id(refobj_id))<0)
{
return NULL;
}
/* linear search */
for ( i=0; i<travt->nobjs; i++)
{
switch ( travt->objs[i].type )
{
default:
break;
/*-------------------------------------------------------------------------
* H5G_DATASET
*-------------------------------------------------------------------------
*/
case H5G_DATASET:
if ((id = H5Dopen(fid,travt->objs[i].name))<0)
return NULL;
if(H5Gget_objinfo(id, ".", 0, &objstat) <0)
return NULL;
if (H5Dclose(id)<0)
return NULL;
if (!HDmemcmp(&refstat.fileno, &objstat.fileno, sizeof(refstat.fileno)) && !HDmemcmp(&refstat.objno, &objstat.objno, sizeof(refstat.objno)))
{
H5Fclose(fid);
return travt->objs[i].name;
}
break;
} /* switch */
} /* i */
if (H5Fclose(fid)<0)
return NULL;
return NULL;
}
#endif

View File

@ -1,3 +1,4 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
@ -20,18 +21,14 @@
#include "H5private.h"
#include "h5repack.h"
static const char* MapIdToName(hid_t refobj_id,
trav_table_t *travt);
/*-------------------------------------------------------------------------
* local functions
*-------------------------------------------------------------------------
*/
static void close_obj(H5G_obj_t obj_type, hid_t obj_id);
static int copy_refs_attr(hid_t loc_in,
hid_t loc_out,
pack_opt_t *options,
trav_table_t *travt,
hid_t fidout /* for saving references */
);
static const char* MapIdToName(hid_t refobj_id,trav_table_t *travt);
static void close_obj(H5G_obj_t1 obj_type, hid_t obj_id);
static int copy_refs_attr(hid_t loc_in,hid_t loc_out,pack_opt_t *options,trav_table_t *travt,hid_t fidout);
/*-------------------------------------------------------------------------
* Function: do_copy_refobjs
@ -62,12 +59,13 @@ int do_copy_refobjs(hid_t fidin,
hid_t space_id=(-1); /* space ID */
hid_t ftype_id=(-1); /* file data type ID */
hid_t mtype_id=(-1); /* memory data type ID */
size_t msize; /* memory size of memory type */
hsize_t nelmts; /* number of elements in dataset */
int rank; /* rank of dataset */
hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
int next; /* external files */
unsigned i, j;
size_t msize; /* memory size of memory type */
hsize_t nelmts; /* number of elements in dataset */
int rank; /* rank of dataset */
hsize_t dims[H5S_MAX_RANK]; /* dimensions of dataset */
int next; /* external files */
unsigned int i, j;
int k;
/*-------------------------------------------------------------------------
* browse
@ -143,8 +141,8 @@ int do_copy_refobjs(hid_t fidin,
if ( H5Sget_simple_extent_dims(space_id,dims,NULL)<0)
goto error;
nelmts=1;
for (j=0; j<rank; j++)
nelmts*=dims[j];
for (k=0; k<rank; k++)
nelmts*=dims[k];
if ((mtype_id=h5tools_get_native_type(ftype_id))<0)
goto error;
@ -180,7 +178,7 @@ int do_copy_refobjs(hid_t fidin,
*/
if (H5Tequal(mtype_id, H5T_STD_REF_OBJ))
{
H5G_obj_t obj_type;
H5G_obj_t1 obj_type;
hid_t refobj_id;
hobj_ref_t *refbuf=NULL; /* buffer for object references */
hobj_ref_t *buf=NULL;
@ -255,7 +253,7 @@ int do_copy_refobjs(hid_t fidin,
*/
else if (H5Tequal(mtype_id, H5T_STD_REF_DSETREG))
{
H5G_obj_t obj_type;
H5G_obj_t1 obj_type;
hid_t refobj_id;
hdset_reg_ref_t *refbuf=NULL; /* input buffer for region references */
hdset_reg_ref_t *buf=NULL; /* output buffer */
@ -350,8 +348,10 @@ int do_copy_refobjs(hid_t fidin,
* copy referenced objects in attributes
*-------------------------------------------------------------------------
*/
#if 1
if (copy_refs_attr(dset_in,dset_out,options,travt,fidout)<0)
goto error;
#endif
/*-------------------------------------------------------------------------
@ -489,14 +489,14 @@ static int copy_refs_attr(hid_t loc_in,
hid_t fidout /* for saving references */
)
{
hid_t attr_id=-1; /* attr ID */
hid_t attr_out=-1; /* attr ID */
hid_t space_id=-1; /* space ID */
hid_t ftype_id=-1; /* file data type ID */
hid_t mtype_id=-1; /* memory data type ID */
size_t msize; /* memory size of type */
hsize_t nelmts; /* number of elements in dataset */
int rank; /* rank of dataset */
hid_t attr_id=-1; /* attr ID */
hid_t attr_out=-1; /* attr ID */
hid_t space_id=-1; /* space ID */
hid_t ftype_id=-1; /* file data type ID */
hid_t mtype_id=-1; /* memory data type ID */
size_t msize; /* memory size of type */
hsize_t nelmts; /* number of elements in dataset */
int rank; /* rank of dataset */
hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
char name[255];
int n, j;
@ -554,7 +554,7 @@ static int copy_refs_attr(hid_t loc_in,
*/
if (H5Tequal(mtype_id, H5T_STD_REF_OBJ))
{
H5G_obj_t obj_type;
H5G_obj_t1 obj_type;
hid_t refobj_id;
hobj_ref_t *refbuf=NULL;
unsigned k;
@ -631,7 +631,7 @@ static int copy_refs_attr(hid_t loc_in,
*/
else if (H5Tequal(mtype_id, H5T_STD_REF_DSETREG))
{
H5G_obj_t obj_type;
H5G_obj_t1 obj_type;
hid_t refobj_id;
hdset_reg_ref_t *refbuf=NULL; /* input buffer for region references */
hdset_reg_ref_t *buf=NULL; /* output buffer */
@ -734,14 +734,14 @@ error:
}
/*-------------------------------------------------------------------------
* Function: close_obj
* Function: close_obj
*
* Purpose: Auxiliary function to close an object
* Purpose: Auxiliary function to close an object
*
*-------------------------------------------------------------------------
*/
static void close_obj(H5G_obj_t obj_type, hid_t obj_id)
static void close_obj(H5G_obj_t1 obj_type, hid_t obj_id)
{
H5E_BEGIN_TRY
{
@ -761,6 +761,7 @@ static void close_obj(H5G_obj_t obj_type, hid_t obj_id)
}
} H5E_END_TRY;
}
/*-------------------------------------------------------------------------
* Function: MapIdToName
*
@ -772,11 +773,11 @@ static void close_obj(H5G_obj_t obj_type, hid_t obj_id)
static const char* MapIdToName(hid_t refobj_id,
trav_table_t *travt)
{
hid_t id;
hid_t fid;
H5G_stat_t refstat; /* Stat for the refobj id */
H5G_stat_t objstat; /* Stat for objects in the file */
int i;
hid_t id;
hid_t fid;
H5G_stat_t refstat; /* Stat for the refobj id */
H5G_stat_t objstat; /* Stat for objects in the file */
unsigned int i;
/* obtain information to identify the referenced object uniquely */
if(H5Gget_objinfo(refobj_id, ".", 0, &refstat) <0)
@ -825,3 +826,5 @@ static const char* MapIdToName(hid_t refobj_id,
return NULL;
}

View File

@ -160,6 +160,8 @@ int main (void)
*-------------------------------------------------------------------------
*/
#if 0
/*-------------------------------------------------------------------------
* file with fill values
*-------------------------------------------------------------------------
@ -198,11 +200,12 @@ int main (void)
GOERROR;
PASSED();
#endif
/*-------------------------------------------------------------------------
* file with attributes
*-------------------------------------------------------------------------
*/
#if 0
TESTING(" copy of datasets (attributes)");
if (h5repack_init (&pack_options, 0)<0)
GOERROR;
@ -217,7 +220,6 @@ int main (void)
if (h5repack_end (&pack_options)<0)
GOERROR;
PASSED();
#endif
/*-------------------------------------------------------------------------
* file with hardlinks
@ -3541,7 +3543,7 @@ void write_attr_in(hid_t loc_id,
{
status=H5Rcreate(&buf4[0],fid,dset_name,H5R_OBJECT,-1);
status=H5Rcreate(&buf4[1],fid,dset_name,H5R_OBJECT,-1);
make_attr(loc_id,1,dims,"reference to object",H5T_STD_REF_OBJ,buf4);
make_attr(loc_id,1,dims,"reference",H5T_STD_REF_OBJ,buf4);
}

View File

@ -882,11 +882,10 @@ hsize_t diff_compare (hid_t file1_id,
*
* Purpose: switch between types and choose the diff function
* TYPE is either
* H5G_GROUP Object is a group
* H5G_DATASET Object is a dataset
* H5G_TYPE Object is a named data type
* H5G_LINK Object is a symbolic link
* H5G_UDLINK Object is a user-defined link
* H5G_GROUP Object is a group
* H5G_DATASET Object is a dataset
* H5G_TYPE Object is a named data type
* H5G_LINK Object is a symbolic link
*
* Return: Number of differences found
*
@ -899,301 +898,301 @@ hsize_t diff_compare (hid_t file1_id,
hsize_t diff (hid_t file1_id,
const char *path1,
hid_t file2_id,
const char *path2,
diff_opt_t * options,
H5G_obj_t type)
hid_t file2_id,
const char *path2,
diff_opt_t * options,
H5G_obj_t1 type)
{
hid_t type1_id=(-1);
hid_t type2_id=(-1);
hid_t grp1_id=(-1);
hid_t grp2_id=(-1);
int ret;
H5G_stat_t sb1;
H5G_stat_t sb2;
hsize_t nfound=0;
switch (type)
{
/*-------------------------------------------------------------------------
* H5G_DATASET
*-------------------------------------------------------------------------
*/
case H5G_DATASET:
/*-------------------------------------------------------------------------
* verbose, always print name
*-------------------------------------------------------------------------
*/
if (options->m_verbose)
{
if (print_objname (options, (hsize_t)1))
do_print_objname ("dataset", path1, path2);
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
/* always print the number of differences found */
print_found(nfound);
}
/*-------------------------------------------------------------------------
* non verbose, check first if we have differences
*-------------------------------------------------------------------------
*/
else
{
if (options->m_quiet == 0)
{
/* shut up temporarily */
options->m_quiet = 1;
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
/* print again */
options->m_quiet = 0;
if (nfound)
hid_t type1_id=(-1);
hid_t type2_id=(-1);
hid_t grp1_id=(-1);
hid_t grp2_id=(-1);
int ret;
H5G_stat_t sb1;
H5G_stat_t sb2;
hsize_t nfound = 0;
switch (type)
{
if (print_objname (options, nfound))
do_print_objname ("dataset", path1, path2);
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
/* print the number of differences found only when found
this is valid for the default mode and report mode */
print_found(nfound);
} /*if nfound */
} /*if quiet */
/*-------------------------------------------------------------------------
* quiet mode, just count differences
*-------------------------------------------------------------------------
*/
else
{
nfound = diff_dataset (file1_id, file2_id, path1, path2, options);
}
} /*else verbose */
break;
/*-------------------------------------------------------------------------
* H5G_TYPE
*-------------------------------------------------------------------------
*/
case H5G_TYPE:
if ((type1_id = H5Topen (file1_id, path1)) < 0)
goto out;
if ((type2_id = H5Topen (file2_id, path2)) < 0)
goto out;
if ((ret = H5Tequal (type1_id, type2_id)) < 0)
goto out;
/* if H5Tequal is > 0 then the datatypes refer to the same datatype */
nfound = (ret > 0) ? 0 : 1;
if (print_objname (options, nfound))
do_print_objname ("datatype", path1, path2);
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
/*-------------------------------------------------------------------------
* compare attributes
* the if condition refers to cases when the dataset is a referenced object
*-------------------------------------------------------------------------
*/
if (path1)
diff_attr (type1_id, type2_id, path1, path2, options);
if (H5Tclose (type1_id) < 0)
goto out;
if (H5Tclose (type2_id) < 0)
goto out;
break;
/*-------------------------------------------------------------------------
* H5G_GROUP
*-------------------------------------------------------------------------
*/
case H5G_GROUP:
if ((grp1_id = H5Gopen (file1_id, path1)) < 0)
goto out;
if ((grp2_id = H5Gopen (file2_id, path2)) < 0)
goto out;
ret = HDstrcmp (path1, path2);
/* if "path1" != "path2" then the groups are "different" */
nfound = (ret != 0) ? 1 : 0;
if (print_objname (options, nfound))
do_print_objname ("group", path1, path2);
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
/*-------------------------------------------------------------------------
* compare attributes
* the if condition refers to cases when the dataset is a referenced object
*-------------------------------------------------------------------------
*/
if (path1)
diff_attr (grp1_id, grp2_id, path1, path2, options);
if (H5Gclose (grp1_id) < 0)
goto out;
if (H5Gclose (grp2_id) < 0)
goto out;
break;
/*-------------------------------------------------------------------------
* H5G_LINK
*-------------------------------------------------------------------------
*/
case H5G_LINK:
{
char *buf1 = NULL;
char *buf2 = NULL;
if (H5Gget_objinfo (file1_id, path1, FALSE, &sb1) < 0)
goto out;
if (H5Gget_objinfo (file1_id, path1, FALSE, &sb2) < 0)
goto out;
buf1 = HDmalloc (sb1.linklen);
buf2 = HDmalloc (sb2.linklen);
if (H5Gget_linkval (file1_id, path1, sb1.linklen, buf1) < 0)
goto out;
if (H5Gget_linkval (file2_id, path2, sb1.linklen, buf2) < 0)
goto out;
ret = HDstrcmp (buf1, buf2);
/* if "buf1" != "buf2" then the links are "different" */
nfound = (ret != 0) ? 1 : 0;
if (print_objname (options, nfound))
do_print_objname ("soft link", path1, path2);
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
HDfree (buf1);
HDfree (buf2);
}
break;
/*-------------------------------------------------------------------------
* H5G_UDLINK
*-------------------------------------------------------------------------
*/
case H5G_UDLINK:
{
char *buf1 = NULL;
char *buf2 = NULL;
H5L_info_t li1;
H5L_info_t li2;
if(H5Lget_info(file1_id, path1, &li1, H5P_DEFAULT) < 0)
goto out;
if(H5Lget_info(file1_id, path1, &li2, H5P_DEFAULT) < 0)
goto out;
/* Only external links will have a query function registered */
if(li1.type == H5L_TYPE_EXTERNAL && li2.type == H5L_TYPE_EXTERNAL)
{
buf1 = HDmalloc (li1.u.val_size);
buf2 = HDmalloc (li2.u.val_size);
if(H5Lget_val(file1_id, path1, buf1, li1.u.val_size, H5P_DEFAULT) < 0)
{
HDfree (buf1); HDfree (buf2);
goto out;
}
if(H5Lget_val(file2_id, path2, buf2, li2.u.val_size, H5P_DEFAULT) < 0)
{
HDfree (buf1); HDfree (buf2);
goto out;
}
/* If the buffers are the same size, compare them */
if(li1.u.val_size == li2.u.val_size)
{
if(H5Lget_val(file1_id, path1, buf1, li1.u.val_size, H5P_DEFAULT) < 0)
/*-------------------------------------------------------------------------
* H5G_DATASET
*-------------------------------------------------------------------------
*/
case H5G_DATASET:
/*-------------------------------------------------------------------------
* verbose, always print name
*-------------------------------------------------------------------------
*/
if (options->m_verbose)
{
HDfree (buf1); HDfree (buf2);
goto out;
if (print_objname(options,(hsize_t)1))
do_print_objname ("dataset", path1, path2);
nfound=diff_dataset(file1_id,file2_id,path1,path2,options);
print_found(nfound);
}
if(H5Lget_val(file2_id, path2, buf2, li2.u.val_size, H5P_DEFAULT) < 0)
/*-------------------------------------------------------------------------
* non verbose, check first if we have differences by enabling quiet mode
* so that printing is off, and compare again if differences found,
* disabling quite mode
*-------------------------------------------------------------------------
*/
else
{
HDfree (buf1); HDfree (buf2);
goto out;
if (options->m_quiet==0)
{
/* shut up temporarily */
options->m_quiet=1;
nfound=diff_dataset(file1_id,file2_id,path1,path2,options);
/* print again */
options->m_quiet=0;
if (nfound)
{
if (print_objname(options,nfound))
do_print_objname ("dataset", path1, path2);
nfound=diff_dataset(file1_id,file2_id,path1,path2,options);
print_found(nfound);
}
}
/* in quiet mode, just count differences */
else
{
nfound=diff_dataset(file1_id,file2_id,path1,path2,options);
}
}
ret = HDmemcmp (buf1, buf2, li1.u.val_size);
}
else
ret = 1;
break;
/*-------------------------------------------------------------------------
* H5G_TYPE
*-------------------------------------------------------------------------
*/
case H5G_TYPE:
/* if "buf1" != "buf2" then the links are "different" */
nfound = (ret != 0) ? 1 : 0;
if ((type1_id = H5Topen(file1_id, path1))<0)
goto out;
if ((type2_id = H5Topen(file2_id, path2))<0)
goto out;
if ((ret = H5Tequal(type1_id,type2_id))<0)
goto out;
/* if H5Tequal is > 0 then the datatypes refer to the same datatype */
nfound = (ret>0) ? 0 : 1;
if (print_objname(options,nfound))
do_print_objname ("datatype", path1, path2);
if (print_objname (options, nfound))
do_print_objname ("external link", path1, path2);
}
else
{
/* If one or both of these links isn't an external link, we can only
* compare information from H5Lget_info since we don't have a query
* function registered for them. */
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
/*-------------------------------------------------------------------------
* compare attributes
* the if condition refers to cases when the dataset is a referenced object
*-------------------------------------------------------------------------
*/
if (path1)
nfound += diff_attr(type1_id,type2_id,path1,path2,options);
if ( H5Tclose(type1_id)<0)
goto out;
if ( H5Tclose(type2_id)<0)
goto out;
break;
/*-------------------------------------------------------------------------
* H5G_GROUP
*-------------------------------------------------------------------------
*/
case H5G_GROUP:
/* If the link classes or the buffer length are not the
* same, the links are "different"
*/
if((li1.type != li2.type) || (li1.u.val_size != li2.u.val_size))
nfound = 1;
else
nfound = 0;
if (print_objname (options, nfound))
do_print_objname ("user defined link", path1, path2);
}
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
HDfree (buf1);
HDfree (buf2);
}
break;
default:
nfound = 0;
if (options->m_verbose)
{
parallel_print("Comparison not supported: <%s> and <%s> are of type %s\n",
path1, path2, get_type (type));
options->not_cmp=1;
}
break;
} /* switch */
ret = HDstrcmp(path1,path2);
/* if "path1" != "path2" then the groups are "different" */
nfound = (ret!=0) ? 1 : 0;
if (print_objname(options,nfound))
do_print_objname ("group", path1, path2);
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
if ((grp1_id = H5Gopen(file1_id, path1))<0)
goto out;
if ((grp2_id = H5Gopen(file2_id, path2))<0)
goto out;
/*-------------------------------------------------------------------------
* compare attributes
* the if condition refers to cases when the dataset is a referenced object
*-------------------------------------------------------------------------
*/
if (path1)
nfound += diff_attr(grp1_id,grp2_id,path1,path2,options);
if ( H5Gclose(grp1_id)<0)
goto out;
if ( H5Gclose(grp2_id)<0)
goto out;
break;
/*-------------------------------------------------------------------------
* H5G_LINK
*-------------------------------------------------------------------------
*/
case H5G_LINK:
{
char *buf1 = NULL;
char *buf2 = NULL;
if (H5Gget_objinfo (file1_id, path1, FALSE, &sb1) < 0)
goto out;
if (H5Gget_objinfo (file1_id, path1, FALSE, &sb2) < 0)
goto out;
buf1 = HDmalloc (sb1.linklen);
buf2 = HDmalloc (sb2.linklen);
if (H5Gget_linkval (file1_id, path1, sb1.linklen, buf1) < 0)
goto out;
if (H5Gget_linkval (file2_id, path2, sb1.linklen, buf2) < 0)
goto out;
ret = HDstrcmp (buf1, buf2);
/* if "buf1" != "buf2" then the links are "different" */
nfound = (ret != 0) ? 1 : 0;
if (print_objname (options, nfound))
do_print_objname ("link", path1, path2);
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
HDfree (buf1);
HDfree (buf2);
}
break;
/*-------------------------------------------------------------------------
* H5G_UDLINK
*-------------------------------------------------------------------------
*/
case H5G_UDLINK:
{
char *buf1 = NULL;
char *buf2 = NULL;
H5L_info_t li1;
H5L_info_t li2;
if(H5Lget_info(file1_id, path1, &li1, H5P_DEFAULT) < 0)
goto out;
if(H5Lget_info(file1_id, path1, &li2, H5P_DEFAULT) < 0)
goto out;
/* Only external links will have a query function registered */
if(li1.type == H5L_TYPE_EXTERNAL && li2.type == H5L_TYPE_EXTERNAL)
{
buf1 = HDmalloc (li1.u.val_size);
buf2 = HDmalloc (li2.u.val_size);
if(H5Lget_val(file1_id, path1, buf1, li1.u.val_size, H5P_DEFAULT) < 0)
{
HDfree (buf1); HDfree (buf2);
goto out;
}
if(H5Lget_val(file2_id, path2, buf2, li2.u.val_size, H5P_DEFAULT) < 0)
{
HDfree (buf1); HDfree (buf2);
goto out;
}
/* If the buffers are the same size, compare them */
if(li1.u.val_size == li2.u.val_size)
{
if(H5Lget_val(file1_id, path1, buf1, li1.u.val_size, H5P_DEFAULT) < 0)
{
HDfree (buf1); HDfree (buf2);
goto out;
}
if(H5Lget_val(file2_id, path2, buf2, li2.u.val_size, H5P_DEFAULT) < 0)
{
HDfree (buf1); HDfree (buf2);
goto out;
}
ret = HDmemcmp (buf1, buf2, li1.u.val_size);
}
else
ret = 1;
/* if "buf1" != "buf2" then the links are "different" */
nfound = (ret != 0) ? 1 : 0;
if (print_objname (options, nfound))
do_print_objname ("external link", path1, path2);
}
else
{
/* If one or both of these links isn't an external link, we can only
* compare information from H5Lget_info since we don't have a query
* function registered for them.
/* If the link classes or the buffer length are not the
* same, the links are "different"
*/
if((li1.type != li2.type) || (li1.u.val_size != li2.u.val_size))
nfound = 1;
else
nfound = 0;
if (print_objname (options, nfound))
do_print_objname ("user defined link", path1, path2);
}
/* always print the number of differences found in verbose mode */
if (options->m_verbose)
print_found(nfound);
HDfree (buf1);
HDfree (buf2);
}
break;
default:
if (options->m_verbose)
{
printf("Comparison not supported: <%s> and <%s> are of type %s\n",
path1, path2, get_type(type) );
}
options->not_cmp=1;
break;
}
return nfound;
out:
options->err_stat=1;
/* close */
/* disable error reporting */
H5E_BEGIN_TRY
{
H5Tclose (type1_id);
H5Tclose (type2_id);
H5Gclose (grp1_id);
H5Tclose (grp2_id);
/* enable error reporting */
H5Tclose (type1_id);
H5Tclose (type2_id);
H5Gclose (grp1_id);
H5Tclose (grp2_id);
/* enable error reporting */
}
H5E_END_TRY;
return nfound;
}

View File

@ -138,12 +138,11 @@ int diff_can_type( hid_t f_type1, /* file data type */
diff_opt_t *options );
int diff_attr(hid_t loc1_id,
hid_t loc2_id,
const char *path1,
const char *path2,
diff_opt_t *options
);
hsize_t diff_attr(hid_t loc1_id,
hid_t loc2_id,
const char *path1,
const char *path2,
diff_opt_t *options);
/*-------------------------------------------------------------------------

View File

@ -26,22 +26,23 @@
* loc_id = H5Dopen( fid, name);
* loc_id = H5Topen( fid, name);
*
* Return:
* 0 : no differences found
* 1 : differences found
* Return: number of differences found
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
* Date: November, 03, 2003
*
* Modifications:
* March, 02, 2007: return the number of differences found
*
*-------------------------------------------------------------------------
*/
int diff_attr(hid_t loc1_id,
hid_t loc2_id,
const char *path1,
const char *path2,
diff_opt_t *options)
hsize_t diff_attr(hid_t loc1_id,
hid_t loc2_id,
const char *path1,
const char *path2,
diff_opt_t *options)
{
hid_t attr1_id=-1; /* attr ID */
hid_t attr2_id=-1; /* attr ID */
@ -65,9 +66,9 @@ int diff_attr(hid_t loc1_id,
char np1[512];
char np2[512];
int n1, n2, i, j;
hsize_t nfound;
hsize_t nfound=0;
hsize_t nfound_total=0;
int cmp=1;
int ret=0;
if ((n1 = H5Aget_num_attrs(loc1_id))<0)
goto error;
@ -95,7 +96,6 @@ int diff_attr(hid_t loc1_id,
{
if ((attr2_id = H5Aopen_name(loc2_id, name1))<0)
{
ret = 1;
goto error;
}
} H5E_END_TRY;
@ -285,9 +285,11 @@ int diff_attr(hid_t loc1_id,
HDfree(buf1);
if (buf2)
HDfree(buf2);
nfound_total += nfound;
} /* i */
return ret;
return nfound_total;
error:
H5E_BEGIN_TRY {
@ -306,7 +308,7 @@ error:
} H5E_END_TRY;
options->err_stat=1;
return ret;
return nfound_total;
}

View File

@ -515,7 +515,8 @@ hsize_t diff_datasetid( hid_t did1,
}
} /* hyperslab read */
}/*cmp*/
/*-------------------------------------------------------------------------
* compare attributes
* the if condition refers to cases when the dataset is a referenced object
@ -523,9 +524,7 @@ hsize_t diff_datasetid( hid_t did1,
*/
if (obj1_name)
diff_attr(did1,did2,obj1_name,obj2_name,options);
}/*cmp*/
nfound += diff_attr(did1,did2,obj1_name,obj2_name,options);
/*-------------------------------------------------------------------------
* close

View File

@ -29,6 +29,9 @@
*-------------------------------------------------------------------------
*/
typedef H5G_obj_t H5G_obj_t1;
typedef struct trav_info_t {
char *name;
H5G_obj_t type;
@ -133,3 +136,5 @@ void trav_table_addlink(trav_table_t *table,
#endif /* H5TRAV_H__ */

View File

@ -1,5 +1,5 @@
#############################
Expected output for 'h5diff h5diff_types.h5 h5diff_types.h5 -v l1 l1'
#############################
soft link: </l1> and </l1>
link : </l1> and </l1>
0 differences found

View File

@ -1,5 +1,5 @@
#############################
Expected output for 'h5diff h5diff_types.h5 h5diff_types.h5 -v l1 l2'
#############################
soft link: </l1> and </l2>
link : </l1> and </l2>
1 differences found

View File

@ -9,7 +9,604 @@ file1 file2
dataset: </dset> and </dset>
</dset> and </dset> are empty datasets
attribute: <string of </dset>> and <string of </dset>>
size: [2] [2]
position string of </dset> string of </dset> difference
------------------------------------------------------------
[ 0 ] a z
[ 0 ] b z
[ 1 ] d z
[ 1 ] e z
4 differences found
attribute: <bitfield of </dset>> and <bitfield of </dset>>
size: [2] [2]
position bitfield of </dset> bitfield of </dset> difference
------------------------------------------------------------
[ 0 ] 1 0 1
[ 1 ] 2 0 2
2 differences found
attribute: <opaque of </dset>> and <opaque of </dset>>
size: [2] [2]
position opaque of </dset> opaque of </dset> difference
------------------------------------------------------------
[ 0 ] 1 0 1
[ 1 ] 2 0 2
2 differences found
attribute: <compound of </dset>> and <compound of </dset>>
size: [2] [2]
position compound of </dset> compound of </dset> difference
------------------------------------------------------------
[ 0 ] 1 0 1
[ 0 ] 2 0 2
[ 1 ] 3 0 3
[ 1 ] 4 0 4
4 differences found
attribute: <reference of </dset>> and <reference of </dset>>
0 differences found
attribute: <enum of </dset>> and <enum of </dset>>
size: [2] [2]
position enum of </dset> enum of </dset> difference
------------------------------------------------------------
[ 0 ] RED GREEN
[ 1 ] RED GREEN
2 differences found
attribute: <vlen of </dset>> and <vlen of </dset>>
size: [2] [2]
position vlen of </dset> vlen of </dset> difference
------------------------------------------------------------
[ 0 ] 1 0 1
[ 1 ] 2 0 2
[ 1 ] 3 0 3
3 differences found
attribute: <array of </dset>> and <array of </dset>>
size: [2] [2]
position array of </dset> array of </dset> difference
------------------------------------------------------------
[ 0 ] 1 0 1
[ 0 ] 2 0 2
[ 0 ] 3 0 3
[ 1 ] 4 0 4
[ 1 ] 5 0 5
[ 1 ] 6 0 6
6 differences found
attribute: <integer of </dset>> and <integer of </dset>>
size: [2] [2]
position integer of </dset> integer of </dset> difference
------------------------------------------------------------
[ 0 ] 1 0 1
[ 1 ] 2 0 2
2 differences found
attribute: <float of </dset>> and <float of </dset>>
size: [2] [2]
position float of </dset> float of </dset> difference
------------------------------------------------------------
[ 0 ] 1 0 1
[ 1 ] 2 0 2
2 differences found
attribute: <string2D of </dset>> and <string2D of </dset>>
size: [3x2] [3x2]
position string2D of </dset> string2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] a z
[ 0 0 ] b z
[ 0 1 ] c z
[ 0 1 ] d z
[ 1 0 ] e z
[ 1 0 ] f z
[ 1 1 ] g z
[ 1 1 ] h z
[ 2 0 ] i z
[ 2 0 ] j z
[ 2 1 ] k z
[ 2 1 ] l z
12 differences found
attribute: <bitfield2D of </dset>> and <bitfield2D of </dset>>
size: [3x2] [3x2]
position bitfield2D of </dset> bitfield2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] 1 0 1
[ 0 1 ] 2 0 2
[ 1 0 ] 3 0 3
[ 1 1 ] 4 0 4
[ 2 0 ] 5 0 5
[ 2 1 ] 6 0 6
6 differences found
attribute: <opaque2D of </dset>> and <opaque2D of </dset>>
size: [3x2] [3x2]
position opaque2D of </dset> opaque2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] 1 0 1
[ 0 1 ] 2 0 2
[ 1 0 ] 3 0 3
[ 1 1 ] 4 0 4
[ 2 0 ] 5 0 5
[ 2 1 ] 6 0 6
6 differences found
attribute: <compound2D of </dset>> and <compound2D of </dset>>
size: [3x2] [3x2]
position compound2D of </dset> compound2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] 1 0 1
[ 0 0 ] 2 0 2
[ 0 1 ] 3 0 3
[ 0 1 ] 4 0 4
[ 1 0 ] 5 0 5
[ 1 0 ] 6 0 6
[ 1 1 ] 7 0 7
[ 1 1 ] 8 0 8
[ 2 0 ] 9 0 9
[ 2 0 ] 10 0 10
[ 2 1 ] 11 0 11
[ 2 1 ] 12 0 12
12 differences found
attribute: <reference2D of </dset>> and <reference2D of </dset>>
0 differences found
attribute: <enum2D of </dset>> and <enum2D of </dset>>
size: [3x2] [3x2]
position enum2D of </dset> enum2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] RED GREEN
[ 0 1 ] RED GREEN
[ 1 0 ] RED GREEN
[ 1 1 ] RED GREEN
[ 2 0 ] RED GREEN
[ 2 1 ] RED GREEN
6 differences found
attribute: <vlen2D of </dset>> and <vlen2D of </dset>>
size: [3x2] [3x2]
position vlen2D of </dset> vlen2D of </dset> difference
------------------------------------------------------------
[ 0 1 ] 1 0 1
[ 1 0 ] 2 0 2
[ 1 0 ] 3 0 3
[ 1 1 ] 4 0 4
[ 1 1 ] 5 0 5
[ 2 0 ] 6 0 6
[ 2 0 ] 7 0 7
[ 2 0 ] 8 0 8
[ 2 1 ] 9 0 9
[ 2 1 ] 10 0 10
[ 2 1 ] 11 0 11
11 differences found
attribute: <array2D of </dset>> and <array2D of </dset>>
size: [3x2] [3x2]
position array2D of </dset> array2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] 1 0 1
[ 0 0 ] 2 0 2
[ 0 0 ] 3 0 3
[ 0 1 ] 4 0 4
[ 0 1 ] 5 0 5
[ 0 1 ] 6 0 6
[ 1 0 ] 7 0 7
[ 1 0 ] 8 0 8
[ 1 0 ] 9 0 9
[ 1 1 ] 10 0 10
[ 1 1 ] 11 0 11
[ 1 1 ] 12 0 12
[ 2 0 ] 13 0 13
[ 2 0 ] 14 0 14
[ 2 0 ] 15 0 15
[ 2 1 ] 16 0 16
[ 2 1 ] 17 0 17
[ 2 1 ] 18 0 18
18 differences found
attribute: <integer2D of </dset>> and <integer2D of </dset>>
size: [3x2] [3x2]
position integer2D of </dset> integer2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] 1 0 1
[ 0 1 ] 2 0 2
[ 1 0 ] 3 0 3
[ 1 1 ] 4 0 4
[ 2 0 ] 5 0 5
[ 2 1 ] 6 0 6
6 differences found
attribute: <float2D of </dset>> and <float2D of </dset>>
size: [3x2] [3x2]
position float2D of </dset> float2D of </dset> difference
------------------------------------------------------------
[ 0 0 ] 1 0 1
[ 0 1 ] 2 0 2
[ 1 0 ] 3 0 3
[ 1 1 ] 4 0 4
[ 2 0 ] 5 0 5
[ 2 1 ] 6 0 6
6 differences found
attribute: <string3D of </dset>> and <string3D of </dset>>
size: [4x3x2] [4x3x2]
position string3D of </dset> string3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] a z
[ 0 0 0 ] b z
[ 0 0 1 ] c z
[ 0 0 1 ] d z
[ 0 1 0 ] e z
[ 0 1 0 ] f z
[ 0 1 1 ] g z
[ 0 1 1 ] h z
[ 0 2 0 ] i z
[ 0 2 0 ] j z
[ 0 2 1 ] k z
[ 0 2 1 ] l z
[ 1 0 0 ] m z
[ 1 0 0 ] n z
[ 1 0 1 ] p z
[ 1 0 1 ] q z
[ 1 1 0 ] r z
[ 1 1 0 ] s z
[ 1 1 1 ] t z
[ 1 1 1 ] u z
[ 1 2 0 ] v z
[ 1 2 0 ] w z
[ 1 2 1 ] x z
[ 2 0 0 ] A z
[ 2 0 0 ] B z
[ 2 0 1 ] C z
[ 2 0 1 ] D z
[ 2 1 0 ] E z
[ 2 1 0 ] F z
[ 2 1 1 ] G z
[ 2 1 1 ] H z
[ 2 2 0 ] I z
[ 2 2 0 ] J z
[ 2 2 1 ] K z
[ 2 2 1 ] L z
[ 3 0 0 ] M z
[ 3 0 0 ] N z
[ 3 0 1 ] P z
[ 3 0 1 ] Q z
[ 3 1 0 ] R z
[ 3 1 0 ] S z
[ 3 1 1 ] T z
[ 3 1 1 ] U z
[ 3 2 0 ] V z
[ 3 2 0 ] W z
[ 3 2 1 ] X z
[ 3 2 1 ] Z z
47 differences found
attribute: <bitfield3D of </dset>> and <bitfield3D of </dset>>
size: [4x3x2] [4x3x2]
position bitfield3D of </dset> bitfield3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] 1 0 1
[ 0 0 1 ] 2 0 2
[ 0 1 0 ] 3 0 3
[ 0 1 1 ] 4 0 4
[ 0 2 0 ] 5 0 5
[ 0 2 1 ] 6 0 6
[ 1 0 0 ] 7 0 7
[ 1 0 1 ] 8 0 8
[ 1 1 0 ] 9 0 9
[ 1 1 1 ] 10 0 10
[ 1 2 0 ] 11 0 11
[ 1 2 1 ] 12 0 12
[ 2 0 0 ] 13 0 13
[ 2 0 1 ] 14 0 14
[ 2 1 0 ] 15 0 15
[ 2 1 1 ] 16 0 16
[ 2 2 0 ] 17 0 17
[ 2 2 1 ] 18 0 18
[ 3 0 0 ] 19 0 19
[ 3 0 1 ] 20 0 20
[ 3 1 0 ] 21 0 21
[ 3 1 1 ] 22 0 22
[ 3 2 0 ] 23 0 23
[ 3 2 1 ] 24 0 24
24 differences found
attribute: <opaque3D of </dset>> and <opaque3D of </dset>>
size: [4x3x2] [4x3x2]
position opaque3D of </dset> opaque3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] 1 0 1
[ 0 0 1 ] 2 0 2
[ 0 1 0 ] 3 0 3
[ 0 1 1 ] 4 0 4
[ 0 2 0 ] 5 0 5
[ 0 2 1 ] 6 0 6
[ 1 0 0 ] 7 0 7
[ 1 0 1 ] 8 0 8
[ 1 1 0 ] 9 0 9
[ 1 1 1 ] 10 0 10
[ 1 2 0 ] 11 0 11
[ 1 2 1 ] 12 0 12
[ 2 0 0 ] 13 0 13
[ 2 0 1 ] 14 0 14
[ 2 1 0 ] 15 0 15
[ 2 1 1 ] 16 0 16
[ 2 2 0 ] 17 0 17
[ 2 2 1 ] 18 0 18
[ 3 0 0 ] 19 0 19
[ 3 0 1 ] 20 0 20
[ 3 1 0 ] 21 0 21
[ 3 1 1 ] 22 0 22
[ 3 2 0 ] 23 0 23
[ 3 2 1 ] 24 0 24
24 differences found
attribute: <compound3D of </dset>> and <compound3D of </dset>>
size: [4x3x2] [4x3x2]
position compound3D of </dset> compound3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] 1 0 1
[ 0 0 0 ] 2 0 2
[ 0 0 1 ] 3 0 3
[ 0 0 1 ] 4 0 4
[ 0 1 0 ] 5 0 5
[ 0 1 0 ] 6 0 6
[ 0 1 1 ] 7 0 7
[ 0 1 1 ] 8 0 8
[ 0 2 0 ] 9 0 9
[ 0 2 0 ] 10 0 10
[ 0 2 1 ] 11 0 11
[ 0 2 1 ] 12 0 12
[ 1 0 0 ] 13 0 13
[ 1 0 0 ] 14 0 14
[ 1 0 1 ] 15 0 15
[ 1 0 1 ] 16 0 16
[ 1 1 0 ] 17 0 17
[ 1 1 0 ] 18 0 18
[ 1 1 1 ] 19 0 19
[ 1 1 1 ] 20 0 20
[ 1 2 0 ] 21 0 21
[ 1 2 0 ] 22 0 22
[ 1 2 1 ] 23 0 23
[ 1 2 1 ] 24 0 24
[ 2 0 0 ] 25 0 25
[ 2 0 0 ] 26 0 26
[ 2 0 1 ] 27 0 27
[ 2 0 1 ] 28 0 28
[ 2 1 0 ] 29 0 29
[ 2 1 0 ] 30 0 30
[ 2 1 1 ] 31 0 31
[ 2 1 1 ] 32 0 32
[ 2 2 0 ] 33 0 33
[ 2 2 0 ] 34 0 34
[ 2 2 1 ] 35 0 35
[ 2 2 1 ] 36 0 36
[ 3 0 0 ] 37 0 37
[ 3 0 0 ] 38 0 38
[ 3 0 1 ] 39 0 39
[ 3 0 1 ] 40 0 40
[ 3 1 0 ] 41 0 41
[ 3 1 0 ] 42 0 42
[ 3 1 1 ] 43 0 43
[ 3 1 1 ] 44 0 44
[ 3 2 0 ] 45 0 45
[ 3 2 0 ] 46 0 46
[ 3 2 1 ] 47 0 47
[ 3 2 1 ] 48 0 48
48 differences found
attribute: <reference3D of </dset>> and <reference3D of </dset>>
0 differences found
attribute: <enum3D of </dset>> and <enum3D of </dset>>
size: [4x3x2] [4x3x2]
position enum3D of </dset> enum3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] GREEN RED
[ 0 0 1 ] GREEN RED
[ 0 1 0 ] GREEN RED
[ 0 1 1 ] GREEN RED
[ 0 2 0 ] GREEN RED
[ 0 2 1 ] GREEN RED
[ 1 0 0 ] GREEN RED
[ 1 0 1 ] GREEN RED
[ 1 1 0 ] GREEN RED
[ 1 1 1 ] GREEN RED
[ 1 2 0 ] GREEN RED
[ 1 2 1 ] GREEN RED
[ 2 0 0 ] GREEN RED
[ 2 0 1 ] GREEN RED
[ 2 1 0 ] GREEN RED
[ 2 1 1 ] GREEN RED
[ 2 2 0 ] GREEN RED
[ 2 2 1 ] GREEN RED
[ 3 0 0 ] GREEN RED
[ 3 0 1 ] GREEN RED
[ 3 1 0 ] GREEN RED
[ 3 1 1 ] GREEN RED
[ 3 2 0 ] GREEN RED
[ 3 2 1 ] GREEN RED
24 differences found
attribute: <vlen3D of </dset>> and <vlen3D of </dset>>
size: [4x3x2] [4x3x2]
position vlen3D of </dset> vlen3D of </dset> difference
------------------------------------------------------------
[ 0 0 1 ] 1 0 1
[ 0 1 0 ] 2 0 2
[ 0 1 1 ] 3 0 3
[ 0 2 0 ] 4 0 4
[ 0 2 1 ] 5 0 5
[ 1 0 0 ] 6 0 6
[ 1 0 0 ] 7 0 7
[ 1 0 1 ] 8 0 8
[ 1 0 1 ] 9 0 9
[ 1 1 0 ] 10 0 10
[ 1 1 0 ] 11 0 11
[ 1 1 1 ] 12 0 12
[ 1 1 1 ] 13 0 13
[ 1 2 0 ] 14 0 14
[ 1 2 0 ] 15 0 15
[ 1 2 1 ] 16 0 16
[ 1 2 1 ] 17 0 17
[ 2 0 0 ] 18 0 18
[ 2 0 0 ] 19 0 19
[ 2 0 0 ] 20 0 20
[ 2 0 1 ] 21 0 21
[ 2 0 1 ] 22 0 22
[ 2 0 1 ] 23 0 23
[ 2 1 0 ] 24 0 24
[ 2 1 0 ] 25 0 25
[ 2 1 0 ] 26 0 26
[ 2 1 1 ] 27 0 27
[ 2 1 1 ] 28 0 28
[ 2 1 1 ] 29 0 29
[ 2 2 0 ] 30 0 30
[ 2 2 0 ] 31 0 31
[ 2 2 0 ] 32 0 32
[ 2 2 1 ] 33 0 33
[ 2 2 1 ] 34 0 34
[ 2 2 1 ] 35 0 35
[ 3 0 0 ] 36 0 36
[ 3 0 0 ] 37 0 37
[ 3 0 0 ] 38 0 38
[ 3 0 0 ] 39 0 39
[ 3 0 1 ] 40 0 40
[ 3 0 1 ] 41 0 41
[ 3 0 1 ] 42 0 42
[ 3 0 1 ] 43 0 43
[ 3 1 0 ] 44 0 44
[ 3 1 0 ] 45 0 45
[ 3 1 0 ] 46 0 46
[ 3 1 0 ] 47 0 47
[ 3 1 1 ] 48 0 48
[ 3 1 1 ] 49 0 49
[ 3 1 1 ] 50 0 50
[ 3 1 1 ] 51 0 51
[ 3 2 0 ] 52 0 52
[ 3 2 0 ] 53 0 53
[ 3 2 0 ] 54 0 54
[ 3 2 0 ] 55 0 55
[ 3 2 1 ] 56 0 56
[ 3 2 1 ] 57 0 57
[ 3 2 1 ] 58 0 58
[ 3 2 1 ] 59 0 59
59 differences found
attribute: <array3D of </dset>> and <array3D of </dset>>
size: [4x3x2] [4x3x2]
position array3D of </dset> array3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] 1 0 1
[ 0 0 0 ] 2 0 2
[ 0 0 0 ] 3 0 3
[ 0 0 1 ] 4 0 4
[ 0 0 1 ] 5 0 5
[ 0 0 1 ] 6 0 6
[ 0 1 0 ] 7 0 7
[ 0 1 0 ] 8 0 8
[ 0 1 0 ] 9 0 9
[ 0 1 1 ] 10 0 10
[ 0 1 1 ] 11 0 11
[ 0 1 1 ] 12 0 12
[ 0 2 0 ] 13 0 13
[ 0 2 0 ] 14 0 14
[ 0 2 0 ] 15 0 15
[ 0 2 1 ] 16 0 16
[ 0 2 1 ] 17 0 17
[ 0 2 1 ] 18 0 18
[ 1 0 0 ] 19 0 19
[ 1 0 0 ] 20 0 20
[ 1 0 0 ] 21 0 21
[ 1 0 1 ] 22 0 22
[ 1 0 1 ] 23 0 23
[ 1 0 1 ] 24 0 24
[ 1 1 0 ] 25 0 25
[ 1 1 0 ] 26 0 26
[ 1 1 0 ] 27 0 27
[ 1 1 1 ] 28 0 28
[ 1 1 1 ] 29 0 29
[ 1 1 1 ] 30 0 30
[ 1 2 0 ] 31 0 31
[ 1 2 0 ] 32 0 32
[ 1 2 0 ] 33 0 33
[ 1 2 1 ] 34 0 34
[ 1 2 1 ] 35 0 35
[ 1 2 1 ] 36 0 36
[ 2 0 0 ] 37 0 37
[ 2 0 0 ] 38 0 38
[ 2 0 0 ] 39 0 39
[ 2 0 1 ] 40 0 40
[ 2 0 1 ] 41 0 41
[ 2 0 1 ] 42 0 42
[ 2 1 0 ] 43 0 43
[ 2 1 0 ] 44 0 44
[ 2 1 0 ] 45 0 45
[ 2 1 1 ] 46 0 46
[ 2 1 1 ] 47 0 47
[ 2 1 1 ] 48 0 48
[ 2 2 0 ] 49 0 49
[ 2 2 0 ] 50 0 50
[ 2 2 0 ] 51 0 51
[ 2 2 1 ] 52 0 52
[ 2 2 1 ] 53 0 53
[ 2 2 1 ] 54 0 54
[ 3 0 0 ] 55 0 55
[ 3 0 0 ] 56 0 56
[ 3 0 0 ] 57 0 57
[ 3 0 1 ] 58 0 58
[ 3 0 1 ] 59 0 59
[ 3 0 1 ] 60 0 60
[ 3 1 0 ] 61 0 61
[ 3 1 0 ] 62 0 62
[ 3 1 0 ] 63 0 63
[ 3 1 1 ] 64 0 64
[ 3 1 1 ] 65 0 65
[ 3 1 1 ] 66 0 66
[ 3 2 0 ] 67 0 67
[ 3 2 0 ] 68 0 68
[ 3 2 0 ] 69 0 69
[ 3 2 1 ] 70 0 70
[ 3 2 1 ] 71 0 71
[ 3 2 1 ] 72 0 72
72 differences found
attribute: <integer3D of </dset>> and <integer3D of </dset>>
size: [4x3x2] [4x3x2]
position integer3D of </dset> integer3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] 1 0 1
[ 0 0 1 ] 2 0 2
[ 0 1 0 ] 3 0 3
[ 0 1 1 ] 4 0 4
[ 0 2 0 ] 5 0 5
[ 0 2 1 ] 6 0 6
[ 1 0 0 ] 7 0 7
[ 1 0 1 ] 8 0 8
[ 1 1 0 ] 9 0 9
[ 1 1 1 ] 10 0 10
[ 1 2 0 ] 11 0 11
[ 1 2 1 ] 12 0 12
[ 2 0 0 ] 13 0 13
[ 2 0 1 ] 14 0 14
[ 2 1 0 ] 15 0 15
[ 2 1 1 ] 16 0 16
[ 2 2 0 ] 17 0 17
[ 2 2 1 ] 18 0 18
[ 3 0 0 ] 19 0 19
[ 3 0 1 ] 20 0 20
[ 3 1 0 ] 21 0 21
[ 3 1 1 ] 22 0 22
[ 3 2 0 ] 23 0 23
[ 3 2 1 ] 24 0 24
24 differences found
attribute: <float3D of </dset>> and <float3D of </dset>>
size: [4x3x2] [4x3x2]
position float3D of </dset> float3D of </dset> difference
------------------------------------------------------------
[ 0 0 0 ] 1 0 1
[ 0 0 1 ] 2 0 2
[ 0 1 0 ] 3 0 3
[ 0 1 1 ] 4 0 4
[ 0 2 0 ] 5 0 5
[ 0 2 1 ] 6 0 6
[ 1 0 0 ] 7 0 7
[ 1 0 1 ] 8 0 8
[ 1 1 0 ] 9 0 9
[ 1 1 1 ] 10 0 10
[ 1 2 0 ] 11 0 11
[ 1 2 1 ] 12 0 12
[ 2 0 0 ] 13 0 13
[ 2 0 1 ] 14 0 14
[ 2 1 0 ] 15 0 15
[ 2 1 1 ] 16 0 16
[ 2 2 0 ] 17 0 17
[ 2 2 1 ] 18 0 18
[ 3 0 0 ] 19 0 19
[ 3 0 1 ] 20 0 20
[ 3 1 0 ] 21 0 21
[ 3 1 1 ] 22 0 22
[ 3 2 0 ] 23 0 23
[ 3 2 1 ] 24 0 24
24 differences found
456 differences found
group : </g1> and </g1>
0 differences found
attribute: <string of </g1>> and <string of </g1>>