From 41cea953dd4a69e4d375265f490b8f8e498bcf76 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Tue, 7 Apr 2009 18:04:19 -0500 Subject: [svn-r16694] Purpose: Fix bug 1526 Description: Previously, H5Lcopy and H5Lmove would (through H5L_move) improperly apply the "create intermediate groups" property to the source path traversal, and not the destination. Fixed it to apply the property to the destination and not the source. Also fixed H5Lcreate_ud to reject internal link classes without throwing an assertion. Tested: linew, jam, smirom (h5committtest) --- release_docs/RELEASE.txt | 2 ++ src/H5L.c | 15 ++++++--- test/links.c | 8 +++++ test/tmisc.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 4 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index d11a8b9..7c93e6c 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -151,6 +151,8 @@ Bug Fixes since HDF5-1.8.0 release Library ------- + - Fixed a bug where H5Lcopy and H5Lmove wouldn't create intermediate + groups when that property was set. (NAF - 2009/04/07 - 1526) - Fixed a bug that caused files with a user block to grow by the size of the user block every time they were opened. (NAF - 2009/03/26 - 1499) diff --git a/src/H5L.c b/src/H5L.c index 368272b..7066acc 100644 --- a/src/H5L.c +++ b/src/H5L.c @@ -82,6 +82,7 @@ typedef struct { const char *dst_name; /* Destination name for moving object */ H5T_cset_t cset; /* Char set for new name */ H5G_loc_t *dst_loc; /* Destination location for moving object */ + unsigned dst_target_flags; /* Target flags for destination object */ hbool_t copy; /* TRUE if this is a copy operation */ hid_t lapl_id; /* LAPL to use in callback */ hid_t dxpl_id; /* DXPL to use in callback */ @@ -557,6 +558,8 @@ H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!link_name || !*link_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified") + if(link_type < H5L_TYPE_UD_MIN || link_type > H5L_TYPE_MAX) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link class") /* Create external link */ if(H5L_create_ud(&link_loc, link_name, udata, udata_size, link_type, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) @@ -2528,7 +2531,8 @@ H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, orig_name = H5MM_xstrdup(name); /* Insert the link into its new location */ - if(H5G_traverse(udata->dst_loc, udata->dst_name, H5G_TARGET_NORMAL, H5L_move_dest_cb, &udata_out, udata->lapl_id, udata->dxpl_id) < 0) + if(H5G_traverse(udata->dst_loc, udata->dst_name, udata->dst_target_flags, + H5L_move_dest_cb, &udata_out, udata->lapl_id, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") /* If this is a move and not a copy operation, change the object's name and remove the old link */ @@ -2614,7 +2618,7 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id) { - unsigned target_flags = H5G_TARGET_MOUNT|H5G_TARGET_SLINK|H5G_TARGET_UDLINK; + unsigned dst_target_flags = H5G_TARGET_NORMAL; H5T_cset_t char_encoding = H5F_DEFAULT_CSET; /* Character encoding for link */ H5P_genplist_t* lc_plist; /* Link creation property list */ H5P_genplist_t* la_plist; /* Link access property list */ @@ -2641,8 +2645,9 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, if(H5P_get(lc_plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups") + /* Set target flags for source and destination */ if(crt_intmd_group > 0) - target_flags |= H5G_CRT_INTMD_GROUP; + dst_target_flags |= H5G_CRT_INTMD_GROUP; /* Get character encoding property */ if(H5P_get(lc_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &char_encoding) < 0) @@ -2664,13 +2669,15 @@ H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, /* Set up user data */ udata.dst_loc = dst_loc; udata.dst_name= dst_name; + udata.dst_target_flags = dst_target_flags; udata.cset = char_encoding; udata.copy = copy_flag; udata.lapl_id = lapl_copy; udata.dxpl_id = dxpl_id; /* Do the move */ - if(H5G_traverse(src_loc, src_name, target_flags, H5L_move_cb, &udata, lapl_id, dxpl_id) < 0) + if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT | H5G_TARGET_SLINK | H5G_TARGET_UDLINK, + H5L_move_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to find link") done: diff --git a/test/links.c b/test/links.c index c169670..d9e9b52 100644 --- a/test/links.c +++ b/test/links.c @@ -7177,6 +7177,14 @@ ud_link_errors(hid_t fapl, hbool_t new_format) if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR if(H5Gclose(gid) < 0) FAIL_STACK_ERROR + /* Try to create internally defined links with H5Lcreate_ud */ + H5E_BEGIN_TRY { + if(H5Lcreate_ud(fid, "/ud_link", H5L_TYPE_HARD, NULL, 0, H5P_DEFAULT, H5P_DEFAULT) >= 0) + TEST_ERROR + if(H5Lcreate_ud(fid, "/ud_link", H5L_TYPE_SOFT, "str", 4, H5P_DEFAULT, H5P_DEFAULT) >= 0) + TEST_ERROR + } H5E_END_TRY + /* Create a user-defined link to the group. */ strcpy(group_name, "/group"); if(H5Lcreate_ud(fid, "/ud_link", UD_CBFAIL_TYPE, &group_name, HDstrlen(group_name) + 1, H5P_DEFAULT, H5P_DEFAULT) < 0) FAIL_STACK_ERROR diff --git a/test/tmisc.c b/test/tmisc.c index 4db800c..b646a69 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -3779,6 +3779,7 @@ test_misc23(void) tmp_id=0, create_id=H5P_DEFAULT, access_id=H5P_DEFAULT; char objname[MISC23_NAME_BUF_SIZE]; /* Name of object */ H5O_info_t oinfo; + htri_t tri_status; herr_t status; /* Output message about test being performed */ @@ -4022,6 +4023,87 @@ test_misc23(void) status = H5Pclose(create_id); CHECK(status, FAIL, "H5Pclose"); + /********************************************************************** + * test H5Lcopy() + **********************************************************************/ + + /* Create link creation property list */ + create_id = H5Pcreate(H5P_LINK_CREATE); + CHECK(create_id, FAIL, "H5Pcreate"); + + /* Set flag for intermediate group creation */ + status = H5Pset_create_intermediate_group(create_id, TRUE); + CHECK(status, FAIL, "H5Pset_create_intermediate_group"); + + status = H5Lcopy(file_id, "/A/B01/grp", file_id, "/A/B16/grp", create_id, access_id); + CHECK(status, FAIL, "H5Lcopy"); + + tri_status = H5Lexists(file_id, "/A/B16/grp", access_id); + VERIFY(tri_status, TRUE, "H5Lexists"); + + tri_status = H5Lexists(file_id, "/A/B01/grp", access_id); + VERIFY(tri_status, TRUE, "H5Lexists"); + + /********************************************************************** + * test H5Lmove() + **********************************************************************/ + + status = H5Lmove(file_id, "/A/B16/grp", file_id, "/A/B17/grp", create_id, access_id); + CHECK(status, FAIL, "H5Lmove"); + + tri_status = H5Lexists(file_id, "/A/B17/grp", access_id); + VERIFY(tri_status, TRUE, "H5Lexists"); + + tri_status = H5Lexists(file_id, "/A/B16/grp", access_id); + VERIFY(tri_status, FALSE, "H5Lexists"); + + /********************************************************************** + * test H5Lcreate_hard() + **********************************************************************/ + + status = H5Lcreate_hard(file_id, "/A/B01/grp", file_id, "/A/B18/grp", create_id, access_id); + CHECK(status, FAIL, "H5Lcreate_hard"); + + tri_status = H5Lexists(file_id, "/A/B18/grp", access_id); + VERIFY(tri_status, TRUE, "H5Lexists"); + + /********************************************************************** + * test H5Lcreate_soft() + **********************************************************************/ + + status = H5Lcreate_soft("/A/B01/grp", file_id, "/A/B19/grp", create_id, access_id); + CHECK(status, FAIL, "H5Lcreate_soft"); + + tri_status = H5Lexists(file_id, "/A/B19/grp", access_id); + VERIFY(tri_status, TRUE, "H5Lexists"); + + /********************************************************************** + * test H5Lcreate_external() + **********************************************************************/ + + status = H5Lcreate_external("fake_filename", "fake_path", file_id, "/A/B20/grp", create_id, access_id); + CHECK(status, FAIL, "H5Lcreate_external"); + + tri_status = H5Lexists(file_id, "/A/B20/grp", access_id); + VERIFY(tri_status, TRUE, "H5Lexists"); + + /********************************************************************** + * test H5Lcreate_ud() + **********************************************************************/ + + status = H5Lcreate_ud(file_id, "/A/B21/grp", H5L_TYPE_EXTERNAL, "file\0obj", (size_t) 9, create_id, access_id); + CHECK(status, FAIL, "H5Lcreate_ud"); + + tri_status = H5Lexists(file_id, "/A/B21/grp", access_id); + VERIFY(tri_status, TRUE, "H5Lexists"); + + /********************************************************************** + * close + **********************************************************************/ + + status = H5Pclose(create_id); + CHECK(status, FAIL, "H5Pclose"); + status = H5Gclose(group_id); CHECK(status, FAIL, "H5Gclose"); -- cgit v0.12