diff options
-rw-r--r-- | src/H5G.c | 29 | ||||
-rw-r--r-- | src/H5Gpublic.h | 1 | ||||
-rw-r--r-- | test/extend.c | 2 | ||||
-rw-r--r-- | test/hyperslab.c | 3 | ||||
-rw-r--r-- | test/links.c | 261 | ||||
-rw-r--r-- | test/mtime.c | 1 |
6 files changed, 265 insertions, 32 deletions
@@ -1961,6 +1961,7 @@ H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, const char *s = NULL; H5D_t *temp_dset = NULL; H5G_t *temp_grp = NULL; + H5T_t *temp_type = NULL; FUNC_ENTER (H5G_stat, FAIL); @@ -1980,7 +1981,22 @@ H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, * length is specific to symbolic links. */ if (statbuf) { - if (H5G_CACHED_SLINK!=obj_ent.type) { + if (H5G_CACHED_SLINK==obj_ent.type) { + /* Named object is a symbolic link */ + if (NULL==H5O_read (&grp_ent, H5O_STAB, 0, &stab_mesg) || + NULL==(s=H5HL_peek (grp_ent.file, &(stab_mesg.heap_addr), + obj_ent.cache.slink.lval_offset))) { + HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, + "unable to read symbolic link value"); + } + statbuf->linklen = strlen(s)+1; /*count the null terminator*/ + statbuf->objno[0] = statbuf->objno[1] = 0; + statbuf->nlink = 0; + statbuf->type = H5G_LINK; + statbuf->mtime = 0; + + } else { + /* Some other type of object */ statbuf->objno[0] = (unsigned long)(obj_ent.header.offset); if (sizeof(obj_ent.header.offset)>sizeof(long)) { statbuf->objno[1] = (unsigned long)(obj_ent.header.offset >> @@ -1992,14 +2008,6 @@ H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, H5E_clear(); statbuf->mtime = 0; } - } else { - if (NULL==H5O_read (&grp_ent, H5O_STAB, 0, &stab_mesg) || - NULL==(s=H5HL_peek (grp_ent.file, &(stab_mesg.heap_addr), - obj_ent.cache.slink.lval_offset))) { - HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, - "unable to read symbolic link value"); - } - statbuf->linklen = strlen(s)+1; /*count the null terminator*/ /* * Determining the type of an object is a rather expensive @@ -2012,6 +2020,9 @@ H5G_stat (H5G_t *loc, const char *name, hbool_t follow_link, } else if (NULL!=(temp_grp=H5G_open (loc, name))) { statbuf->type = H5G_GROUP; H5G_close (temp_grp); + } else if (NULL!=(temp_type=H5T_open(loc, name))) { + statbuf->type = H5G_TYPE; + H5T_close(temp_type); } else { statbuf->type = H5G_UNKNOWN; } diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index f4de521..d7b8c6c 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -39,6 +39,7 @@ typedef enum H5G_link_t { #define H5G_LINK 0 /* Object is a symbolic link */ #define H5G_GROUP 1 /* Object is a group */ #define H5G_DATASET 2 /* Object is a dataset */ +#define H5G_TYPE 3 /* Object is a named data type */ /* Information about an object */ typedef struct H5G_stat_t { diff --git a/test/extend.c b/test/extend.c index 15f2322..361592f 100644 --- a/test/extend.c +++ b/test/extend.c @@ -150,7 +150,7 @@ main (void) H5Dclose (dataset); H5Fclose (file); - + printf("All extend tests passed.\n"); cleanup(); return 0; } diff --git a/test/hyperslab.c b/test/hyperslab.c index 5ca810d..b645dfd 100644 --- a/test/hyperslab.c +++ b/test/hyperslab.c @@ -1201,7 +1201,8 @@ main(int argc, char *argv[]) status = test_sub_super(480, 640); nerrors += status < 0 ? 1 : 0; } -/*--- END OF TESTS ---*/ + + /*--- END OF TESTS ---*/ if (nerrors) { printf("***** %d HYPERSLAB TEST%s FAILED! *****\n", diff --git a/test/links.c b/test/links.c index 006bf37..0a766c7 100644 --- a/test/links.c +++ b/test/links.c @@ -10,8 +10,20 @@ #include <hdf5.h> #include <stdlib.h> +#include <H5config.h> +#ifndef HAVE_ATTRIBUTE +# undef __attribute__ +# define __attribute__(X) /*void*/ +# define __unused__ /*void*/ +#else +# define __unused__ __attribute__((unused)) +#endif + #define TEST_FILE_NAME "links.h5" +#define FALSE 0 +#define TRUE 1 + /*------------------------------------------------------------------------- * Function: cleanup @@ -37,54 +49,261 @@ cleanup(void) /*------------------------------------------------------------------------- - * Function: main + * Function: display_error_cb * - * Purpose: Tests links. + * Purpose: Displays the error stack after printing "*FAILED*". * * Return: Success: 0 * - * Failure: non-zero + * Failure: -1 * * Programmer: Robb Matzke - * Friday, April 10, 1998 + * Wednesday, March 4, 1998 * * Modifications: * *------------------------------------------------------------------------- */ -int -main (void) +static herr_t +display_error_cb (void __unused__ *client_data) { - hid_t file, scalar, grp, d1; - hsize_t size[1] = {1}; + puts ("*FAILED*"); + H5Eprint (stdout); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: mklinks + * + * Purpose: Build a file with assorted links. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Friday, August 14, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +mklinks(void) +{ + hid_t file, scalar, grp, d1; + static hsize_t size[1] = {1}; + + printf("%-70s", "Testing link creation"); /* Create a file */ - file = H5Fcreate (TEST_FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); - scalar = H5Screate_simple (1, size, size); + if ((file=H5Fcreate(TEST_FILE_NAME, H5F_ACC_TRUNC, + H5P_DEFAULT, H5P_DEFAULT))<0) { + goto error; + } + if ((scalar=H5Screate_simple (1, size, size))<0) goto error; /* Create a group */ - grp = H5Gcreate (file, "grp1", 0); - H5Gclose (grp); + if ((grp=H5Gcreate (file, "grp1", 0))<0) goto error; + if (H5Gclose (grp)<0) goto error; /* Create a dataset */ - d1 = H5Dcreate (file, "d1", H5T_NATIVE_INT, scalar, H5P_DEFAULT); - H5Dclose (d1); + if ((d1=H5Dcreate (file, "d1", H5T_NATIVE_INT, scalar, H5P_DEFAULT))<0) { + goto error; + } + if (H5Dclose (d1)<0) goto error; /* Create a hard link */ - H5Glink (file, H5G_LINK_HARD, "d1", "grp1/hard"); + if (H5Glink (file, H5G_LINK_HARD, "d1", "grp1/hard")<0) goto error; /* Create a symbolic link */ - H5Glink (file, H5G_LINK_SOFT, "/d1", "grp1/soft"); + if (H5Glink (file, H5G_LINK_SOFT, "/d1", "grp1/soft")<0) goto error; /* Create a symbolic link to something that doesn't exist */ - H5Glink (file, H5G_LINK_SOFT, "foobar", "grp1/dangle"); + if (H5Glink (file, H5G_LINK_SOFT, "foobar", "grp1/dangle")<0) goto error; /* Create a recursive symbolic link */ - H5Glink (file, H5G_LINK_SOFT, "/grp1/recursive", "/grp1/recursive"); - + if (H5Glink (file, H5G_LINK_SOFT, "/grp1/recursive", + "/grp1/recursive")<0) { + goto error; + } + /* Close */ - H5Sclose (scalar); - H5Fclose (file); + if (H5Sclose (scalar)<0) goto error; + if (H5Fclose (file)<0) goto error; + + puts(" PASSED"); + return 0; + + error: + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: cklinks + * + * Purpose: Open the file created in the first step and check that the + * links look correct. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Friday, August 14, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +cklinks(void) +{ + hid_t file; + H5G_stat_t sb1, sb2; + char linkval[1024]; + herr_t status; + + printf("%-70s", "Testing link queries"); + fflush(stdout); + + /* Open the file */ + if ((file=H5Fopen(TEST_FILE_NAME, H5F_ACC_RDONLY, H5P_DEFAULT))<0) { + goto error; + } + + /* Hard link */ + if (H5Gstat(file, "d1", TRUE, &sb1)<0) goto error; + if (H5Gstat(file, "grp1/hard", TRUE, &sb2)<0) goto error; + if (H5G_DATASET!=sb2.type) { + puts("*FAILED*"); + puts(" Unexpected object type should have been a dataset"); + goto error; + } + if (sb1.objno[0]!=sb2.objno[0] || sb1.objno[1]!=sb2.objno[1]) { + puts("*FAILED*"); + puts(" Hard link test failed. Link seems not to point to the "); + puts(" expected file location."); + goto error; + } + + /* Symbolic link */ + if (H5Gstat(file, "grp1/soft", TRUE, &sb2)<0) goto error; + if (H5G_DATASET!=sb2.type) { + puts("*FAILED*"); + puts(" Unexpected object type should have been a dataset"); + goto error; + } + if (sb1.objno[0]!=sb2.objno[0] || sb1.objno[1]!=sb2.objno[1]) { + puts("*FAILED*"); + puts(" Soft link test failed. Link seems not to point to the "); + puts(" expected file location."); + goto error; + } + if (H5Gget_linkval(file, "grp1/soft", sizeof linkval, linkval)<0) { + goto error; + } + if (strcmp(linkval, "/d1")) { + puts("*FAILED*"); + puts(" Soft link test failed. Wrong link value"); + goto error; + } + + /* Dangling link */ + H5E_BEGIN_TRY { + status = H5Gstat(file, "grp1/dangle", TRUE, &sb2); + } H5E_END_TRY; + if (status>=0) { + puts("*FAILED*"); + puts(" H5Gstat() should have failed for a dangling link."); + goto error; + } + if (H5Gstat(file, "grp1/dangle", FALSE, &sb2)<0) goto error; + if (H5G_LINK!=sb2.type) { + puts("*FAILED*"); + puts(" Unexpected object type should have been a symbolic link"); + goto error; + } + if (H5Gget_linkval(file, "grp1/dangle", sizeof linkval, linkval)<0) { + goto error; + } + if (strcmp(linkval, "foobar")) { + puts("*FAILED*"); + puts(" Dangling link test failed. Wrong link value"); + goto error; + } + + /* Recursive link */ + H5E_BEGIN_TRY { + status = H5Gstat(file, "grp1/recursive", TRUE, &sb2); + } H5E_END_TRY; + if (status>=0) { + puts("*FAILED*"); + puts(" H5Gstat() should have failed for a recursive link."); + goto error; + } + if (H5Gstat(file, "grp1/recursive", FALSE, &sb2)<0) goto error; + if (H5G_LINK!=sb2.type) { + puts("*FAILED*"); + puts(" Unexpected object type should have been a symbolic link"); + goto error; + } + if (H5Gget_linkval(file, "grp1/recursive", sizeof linkval, linkval)<0) { + goto error; + } + if (strcmp(linkval, "/grp1/recursive")) { + puts("*FAILED*"); + puts(" Recursive link test failed. Wrong link value"); + goto error; + } + + /* Cleanup */ + if (H5Fclose(file)<0) goto error; + puts(" PASSED"); + return 0; + + error: + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Test links + * + * Return: Success: exit(0) + * + * Failure: exit(non-zero) + * + * Programmer: Robb Matzke + * Friday, August 14, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + int nerrors = 0; + + /* Set error handling to print `*FAILED*' before the error stack */ + H5Eset_auto(display_error_cb, NULL); + + /* The tests... */ + nerrors += mklinks() < 0 ? 1 : 0; + nerrors += cklinks() < 0 ? 1 : 0; + + /* Results */ + if (nerrors) { + printf("***** %d LINK TEST%s FAILED! *****\n", + nerrors, 1 == nerrors ? "" : "S"); + exit(1); + } + printf("All link tests passed.\n"); cleanup(); return 0; } diff --git a/test/mtime.c b/test/mtime.c index 019ce26..6f5327a 100644 --- a/test/mtime.c +++ b/test/mtime.c @@ -142,6 +142,7 @@ main(void) /* All looks good */ puts(" PASSED"); + printf("All modification time tests passed.\n"); cleanup(); return 0; } |