From 6d28e06f30587202147f6ae31b658a5021adf2a0 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Sun, 21 Sep 2008 13:35:43 -0500 Subject: [svn-r15668] Purpose: Add feature requested in bug #1282 Description: Adds capability to h5ls to traverse external links when the -r (recursive) option is given. Changes to the way absolute path names are patched in h5trav.c. Changes to the way recursive traversal starting from a non-root group is handled (which also fixes some preexisting issues). Tests added for these cases. Tested: kagiso, smirom, linew (h5committest) --- MANIFEST | 5 + release_docs/RELEASE.txt | 2 + tools/h5dump/h5dumpgentest.c | 8 +- tools/h5ls/h5ls.c | 300 +++++++++++++++++++++++++++++++++------ tools/h5ls/testh5ls.sh | 3 + tools/lib/h5trav.c | 15 +- tools/testfiles/tall-2.ls | 6 +- tools/testfiles/textlink-1.ls | 4 +- tools/testfiles/textlinksrc-1.ls | 17 +++ tools/testfiles/textlinksrc-2.ls | 8 ++ tools/testfiles/textlinksrc-3.ls | 12 ++ tools/testfiles/textlinksrc.h5 | Bin 0 -> 1104 bytes tools/testfiles/textlinktar.h5 | Bin 0 -> 5664 bytes tools/testfiles/tslink-1.ls | 4 +- tools/testfiles/tudlink-1.ls | 4 +- 15 files changed, 328 insertions(+), 60 deletions(-) create mode 100644 tools/testfiles/textlinksrc-1.ls create mode 100644 tools/testfiles/textlinksrc-2.ls create mode 100644 tools/testfiles/textlinksrc-3.ls create mode 100644 tools/testfiles/textlinksrc.h5 create mode 100644 tools/testfiles/textlinktar.h5 diff --git a/MANIFEST b/MANIFEST index 3946690..b997acd 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1159,6 +1159,11 @@ ./tools/testfiles/textlink.h5 ./tools/testfiles/textlink.h5.xml ./tools/testfiles/textlink-1.ls +./tools/testfiles/textlinksrc.h5 +./tools/testfiles/textlinksrc-1.ls +./tools/testfiles/textlinksrc-2.ls +./tools/testfiles/textlinksrc-3.ls +./tools/testfiles/textlinktar.h5 ./tools/testfiles/tfamily.ddl ./tools/testfiles/tfamily00000.h5 ./tools/testfiles/tfamily00001.h5 diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 33cca5d..4d012c0 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -89,6 +89,8 @@ New Features points to. (PVN - 2008/05/12) - h5repack: add a userblock to an HDF5 file during the repack. (PVN - 2008/08/26) - h5repack: add 2 options that call H5Pset_alignment in the repacked file. (PVN - 2008/08/29) + - h5ls: added capability to traverse through external links when the -r + (recursive) flag is given. (NAF - 2008/09/16) diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c index d3e1502..bd3c4de 100644 --- a/tools/h5dump/h5dumpgentest.c +++ b/tools/h5dump/h5dumpgentest.c @@ -6198,14 +6198,18 @@ gent_extlinks(void) /*------------------------------------------------------------------------- - * create a Group, a Dataset, and a committed Datatype in the target + * create Groups, a Dataset, a committed Datatype, and external links in + * the target *------------------------------------------------------------------------- */ gid = H5Gcreate2(target_fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + H5Gclose(H5Gcreate2(target_fid, "empty_group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)); sid = H5Screate_simple(1, dims, NULL); did = H5Dcreate2(gid, "dset", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); H5Dwrite(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); + H5Lcreate_external(FILE61, "/", gid, "elink_t1", H5P_DEFAULT, H5P_DEFAULT); + H5Lcreate_external(FILE61, "/ext_link4", gid, "elink_t2", H5P_DEFAULT, H5P_DEFAULT); H5Dclose(did); H5Sclose(sid); H5Gclose(gid); @@ -6229,6 +6233,8 @@ gent_extlinks(void) H5Lcreate_external(FILE62, "group", source_fid, "ext_link1", H5P_DEFAULT, H5P_DEFAULT); H5Lcreate_external(FILE62, "dset", source_fid, "ext_link2", H5P_DEFAULT, H5P_DEFAULT); H5Lcreate_external(FILE62, "type", source_fid, "ext_link3", H5P_DEFAULT, H5P_DEFAULT); + H5Lcreate_external(FILE62, "group/elink_t2", source_fid, "ext_link4", H5P_DEFAULT, H5P_DEFAULT); + H5Lcreate_external(FILE62, "empty_group", source_fid, "ext_link5", H5P_DEFAULT, H5P_DEFAULT); /* close */ H5Fclose(source_fid); diff --git a/tools/h5ls/h5ls.c b/tools/h5ls/h5ls.c index 357dacf..7850a59 100644 --- a/tools/h5ls/h5ls.c +++ b/tools/h5ls/h5ls.c @@ -31,10 +31,25 @@ #define NAME_BUF_SIZE 2048 +/* Struct to keep track of external link targets visited */ +typedef struct elink_trav_t { + size_t nalloc; + size_t nused; + struct { + char *file; + char *path; + } *objs; +} elink_trav_t; + /* Struct to pass through to visitors */ typedef struct { const char *fname; /* Filename */ + hid_t fid; /* File ID */ hid_t gid; /* Group ID */ + hbool_t ext_target; /* Whether this is the target of an external link */ + elink_trav_t *elink_list; /* List of visited external links */ + int base_len; /* Length of base path name, if not root */ + int name_start; /* # of leading characters to strip off path names on output */ }iter_t; /* Command-line switches */ @@ -70,6 +85,7 @@ static struct dispatch_t { } static void display_type(hid_t type, int ind); +static herr_t visit_obj(hid_t file, const char *oname, iter_t *iter); const char *progname="h5ls"; int d_status; @@ -223,9 +239,9 @@ display_obj_name(FILE *stream, const iter_t *iter, const char *oname, int n; if(show_file_name_g) - sprintf(fullname, "%s/%s", iter->fname, oname); + sprintf(fullname, "%s/%s", iter->fname, oname + iter->name_start); else - name = oname; + name = oname + iter->name_start; /* Print the object name, either full name or base name */ if(fullname_g) @@ -1661,13 +1677,16 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void iter_t *iter = (iter_t*)_iter; /* Print the link's name, either full name or base name */ - display_obj_name(stdout, iter, name, ""); + if(!iter->ext_target) + display_obj_name(stdout, iter, name, ""); /* Check object information */ if(oinfo->type < 0 || oinfo->type >= H5O_TYPE_NTYPES) { printf("Unknown type(%d)", (int)oinfo->type); obj_type = H5O_TYPE_UNKNOWN; } + if(iter->ext_target) + fputc('{', stdout); if(obj_type >= 0 && dispatch_g[obj_type].name) fputs(dispatch_g[obj_type].name, stdout); @@ -1675,7 +1694,8 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void if(first_seen) { printf(", same as "); display_string(stdout, first_seen, TRUE); - printf("\n"); + if(!iter->ext_target) + printf("\n"); } /* end if */ else { hid_t obj = (-1); /* ID of object opened */ @@ -1683,7 +1703,7 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void /* Open the object. Not all objects can be opened. If this is the case * then return right away. */ - if(obj_type >= 0 && (obj = H5Oopen(iter->gid, name, H5P_DEFAULT)) < 0) { + if(obj_type >= 0 && (obj = H5Oopen(iter->fid, name, H5P_DEFAULT)) < 0) { printf(" *ERROR*\n"); goto done; } /* end if */ @@ -1691,7 +1711,8 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void /* List the first line of information for the object. */ if(obj_type >= 0 && dispatch_g[obj_type].list1) (dispatch_g[obj_type].list1)(obj); - putchar('\n'); + if(!iter->ext_target || (verbose_g > 0)) + putchar('\n'); /* Show detailed information about the object, beginning with information * which is common to all objects. */ @@ -1742,11 +1763,89 @@ list_obj(const char *name, const H5O_info_t *oinfo, const char *first_seen, void } /* end else */ done: + if(iter->ext_target) { + fputs("}\n", stdout); + iter->ext_target = FALSE; + } return 0; } /* end list_obj() */ /*------------------------------------------------------------------------- + * Function: elink_trav_add + * + * Purpose: Add an external link to visited data structure + * + * Return: 0 on success, -1 on failure + * + * Programmer: Neil Fortner, nfortne2@hdfgroup.org + * Adapted from trav_addr_add in h5trav.c by Quincey Koziol + * + * Date: September 5, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +elink_trav_add(elink_trav_t *visited, const char *file, const char *path) +{ + size_t idx; /* Index of address to use */ + void *tmp_ptr; + + /* Allocate space if necessary */ + if(visited->nused == visited->nalloc) { + visited->nalloc = MAX(1, visited->nalloc * 2); + if(NULL == (tmp_ptr = HDrealloc(visited->objs, visited->nalloc * sizeof(visited->objs[0])))) + return -1; + visited->objs = tmp_ptr; + } /* end if */ + + /* Append it */ + idx = visited->nused++; + if(NULL == (visited->objs[idx].file = HDstrdup(file))) { + visited->nused--; + return -1; + } + if(NULL == (visited->objs[idx].path = HDstrdup(path))) { + visited->nused--; + HDfree (visited->objs[idx].file); + return -1; + } + + return 0; +} /* end elink_trav_add() */ + + +/*------------------------------------------------------------------------- + * Function: elink_trav_visited + * + * Purpose: Check if an external link has already been visited + * + * Return: TRUE/FALSE + * + * Programmer: Neil Fortner, nfortne2@hdfgroup.org + * Adapted from trav_addr_visited in h5trav.c by Quincey Koziol + * + * Date: September 5, 2008 + * + *------------------------------------------------------------------------- + */ +static hbool_t +elink_trav_visited(elink_trav_t *visited, const char *file, const char *path) +{ + size_t u; /* Local index variable */ + + /* Look for elink */ + for(u = 0; u < visited->nused; u++) + /* Check for elink value already in array */ + if(!HDstrcmp(visited->objs[u].file, file) && !HDstrcmp(visited->objs[u].path, path)) + return(TRUE); + + /* Didn't find elink */ + return(FALSE); +} /* end elink_trav_visited() */ + + +/*------------------------------------------------------------------------- * Function: list_lnk * * Purpose: Prints information about a link @@ -1769,19 +1868,20 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter) /* Print the link's name, either full name or base name */ display_obj_name(stdout, iter, name, ""); - HDfputs("-> ", stdout); switch(linfo->type) { case H5L_TYPE_SOFT: if((buf = HDmalloc(linfo->u.val_size)) == NULL) goto done; - if(H5Lget_val(iter->gid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) { + if(H5Lget_val(iter->fid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) { HDfree(buf); goto done; } /* end if */ + HDfputs("Soft Link {", stdout); HDfputs(buf, stdout); HDfree(buf); + HDfputs("}\n", stdout); break; case H5L_TYPE_EXTERNAL: @@ -1791,8 +1891,7 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter) if((buf = HDmalloc(linfo->u.val_size)) == NULL) goto done; - - if(H5Lget_val(iter->gid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) { + if(H5Lget_val(iter->fid, name, buf, linfo->u.val_size, H5P_DEFAULT) < 0) { HDfree(buf); goto done; } /* end if */ @@ -1801,19 +1900,50 @@ list_lnk(const char *name, const H5L_info_t *linfo, void *_iter) goto done; } /* end if */ - HDfputs("file: ", stdout); + HDfputs("External Link {", stdout); HDfputs(filename, stdout); - HDfputs(" path: ", stdout); + HDfputc('/', stdout); + if(*path != '/') + HDfputc('/', stdout); HDfputs(path, stdout); + HDfputs("} ", stdout); + + /* Recurse through the external link */ + if(recursive_g) { + /* Check if we have already seen this elink */ + if(elink_trav_visited(iter->elink_list, filename, path)) { + HDfputs("{Already Visited}\n", stdout); + HDfree(buf); + goto done; + } + + /* Add this link to the list of seen elinks */ + if(elink_trav_add(iter->elink_list, filename, path) < 0) { + HDfree(buf); + goto done; + } + + /* Adjust user data to specify that we are operating on the + * target of an external link */ + iter->ext_target = TRUE; + + /* Recurse through the external link */ + if(visit_obj(iter->fid, name, iter) < 0) { + HDfree(buf); + goto done; + } + } + else + HDfputc('\n', stdout); + HDfree(buf); } break; default: - HDfputs("cannot follow UD links", stdout); + HDfputs("UD Link {cannot follow UD links}\n", stdout); break; } /* end switch */ - HDfputc('\n', stdout); done: return 0; @@ -1821,6 +1951,70 @@ done: /*------------------------------------------------------------------------- + * Function: visit_obj + * + * Purpose: Begins iteration on an object + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Neil Fortner + * Wednesday, August 21, 2008 + * Mostly copied from main() + * + *------------------------------------------------------------------------- + */ +static herr_t +visit_obj(hid_t file, const char *oname, iter_t *iter) +{ + H5O_info_t oi; /* Information for object */ + + /* Retrieve info for object to list */ + if(H5Oget_info_by_name(file, oname, &oi, H5P_DEFAULT) < 0) { + if(iter->ext_target) { + HDfputs("{**NOT FOUND**}\n", stdout); + iter->ext_target = FALSE; + } + else + display_obj_name(stdout, iter, oname, "**NOT FOUND**"); + return -1; + } /* end if */ + + /* Check for group iteration */ + if(H5O_TYPE_GROUP == oi.type && !grp_literal_g) { + /* Get ID for group */ + if(!iter->ext_target && (iter->gid = H5Gopen2(file, oname, H5P_DEFAULT)) < 0) { + fprintf(stderr, "%s: unable to open '%s' as group\n", iter->fname, oname); + return 0; /* Previously "continue", when this code was in main(). + * We don't "continue" here in order to close the file + * and free the file name properly. */ + } /* end if */ + + /* Delay specifying the name start point so the original object name is + * displayed if it is a link or non-group object */ + iter->name_start = iter->base_len; + + /* Specified name is a group. List the complete contents of the group. */ + h5trav_visit(file, oname, (hbool_t) (display_root_g || iter->ext_target), recursive_g, list_obj, list_lnk, iter); + + /* Close group */ + if(!iter->ext_target) + H5Gclose(iter->gid); + } /* end if */ + else { + /* Use file ID for root group ID */ + iter->gid = file; + + /* Specified name is a non-group object -- list that object */ + list_obj(oname, &oi, NULL, iter); + } /* end else */ + + return 0; +} + + +/*------------------------------------------------------------------------- * Function: get_width * * Purpose: Figure out how wide the screen is. This is highly @@ -2144,6 +2338,8 @@ main(int argc, const char *argv[]) while(argno < argc) { H5L_info_t li; iter_t iter; + elink_trav_t elink_list; + size_t u; fname = HDstrdup(argv[argno++]); oname = NULL; @@ -2169,19 +2365,45 @@ main(int argc, const char *argv[]) } /* end while */ if(file < 0) { fprintf(stderr, "%s: unable to open file\n", argv[argno-1]); + HDfree(fname); continue; } /* end if */ - if(oname) - oname++; + if(oname) { + /* Always use absolute paths to avoid confusion, keep track of where + * to begin path name output */ + *oname = '/'; + iter.base_len = HDstrlen(oname); + iter.base_len -= oname[iter.base_len-1] == '/'; + x = oname; + if(NULL == (oname = HDstrdup(oname))) { + fprintf(stderr, "memory allocation failed\n"); + leave(1); + } + *x = '\0'; + /* Delay specifying the name start point so the original object name + * is displayed if it is a link or non-group object */ + iter.name_start = 1; + } if(!oname || !*oname) { oname = root_name; if(recursive_g) display_root_g = TRUE; + iter.base_len = 0; + iter.name_start = 0; + /* Use x to remember if we have allocated space in oname */ + x = NULL; } /* end if */ /* Remember the file information for later */ iter.fname = fname; + iter.fid = file; iter.gid = -1; + iter.ext_target = FALSE; + iter.elink_list = &elink_list; + + /* Initialize list of visited external links */ + elink_list.nused = elink_list.nalloc = 0; + elink_list.objs = NULL; /* Check for root group as object name */ if(HDstrcmp(oname, root_name)) { @@ -2196,41 +2418,25 @@ main(int argc, const char *argv[]) /* Open the object and display it's information */ if(li.type == H5L_TYPE_HARD) { - H5O_info_t oi; /* Information for object */ - - /* Retrieve info for object to list */ - if(H5Oget_info_by_name(file, oname, &oi, H5P_DEFAULT) < 0) { - display_obj_name(stdout, &iter, oname, "**NOT FOUND**"); + if(visit_obj(file, oname, &iter) < 0) leave(1); - } /* end if */ - - /* Check for group iteration */ - if(H5O_TYPE_GROUP == oi.type && !grp_literal_g) { - /* Get ID for group */ - if((iter.gid = H5Gopen2(file, oname, H5P_DEFAULT)) < 0) { - fprintf(stderr, "%s: unable to open '%s' as group\n", fname, oname); - continue; - } /* end if */ - - /* Specified name is a group. List the complete contents of the group. */ - h5trav_visit(file, oname, display_root_g, recursive_g, list_obj, list_lnk, &iter); - - /* Close group */ - H5Gclose(iter.gid); - } /* end if */ - else { - /* Use file ID for root group ID */ - iter.gid = file; - - /* Specified name is a non-group object -- list that object */ - list_obj(oname, &oi, NULL, &iter); - } /* end else */ - } /* end if */ - else + } /* end if(li.type == H5L_TYPE_HARD) */ + else { /* Specified name is not for object -- list that link */ + /* Use file ID for root group ID */ + iter.gid = file; list_lnk(oname, &li, &iter); + } H5Fclose(file); - free(fname); + HDfree(fname); + if(x) + HDfree(oname); + + for(u=0; u < elink_list.nused; u++) { + HDfree(elink_list.objs[u].file); + HDfree(elink_list.objs[u].path); + } + HDfree(elink_list.objs); } /* end while */ leave(0); diff --git a/tools/h5ls/testh5ls.sh b/tools/h5ls/testh5ls.sh index 6383709..498384c 100755 --- a/tools/h5ls/testh5ls.sh +++ b/tools/h5ls/testh5ls.sh @@ -129,6 +129,9 @@ TOOLTEST tslink-1.ls 0 -w80 -r tslink.h5 # test for displaying external and user-defined links TOOLTEST textlink-1.ls 0 -w80 -r textlink.h5 +TOOLTEST textlinksrc-1.ls 0 -w80 -r textlinksrc.h5 +TOOLTEST textlinksrc-2.ls 0 -w80 -rv textlinksrc.h5/ext_link5 +TOOLTEST textlinksrc-3.ls 0 -w80 -r textlinksrc.h5/ext_link1 TOOLTEST tudlink-1.ls 0 -w80 -r tudlink.h5 # tests for hard links diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c index bb8014d..69b4512 100644 --- a/tools/lib/h5trav.c +++ b/tools/lib/h5trav.c @@ -40,6 +40,8 @@ typedef struct { trav_addr_t *seen; /* List of addresses seen already */ const trav_visitor_t *visitor; /* Information for visiting each link/object */ hbool_t is_absolute; /* Whether the traversal has absolute paths */ + const char *base_grp_name; /* Name of the group that serves as the base + * for iteration */ } trav_ud_traverse_t; typedef struct { @@ -146,9 +148,15 @@ traverse_cb(hid_t loc_id, const char *path, const H5L_info_t *linfo, /* Create the full path name for the link */ if(udata->is_absolute) { - new_name = HDmalloc(HDstrlen(path) + 2); - *new_name = '/'; - HDstrcpy(new_name + 1, path); + size_t base_len = HDstrlen(udata->base_grp_name); + size_t add_slash = base_len ? ((udata->base_grp_name)[base_len-1] != '/') : 1; + + if(NULL == (new_name = HDmalloc(base_len + add_slash + HDstrlen(path) + 1))) + return(H5_ITER_ERROR); + HDstrcpy(new_name, udata->base_grp_name); + if (add_slash) + new_name[base_len] = '/'; + HDstrcpy(new_name + base_len + add_slash, path); full_name = new_name; } /* end if */ else @@ -242,6 +250,7 @@ traverse(hid_t file_id, const char *grp_name, hbool_t visit_start, udata.seen = &seen; udata.visitor = visitor; udata.is_absolute = (*grp_name == '/'); + udata.base_grp_name = grp_name; /* Check for iteration of links vs. visiting all links recursively */ if(recurse) { diff --git a/tools/testfiles/tall-2.ls b/tools/testfiles/tall-2.ls index 2e4cd37..983f515 100644 --- a/tools/testfiles/tall-2.ls +++ b/tools/testfiles/tall-2.ls @@ -16,9 +16,9 @@ Data: (0) 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 /g1/g1.2 Group -/g1/g1.2/extlink -> file: somefile path: somepath +/g1/g1.2/extlink External Link {somefile//somepath} {**NOT FOUND**} /g1/g1.2/g1.2.1 Group -/g1/g1.2/g1.2.1/slink -> somevalue +/g1/g1.2/g1.2.1/slink Soft Link {somevalue} /g2 Group /g2/dset2.1 Dataset {10} Data: @@ -27,4 +27,4 @@ Data: (0,0) 0, 0.1, 0.2, 0.3, 0.4, 0, 0.2, 0.4, 0.6, 0.8, 0, 0.3, 0.6, 0.9, (2,4) 1.2 -/g2/udlink -> cannot follow UD links +/g2/udlink UD Link {cannot follow UD links} diff --git a/tools/testfiles/textlink-1.ls b/tools/testfiles/textlink-1.ls index 87be5a7..aae806e 100644 --- a/tools/testfiles/textlink-1.ls +++ b/tools/testfiles/textlink-1.ls @@ -2,5 +2,5 @@ output for 'h5ls -w80 -r textlink.h5' ############################# / Group -/extlink1 -> file: filename path: objname -/extlink2 -> file: anotherfile path: anotherobj +/extlink1 External Link {filename//objname} {**NOT FOUND**} +/extlink2 External Link {anotherfile//anotherobj} {**NOT FOUND**} diff --git a/tools/testfiles/textlinksrc-1.ls b/tools/testfiles/textlinksrc-1.ls new file mode 100644 index 0000000..44b8948 --- /dev/null +++ b/tools/testfiles/textlinksrc-1.ls @@ -0,0 +1,17 @@ +############################# + output for 'h5ls -w80 -r textlinksrc.h5' +############################# +/ Group +/ext_link1 External Link {textlinktar.h5//group} {Group} +/ext_link1/dset Dataset {6} +/ext_link1/elink_t1 External Link {textlinksrc.h5//} {Group} +/ext_link1/elink_t1/ext_link1 External Link {textlinktar.h5//group} {Already Visited} +/ext_link1/elink_t1/ext_link2 External Link {textlinktar.h5//dset} {Dataset {6}} +/ext_link1/elink_t1/ext_link3 External Link {textlinktar.h5//type} {Type} +/ext_link1/elink_t1/ext_link4 External Link {textlinktar.h5//group/elink_t2} {**NOT FOUND**} +/ext_link1/elink_t1/ext_link5 External Link {textlinktar.h5//empty_group} {Group} +/ext_link1/elink_t2 External Link {textlinksrc.h5//ext_link4} {**NOT FOUND**} +/ext_link2 External Link {textlinktar.h5//dset} {Already Visited} +/ext_link3 External Link {textlinktar.h5//type} {Already Visited} +/ext_link4 External Link {textlinktar.h5//group/elink_t2} {Already Visited} +/ext_link5 External Link {textlinktar.h5//empty_group} {Already Visited} diff --git a/tools/testfiles/textlinksrc-2.ls b/tools/testfiles/textlinksrc-2.ls new file mode 100644 index 0000000..da40ed7 --- /dev/null +++ b/tools/testfiles/textlinksrc-2.ls @@ -0,0 +1,8 @@ +############################# + output for 'h5ls -w80 -rv textlinksrc.h5/ext_link5' +############################# +Opened "textlinksrc.h5" with sec2 driver. +ext_link5 External Link {textlinktar.h5//empty_group} {Group + Location: 3:1832 + Links: 1 +} diff --git a/tools/testfiles/textlinksrc-3.ls b/tools/testfiles/textlinksrc-3.ls new file mode 100644 index 0000000..91ff216 --- /dev/null +++ b/tools/testfiles/textlinksrc-3.ls @@ -0,0 +1,12 @@ +############################# + output for 'h5ls -w80 -r textlinksrc.h5/ext_link1' +############################# +ext_link1 External Link {textlinktar.h5//group} {Group} +/dset Dataset {6} +/elink_t1 External Link {textlinksrc.h5//} {Group} +/elink_t1/ext_link1 External Link {textlinktar.h5//group} {Already Visited} +/elink_t1/ext_link2 External Link {textlinktar.h5//dset} {Dataset {6}} +/elink_t1/ext_link3 External Link {textlinktar.h5//type} {Type} +/elink_t1/ext_link4 External Link {textlinktar.h5//group/elink_t2} {**NOT FOUND**} +/elink_t1/ext_link5 External Link {textlinktar.h5//empty_group} {Group} +/elink_t2 External Link {textlinksrc.h5//ext_link4} {**NOT FOUND**} diff --git a/tools/testfiles/textlinksrc.h5 b/tools/testfiles/textlinksrc.h5 new file mode 100644 index 0000000..062acbe Binary files /dev/null and b/tools/testfiles/textlinksrc.h5 differ diff --git a/tools/testfiles/textlinktar.h5 b/tools/testfiles/textlinktar.h5 new file mode 100644 index 0000000..bf009eb Binary files /dev/null and b/tools/testfiles/textlinktar.h5 differ diff --git a/tools/testfiles/tslink-1.ls b/tools/testfiles/tslink-1.ls index 4c16958..6c3467a 100644 --- a/tools/testfiles/tslink-1.ls +++ b/tools/testfiles/tslink-1.ls @@ -2,5 +2,5 @@ output for 'h5ls -w80 -r tslink.h5' ############################# / Group -/slink1 -> somevalue -/slink2 -> linkvalue +/slink1 Soft Link {somevalue} +/slink2 Soft Link {linkvalue} diff --git a/tools/testfiles/tudlink-1.ls b/tools/testfiles/tudlink-1.ls index b8578ce..d34ef4d 100644 --- a/tools/testfiles/tudlink-1.ls +++ b/tools/testfiles/tudlink-1.ls @@ -2,5 +2,5 @@ output for 'h5ls -w80 -r tudlink.h5' ############################# / Group -/udlink1 -> cannot follow UD links -/udlink2 -> cannot follow UD links +/udlink1 UD Link {cannot follow UD links} +/udlink2 UD Link {cannot follow UD links} -- cgit v0.12