summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2002-11-18 16:38:11 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2002-11-18 16:38:11 (GMT)
commit0105a3b97cabccd3463c82c22da7e3f4d23c2b05 (patch)
tree9b0002e531446227f62b929adba84b9bfbcacc8a
parent02fe47462b798e7f212f09fe65f022965ce4b365 (diff)
downloadhdf5-0105a3b97cabccd3463c82c22da7e3f4d23c2b05.zip
hdf5-0105a3b97cabccd3463c82c22da7e3f4d23c2b05.tar.gz
hdf5-0105a3b97cabccd3463c82c22da7e3f4d23c2b05.tar.bz2
[svn-r6099]
Purpose: bug fix. Description: h5dump cannot dump data and datatype for VL string. Platforms tested: eirene, arabica Misc. update: MANIFEST, RELEASE.txt
-rw-r--r--MANIFEST3
-rw-r--r--release_docs/RELEASE.txt2
-rw-r--r--test/tvlstr.c32
-rw-r--r--tools/h5dump/h5dump.c92
-rw-r--r--tools/h5dump/h5dumpgentest.c54
-rwxr-xr-xtools/h5dump/testh5dump.sh4
-rw-r--r--tools/lib/h5tools.c33
-rw-r--r--tools/lib/h5tools_str.c6
-rw-r--r--tools/testfiles/tvlstr.ddl41
-rw-r--r--tools/testfiles/tvlstr.h5bin0 -> 8192 bytes
-rw-r--r--tools/testfiles/tvlstr.h5.xml51
11 files changed, 277 insertions, 41 deletions
diff --git a/MANIFEST b/MANIFEST
index 71f2346..ed82c0c 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1158,6 +1158,8 @@
./tools/testfiles/tvldtypes3.h5
./tools/testfiles/tvldtypes4.ddl
./tools/testfiles/tvldtypes4.h5
+./tools/testfiles/tvlstr.h5
+./tools/testfiles/tvlstr.ddl
# Expected output from h5ls tests
./tools/testfiles/help-1.ls
@@ -1231,6 +1233,7 @@
./tools/testfiles/tvldtypes1.h5.xml
./tools/testfiles/tvldtypes2.h5.xml
./tools/testfiles/tvldtypes3.h5.xml
+./tools/testfiles/tvlstr.h5.xml
./windows/all.zip
./windows/all_withf90.zip
diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt
index cba2fd3..037bba8 100644
--- a/release_docs/RELEASE.txt
+++ b/release_docs/RELEASE.txt
@@ -198,6 +198,8 @@ Configuration
Tools
-----
+ * The VL string bug(data and datatype cannot be shown) in h5dump is fixed.
+ -SLU - 2002/11/18
* Fixed segfault if h5dump was invoked with some options but no file (e.g.,
h5dump -H). -AKC, 2002/10/15
* Fixed limitation in h5dumper with object names which reached over 1024
diff --git a/test/tvlstr.c b/test/tvlstr.c
index 9d31f2d..91bf47a 100644
--- a/test/tvlstr.c
+++ b/test/tvlstr.c
@@ -239,13 +239,17 @@ static void test_vlstring_type(void)
H5T_cset_t cset;
H5T_str_t pad;
herr_t ret;
+ size_t size;
/* Output message about test being performed */
MESSAGE(5, ("Testing VL String type\n"));
/* Create file */
- fid = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
- CHECK(fid, FAIL, "H5Fcreate");
+ /*fid = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fcreate");*/
+
+ fid = H5Fopen(DATAFILE, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
/* Create a datatype to refer to */
tid_vlstr = H5Tcopy(H5T_C_S1);
@@ -280,8 +284,20 @@ static void test_vlstring_type(void)
/* Close datatype */
ret = H5Tclose(tid_vlstr);
CHECK(ret, FAIL, "H5Tclose");
+
+ tid_vlstr = H5Topen(fid, VLSTR_TYPE);
+ CHECK(tid_vlstr, FAIL, "H5Topen");
+
+ ret = H5Tclose(tid_vlstr);
+ CHECK(ret, FAIL, "H5Tclose");
+
+ ret = H5Fclose(fid);
+ CHECK(ret, FAIL, "H5Fclose");
+ fid = H5Fopen(DATAFILE, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(fid, FAIL, "H5Fopen");
+
/* Open the variable-length string datatype just created */
tid_vlstr = H5Topen(fid, VLSTR_TYPE);
CHECK(tid_vlstr, FAIL, "H5Topen");
@@ -313,8 +329,8 @@ static void test_write_vl_string_attribute(void)
herr_t ret;
char *string_att_check;
- file = H5Fcreate(DATAFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
- CHECK(file, FAIL, "H5Fcreate");
+ file = H5Fopen(DATAFILE, H5F_ACC_RDWR, H5P_DEFAULT);
+ CHECK(file, FAIL, "H5Fopen");
/* Create a datatype to refer to. */
type = H5Tcopy (H5T_C_S1);
@@ -375,6 +391,9 @@ static void test_read_vl_string_attribute(void)
hid_t type;
herr_t ret;
char *string_att_check;
+ hsize_t size[64];
+ hid_t space;
+ int ndims;
file = H5Fopen(DATAFILE, H5F_ACC_RDONLY, H5P_DEFAULT);
CHECK(file, FAIL, "H5Fopen");
@@ -391,6 +410,9 @@ static void test_read_vl_string_attribute(void)
att = H5Aopen_name(root, "test_scalar");
CHECK(att, FAIL, "H5Aopen_name");
+
+ space = H5Aget_space(att);
+ ndims = H5Sget_simple_extent_dims(space, size, NULL);
ret = H5Aread(att, type, &string_att_check);
CHECK(ret, FAIL, "H5Aread");
@@ -433,7 +455,7 @@ test_vlstrings(void)
test_vlstrings_basic();
test_vlstring_type();
- /* Test using VL strings in attributes */
+ /*Test using VL strings in attributes */
test_write_vl_string_attribute();
test_read_vl_string_attribute();
} /* test_vlstrings() */
diff --git a/tools/h5dump/h5dump.c b/tools/h5dump/h5dump.c
index d751d25..36250d3 100644
--- a/tools/h5dump/h5dump.c
+++ b/tools/h5dump/h5dump.c
@@ -677,12 +677,14 @@ print_datatype(hid_t type)
char *fname;
hid_t nmembers, mtype, str_type;
int i, j, ndims, perm[H5DUMP_MAX_RANK];
- size_t size;
+ size_t size=0;
hsize_t dims[H5DUMP_MAX_RANK];
H5T_str_t str_pad;
H5T_cset_t cset;
H5G_stat_t statbuf;
hid_t super;
+ hid_t tmp_type;
+ htri_t is_vlstr=FALSE;
switch (H5Tget_class(type)) {
case H5T_INTEGER:
@@ -770,15 +772,23 @@ print_datatype(hid_t type)
break;
case H5T_STRING:
- size = H5Tget_size(type);
- str_pad = H5Tget_strpad(type);
- cset = H5Tget_cset(type);
+ /* Make a copy of type in memory in case when TYPE is on disk, the size
+ * will be bigger than in memory. This makes it easier to compare
+ * types in memory. */
+ tmp_type = H5Tcopy(type);
+ size = H5Tget_size(tmp_type);
+ str_pad = H5Tget_strpad(tmp_type);
+ cset = H5Tget_cset(tmp_type);
+ is_vlstr = H5Tis_variable_str(tmp_type);
printf("H5T_STRING %s\n", dump_header_format->strblockbegin);
indent += COL;
indentation(indent + COL);
- printf("%s %d;\n", STRSIZE, (int) size);
+ if(is_vlstr)
+ printf("%s H5T_VARIABLE;\n", STRSIZE);
+ else
+ printf("%s %d;\n", STRSIZE, (int) size);
indentation(indent + COL);
printf("%s ", STRPAD);
@@ -800,14 +810,17 @@ print_datatype(hid_t type)
printf("unknown_cset;\n");
str_type = H5Tcopy(H5T_C_S1);
+ if(is_vlstr)
+ H5Tset_size(str_type, H5T_VARIABLE);
+ else
+ H5Tset_size(str_type, size);
H5Tset_cset(str_type, cset);
- H5Tset_size(str_type, size);
H5Tset_strpad(str_type, str_pad);
indentation(indent + COL);
printf("%s ", CTYPE);
- if (H5Tequal(type, str_type)) {
+ if (H5Tequal(tmp_type, str_type)) {
printf("H5T_C_S1;\n");
H5Tclose(str_type);
} else {
@@ -817,7 +830,7 @@ print_datatype(hid_t type)
H5Tset_size(str_type, size);
H5Tset_strpad(str_type, str_pad);
- if (H5Tequal(type, str_type)) {
+ if (H5Tequal(tmp_type, str_type)) {
printf("H5T_FORTRAN_S1;\n");
} else {
printf("unknown_one_character_type;\n ");
@@ -827,6 +840,8 @@ print_datatype(hid_t type)
H5Tclose(str_type);
}
+ H5Tclose(tmp_type);
+
indent -= COL;
indentation(indent + COL);
printf("%s", dump_header_format->strblockend);
@@ -1887,13 +1902,14 @@ dump_data(hid_t obj_id, int obj_data, struct subset_t *sset)
alloc_size = nelmts * MAX(H5Tget_size(type), H5Tget_size(p_type));
assert(alloc_size == (hsize_t)((size_t)alloc_size)); /*check for overflow*/
+
buf = malloc((size_t)alloc_size);
assert(buf);
if (H5Aread(obj_id, p_type, buf) >= 0)
status = h5tools_dump_mem(stdout, outputformat, obj_id, p_type,
- space, buf, depth);
-
+ space, buf, depth);
+
free(buf);
H5Tclose(p_type);
H5Sclose(space);
@@ -2857,10 +2873,25 @@ done:
d_status = EXIT_FAILURE;
free_handler(hand, argc);
-
+
+ for(i=0; i<info.group_table->nobjs; i++) {
+ if(info.group_table->objs[i].objname)
+ free(info.group_table->objs[i].objname);
+ }
free(group_table->objs);
+
+ for(i=0; i<info.dset_table->nobjs; i++) {
+ if(info.dset_table->objs[i].objname)
+ free(info.dset_table->objs[i].objname);
+ }
free(dset_table->objs);
+
+ for(i=0; i<info.type_table->nobjs; i++) {
+ if(info.type_table->objs[i].objname)
+ free(info.type_table->objs[i].objname);
+ }
free(type_table->objs);
+
free(prefix);
free(info.prefix);
@@ -4557,12 +4588,14 @@ xml_print_strs(hid_t did, int source)
{
herr_t e;
hid_t type, space;
- char *buf;
+ void *buf;
char *bp;
char *onestring;
hsize_t ssiz;
- size_t tsiz;
+ size_t tsiz, str_size;
size_t i;
+ htri_t is_vlstr;
+
if (source == DATASET_DATA) {
type = H5Dget_type(did);
} else if (source == ATTRIBUTE_DATA) {
@@ -4575,12 +4608,14 @@ xml_print_strs(hid_t did, int source)
/* return an error */
return FAIL;
}
+ is_vlstr = H5Tis_variable_str(type);
+
if (source == DATASET_DATA) {
space = H5Dget_space(did);
ssiz = H5Sget_simple_extent_npoints(space);
ssiz *= H5Tget_size(type);
- buf = calloc((size_t)ssiz, sizeof(char));
+ buf = malloc((size_t)ssiz);
if (buf == NULL) {
return FAIL;
@@ -4596,11 +4631,12 @@ xml_print_strs(hid_t did, int source)
space = H5Aget_space(did);
ssiz = H5Sget_simple_extent_npoints(space);
ssiz *= H5Tget_size(type);
-
- buf = calloc((size_t)ssiz, sizeof(char));
+
+ buf = malloc((size_t)ssiz);
if (buf == NULL) {
return FAIL;
}
+
e = H5Aread(did, type, buf);
if (e < 0) {
free(buf);
@@ -4611,28 +4647,36 @@ xml_print_strs(hid_t did, int source)
return FAIL;
}
-/* pull out each string... */
+ /* pull out each string... */
ssiz = H5Sget_simple_extent_npoints(space);
tsiz = H5Tget_size(type);
- onestring = (char *) calloc((size_t)tsiz, sizeof(char));
- bp = buf;
+ bp = (char*)buf;
+ if(!is_vlstr)
+ onestring = (char *) calloc(tsiz, sizeof(char));
for (i = 0; i < ssiz; i++) {
- strncpy(onestring, bp, tsiz);
+ if(is_vlstr) {
+ onestring = *(char **)bp;
+ str_size = (size_t)strlen(onestring);
+ } else {
+ strncpy(onestring, bp, tsiz);
+ str_size = tsiz;
+ }
indentation(indent + COL);
if (!onestring) {
printf("\"%s\"\n", "NULL");
} else {
- char *t_onestring = xml_escape_the_string(onestring, (int)tsiz);
+ char *t_onestring = xml_escape_the_string(onestring, (int)str_size);
- printf("\"%s\"\n", xml_escape_the_string(onestring, (int)tsiz));
+ printf("\"%s\"\n", t_onestring);
free(t_onestring);
}
-
- bp += tsiz;
+
+ bp += tsiz;
}
+
return SUCCEED;
}
diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c
index 8f6e3bc..f0e9515 100644
--- a/tools/h5dump/h5dumpgentest.c
+++ b/tools/h5dump/h5dumpgentest.c
@@ -63,6 +63,7 @@
#define FILE35 "tfamily%05d.h5"
#define FILE36 "tmulti"
#define FILE37 "tlarge_objname.h5"
+#define FILE38 "tvlstr.h5"
#define LENSTR 50
#define LENSTR2 11
@@ -108,6 +109,9 @@ typedef struct s1_t {
#define ARRAY3_DIM1 6
#define ARRAY3_DIM2 3
+/* VL string datatype name */
+#define VLSTR_TYPE "vl_string_type"
+
static void gent_group(void)
{
hid_t fid, group;
@@ -2838,6 +2842,55 @@ static void gent_large_objname(void)
H5Fclose(fid);
}
+static void gent_vlstr(void)
+{
+ const char *wdata[SPACE1_DIM1]= {
+ "Four score and seven years ago our forefathers brought forth on this continent a new nation,",
+ "conceived in liberty and dedicated to the proposition that all men are created equal.",
+ "Now we are engaged in a great civil war,",
+ "testing whether that nation or any nation so conceived and so dedicated can long endure."
+ }; /* Information to write */
+ char *string_att= "This is the string for the attribute";
+ hid_t fid1; /* HDF5 File IDs */
+ hid_t dataset, root; /* Dataset ID */
+ hid_t sid1, dataspace;/* Dataspace ID */
+ hid_t tid1, att; /* Datatype ID */
+ hsize_t dims1[] = {SPACE1_DIM1};
+
+ /* Create file */
+ fid1 = H5Fcreate(FILE38, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+ sid1 = H5Screate_simple(SPACE1_RANK, dims1, NULL);
+
+ /* Create a VL string datatype to refer to */
+ tid1 = H5Tcopy (H5T_C_S1);
+ H5Tset_size (tid1,H5T_VARIABLE);
+
+ /* Create a dataset and write VL string to it. */
+ dataset=H5Dcreate(fid1,"Dataset1",tid1,sid1,H5P_DEFAULT);
+ H5Dwrite(dataset,tid1,H5S_ALL,H5S_ALL,H5P_DEFAULT,wdata);
+ H5Dclose(dataset);
+
+ /* Create a named VL string type. Change padding of datatype */
+ H5Tset_strpad(tid1, H5T_STR_NULLPAD);
+ H5Tcommit(fid1, "vl_string_type", tid1);
+
+ /* Create an group attribute of VL string type */
+ root = H5Gopen(fid1, "/");
+ dataspace = H5Screate(H5S_SCALAR);
+
+ att = H5Acreate(root, "test_scalar", tid1, dataspace, H5P_DEFAULT);
+ H5Awrite(att, tid1, &string_att);
+
+ /* Close */
+ H5Tclose(tid1);
+ H5Sclose(sid1);
+ H5Sclose(dataspace);
+ H5Aclose(att);
+ H5Gclose(root);
+ H5Fclose(fid1);
+}
+
int main(void)
{
gent_group();
@@ -2888,6 +2941,7 @@ int main(void)
gent_multi();
gent_large_objname();
+ gent_vlstr();
return 0;
}
diff --git a/tools/h5dump/testh5dump.sh b/tools/h5dump/testh5dump.sh
index ec22362..99c1a89 100755
--- a/tools/h5dump/testh5dump.sh
+++ b/tools/h5dump/testh5dump.sh
@@ -144,6 +144,9 @@ TOOLTEST tvldtypes2.ddl tvldtypes2.h5
TOOLTEST tvldtypes3.ddl tvldtypes3.h5
TOOLTEST tvldtypes4.ddl tvldtypes4.h5
+#test for file with variable length string data
+TOOLTEST tvlstr.ddl tvlstr.h5
+
# test for files with array data
TOOLTEST tarray1.ddl tarray1.h5
TOOLTEST tarray2.ddl tarray2.h5
@@ -218,6 +221,7 @@ TOOLTEST tarray7.h5.xml --xml tarray7.h5
TOOLTEST tvldtypes1.h5.xml --xml tvldtypes1.h5
TOOLTEST tvldtypes2.h5.xml --xml tvldtypes2.h5
TOOLTEST tvldtypes3.h5.xml --xml tvldtypes3.h5
+TOOLTEST tvlstr.h5.xml --xml tvlstr.h5
TOOLTEST tsaf.h5.xml --xml tsaf.h5
TOOLTEST tempty.h5.xml --xml tempty.h5
diff --git a/tools/lib/h5tools.c b/tools/lib/h5tools.c
index b2c4cec..fbdb38a 100644
--- a/tools/lib/h5tools.c
+++ b/tools/lib/h5tools.c
@@ -457,6 +457,7 @@ h5tools_dump_simple_data(FILE *stream, const h5dump_t *info, hid_t container,
*this var to count elements and
*break after we see a number equal
*to the ctx->size_last_dim. */
+ unsigned char *tmp=NULL;
/* Setup */
memset(&buffer, 0, sizeof(h5tools_str_t));
@@ -470,7 +471,12 @@ h5tools_dump_simple_data(FILE *stream, const h5dump_t *info, hid_t container,
for (i = 0; i < nelmts; i++, ctx->cur_elmt++, elmt_counter++) {
/* Render the element */
h5tools_str_reset(&buffer);
- h5tools_str_sprint(&buffer, info, container, type, mem + i * size, ctx);
+ if(H5Tis_variable_str(type)) {
+ tmp = ((unsigned char**)mem)[i];
+ h5tools_str_sprint(&buffer, info, container, type, tmp, ctx);
+
+ } else
+ h5tools_str_sprint(&buffer, info, container, type, mem + i * size, ctx);
if (i + 1 < nelmts || (flags & END_OF_DATA) == 0)
h5tools_str_append(&buffer, "%s", OPT(info->elmt_suf1, ","));
@@ -785,7 +791,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5dump_t *info, hid_t dset,
hsize_t sm_nelmts; /*elements per stripmine*/
unsigned char *sm_buf = NULL; /*buffer for raw data */
hid_t sm_space; /*stripmine data space */
-
+
/* Hyperslab info */
hssize_t hs_offset[H5S_MAX_RANK];/*starting offset */
hsize_t hs_size[H5S_MAX_RANK]; /*size this pass */
@@ -820,9 +826,6 @@ h5tools_dump_simple_dset(FILE *stream, const h5dump_t *info, hid_t dset,
ctx.p_min_idx[i] = 0;
H5Sget_simple_extent_dims(f_space, total_size, NULL);
- /* printf("total_size[ctx.ndims-1]%d\n",total_size[ctx.ndims-1]);
- printf("total_size cast %d\n",(int)(total_size[ctx.ndims-1])); */
- /*assert(total_size[ctx.ndims - 1]==(hsize_t)((int)(total_size[ctx.ndims - 1])));*/
ctx.size_last_dim = (total_size[ctx.ndims - 1]);
/* calculate the number of elements we're going to print */
@@ -858,6 +861,7 @@ h5tools_dump_simple_dset(FILE *stream, const h5dump_t *info, hid_t dset,
assert(sm_nbytes == (hsize_t)((size_t)sm_nbytes)); /*check for overflow*/
sm_buf = malloc((size_t)sm_nbytes);
+
sm_nelmts = sm_nbytes / p_type_nbytes;
sm_space = H5Screate_simple(1, &sm_nelmts, NULL);
@@ -896,10 +900,10 @@ h5tools_dump_simple_dset(FILE *stream, const h5dump_t *info, hid_t dset,
flags = (elmtno == 0) ? START_OF_DATA : 0;
flags |= ((elmtno + hs_nelmts) >= p_nelmts) ? END_OF_DATA : 0;
h5tools_dump_simple_data(stream, info, dset, &ctx, flags, hs_nelmts,
- p_type, sm_buf);
+ p_type, sm_buf);
/* Reclaim any VL memory, if necessary */
- if (vl_data)
+ if(vl_data)
H5Dvlen_reclaim(p_type, sm_space, H5P_DEFAULT, sm_buf);
/* Calculate the next hyperslab offset */
@@ -925,7 +929,9 @@ h5tools_dump_simple_dset(FILE *stream, const h5dump_t *info, hid_t dset,
H5Sclose(sm_space);
H5Sclose(f_space);
+
free(sm_buf);
+
return SUCCEED;
}
@@ -967,7 +973,7 @@ h5tools_dump_simple_mem(FILE *stream, const h5dump_t *info, hid_t obj_id,
ctx.indent_level = indentlevel;
ctx.need_prefix = 1;
-
+
/* Assume entire data space to be printed */
for (i = 0; i < (hsize_t)ctx.ndims; i++)
ctx.p_min_idx[i] = 0;
@@ -976,7 +982,7 @@ h5tools_dump_simple_mem(FILE *stream, const h5dump_t *info, hid_t obj_id,
for (i = 0, nelmts = 1; ctx.ndims != 0 && i < (hsize_t)ctx.ndims; i++)
nelmts *= ctx.p_max_idx[i] - ctx.p_min_idx[i];
-
+
if (nelmts == 0)
return SUCCEED; /*nothing to print*/
assert(ctx.p_max_idx[ctx.ndims - 1]==(hsize_t)((int)ctx.p_max_idx[ctx.ndims - 1]));
@@ -1075,8 +1081,13 @@ h5tools_fixtype(hid_t f_type)
* strDUAction == TRUE. if it is false we will do the original action
* here.
*/
- m_type = H5Tcopy(f_type);
- H5Tset_cset(m_type, H5T_CSET_ASCII);
+ if(H5Tis_variable_str(f_type)) {
+ m_type = H5Tcopy(H5T_C_S1);
+ H5Tset_size(m_type, H5T_VARIABLE);
+ } else {
+ m_type = H5Tcopy(f_type);
+ H5Tset_cset(m_type, H5T_CSET_ASCII);
+ }
break;
case H5T_COMPOUND:
diff --git a/tools/lib/h5tools_str.c b/tools/lib/h5tools_str.c
index 0820cfb..3cacff0 100644
--- a/tools/lib/h5tools_str.c
+++ b/tools/lib/h5tools_str.c
@@ -545,7 +545,11 @@ h5tools_str_sprint(h5tools_str_t *str, const h5dump_t *info, hid_t container,
unsigned int i;
quote = '\0';
- size = H5Tget_size(type);
+ if(H5Tis_variable_str(type)) {
+ size = HDstrlen(cp_vp);
+ } else {
+ size = H5Tget_size(type);
+ }
pad = H5Tget_strpad(type);
for (i = 0; i < size && (cp_vp[i] != '\0' || pad != H5T_STR_NULLTERM); i++) {
diff --git a/tools/testfiles/tvlstr.ddl b/tools/testfiles/tvlstr.ddl
new file mode 100644
index 0000000..93b392e
--- /dev/null
+++ b/tools/testfiles/tvlstr.ddl
@@ -0,0 +1,41 @@
+#############################
+Expected output for 'h5dump tvlstr.h5'
+#############################
+HDF5 "tvlstr.h5" {
+GROUP "/" {
+ ATTRIBUTE "test_scalar" {
+ DATATYPE H5T_STRING {
+ STRSIZE H5T_VARIABLE;
+ STRPAD H5T_STR_NULLPAD;
+ CSET H5T_CSET_ASCII;
+ CTYPE H5T_C_S1;
+ }
+ DATASPACE SCALAR
+ DATA {
+ "This is the string for the attribute"
+ }
+ }
+ DATASET "Dataset1" {
+ DATATYPE H5T_STRING {
+ STRSIZE H5T_VARIABLE;
+ STRPAD H5T_STR_NULLTERM;
+ CSET H5T_CSET_ASCII;
+ CTYPE H5T_C_S1;
+ }
+ DATASPACE SIMPLE { ( 4 ) / ( 4 ) }
+ DATA {
+ "Four score and seven years ago our forefathers brought forth on this continent a new nation,",
+ "conceived in liberty and dedicated to the proposition that all men are created equal.",
+ "Now we are engaged in a great civil war,",
+ "testing whether that nation or any nation so conceived and so dedicated can long endure."
+ }
+ }
+ DATATYPE "vl_string_type" H5T_STRING {
+ STRSIZE H5T_VARIABLE;
+ STRPAD H5T_STR_NULLPAD;
+ CSET H5T_CSET_ASCII;
+ CTYPE H5T_C_S1;
+ };
+
+}
+}
diff --git a/tools/testfiles/tvlstr.h5 b/tools/testfiles/tvlstr.h5
new file mode 100644
index 0000000..53f34ef
--- /dev/null
+++ b/tools/testfiles/tvlstr.h5
Binary files differ
diff --git a/tools/testfiles/tvlstr.h5.xml b/tools/testfiles/tvlstr.h5.xml
new file mode 100644
index 0000000..3e5b07e
--- /dev/null
+++ b/tools/testfiles/tvlstr.h5.xml
@@ -0,0 +1,51 @@
+#############################
+Expected output for 'h5dump --xml tvlstr.h5'
+#############################
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE HDF5-File PUBLIC "HDF5-File.dtd" "http://hdf.ncsa.uiuc.edu/DTDs/HDF5-File.dtd">
+<HDF5-File>
+<RootGroup OBJ-XID="root">
+ <Attribute Name="test_scalar">
+ <Dataspace>
+ <ScalarDataspace />
+ </Dataspace>
+ <DataType>
+ <AtomicType>
+ <StringType Cset="H5T_CSET_ASCII" StrSize="4" StrPad="H5T_STR_NULLPAD"/>
+ </AtomicType>
+ </DataType>
+ <Data>
+ <DataFromFile>
+ "This is the string for the attribute"
+ </DataFromFile>
+ </Data>
+ </Attribute>
+ <NamedDataType Name="vl_string_type" OBJ-XID="/vl_string_type" Parents="root">
+ <DataType>
+ <AtomicType>
+ <StringType Cset="H5T_CSET_ASCII" StrSize="16" StrPad="H5T_STR_NULLPAD"/>
+ </AtomicType>
+ </DataType>
+ </NamedDataType>
+ <Dataset Name="Dataset1" OBJ-XID="/Dataset1" Parents="root">
+ <Dataspace>
+ <SimpleDataspace Ndims="1">
+ <Dimension DimSize="4" MaxDimSize="4"/>
+ </SimpleDataspace>
+ </Dataspace>
+ <DataType>
+ <AtomicType>
+ <StringType Cset="H5T_CSET_ASCII" StrSize="4" StrPad="H5T_STR_NULLTERM"/>
+ </AtomicType>
+ </DataType>
+ <Data>
+ <DataFromFile>
+ "Four score and seven years ago our forefathers brought forth on this continent a new nation,"
+ "conceived in liberty and dedicated to the proposition that all men are created equal."
+ "Now we are engaged in a great civil war,"
+ "testing whether that nation or any nation so conceived and so dedicated can long endure."
+ </DataFromFile>
+ </Data>
+ </Dataset>
+</RootGroup>
+</HDF5-File>