[svn-r17860] Description:

"Normalize" object names for external links, making them into the same
form as used for soft links.

	Begin the process of adding more printf-like information to library
error reporting.  HGOTO_ERROR() and HDONE_ERROR() macros can now use the last
parameter (a string) like a printf() formatting string and pass extra
parameters with additional information.  (For example, see the HGOTO_ERROR
macros in H5FD_sec2_read() in src/H5FDsec2.c)

Tested on:
        FreeBSD/32 6.3 (duty) in debug mode
        FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode
        Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
                w/C++ & FORTRAN, w/threadsafe, in debug mode
        Linux/64-amd64 2.6 (smirom) w/Intel compilers, w/default API=1.6.x,
                w/C++ & FORTRAN, in production mode
        Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
                w/szip filter, in production mode
        Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
                in production mode
        Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode
        Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode
        Mac OS X/32 10.6.2 (amazon) in debug mode
        Mac OS X/32 10.6.2 (amazon) w/C++ & FORTRAN, w/threadsafe,
                in production mode
This commit is contained in:
Quincey Koziol 2009-11-10 12:11:34 -05:00
parent e8f31a2479
commit a83a4ece41
6 changed files with 58 additions and 36 deletions

View File

@ -32,14 +32,14 @@ typedef struct H5E_t H5E_t;
* and a FUNC_LEAVE() within a function body. The arguments are the major
* error number, the minor error number, and a description of the error.
*/
#define HERROR(maj_id, min_id, str) H5E_push_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, str)
#define HERROR(maj_id, min_id, ...) H5E_printf_stack(NULL, __FILE__, FUNC, __LINE__, H5E_ERR_CLS_g, maj_id, min_id, __VA_ARGS__)
/*
* HCOMMON_ERROR macro, used by HDONE_ERROR and HGOTO_ERROR
* (Shouldn't need to be used outside this header file)
*/
#define HCOMMON_ERROR(maj, min, str) \
HERROR(maj, min, str); \
#define HCOMMON_ERROR(maj, min, ...) \
HERROR(maj, min, __VA_ARGS__); \
err_occurred = TRUE;
/*
@ -51,8 +51,8 @@ typedef struct H5E_t H5E_t;
* (This macro can also be used to push an error and set the return value
* without jumping to any labels)
*/
#define HDONE_ERROR(maj, min, ret_val, str) { \
HCOMMON_ERROR(maj, min, str); \
#define HDONE_ERROR(maj, min, ret_val, ...) { \
HCOMMON_ERROR(maj, min, __VA_ARGS__); \
ret_value = ret_val; \
}
@ -63,8 +63,8 @@ typedef struct H5E_t H5E_t;
* error string. The return value is assigned to a variable `ret_value' and
* control branches to the `done' label.
*/
#define HGOTO_ERROR(maj, min, ret_val, str) { \
HCOMMON_ERROR(maj, min, str); \
#define HGOTO_ERROR(maj, min, ret_val, ...) { \
HCOMMON_ERROR(maj, min, __VA_ARGS__); \
HGOTO_DONE(ret_val) \
}

View File

@ -732,11 +732,11 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id,
/* Check for overflow conditions */
if(!H5F_addr_defined(addr))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr)
if(REGION_OVERFLOW(addr, size))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
if((addr + size) > file->eoa)
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
/* Seek to the correct location */
if((addr != file->pos || OP_READ != file->op) &&
@ -813,11 +813,11 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had
/* Check for overflow conditions */
if(!H5F_addr_defined(addr))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined")
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr)
if(REGION_OVERFLOW(addr, size))
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
if((addr + size) > file->eoa)
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow")
HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr)
/* Seek to the correct location */
if((addr != file->pos || OP_WRITE != file->op) &&

View File

@ -890,7 +890,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
{
H5G_trav_goi_t *udata = (H5G_trav_goi_t *)_udata; /* User data passed in */
@ -900,7 +900,7 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_
/* Check if the name in this group resolved to a valid link */
if(lnk == NULL && obj_loc == NULL)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name)
/* Only modify user's buffer if it's available */
if(udata->statbuf) {

View File

@ -716,7 +716,7 @@ H5Lget_val(hid_t loc_id, const char *name, void *buf/*out*/, size_t size,
/* Get the link value */
if(H5L_get_val(&loc, name, buf, size, lapl_id, H5AC_ind_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value")
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value for '%s'", name)
done:
FUNC_LEAVE_API(ret_value)
@ -2120,7 +2120,7 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char *name, const H5O_link_t *lnk,
H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
{
H5L_trav_gv_t *udata = (H5L_trav_gv_t *)_udata; /* User data passed in */
@ -2130,7 +2130,7 @@ H5L_get_val_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H
/* Check if the name in this group resolved to a valid link */
if(lnk == NULL)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name)
/* Retrieve the value for the link */
if(H5L_get_val_real(lnk, udata->buf, udata->size) < 0)

View File

@ -514,6 +514,7 @@ H5Lcreate_external(const char *file_name, const char *obj_name,
hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t link_loc; /* Group location to create link */
char *norm_obj_name = NULL; /* Pointer to normalized current name */
void *ext_link_buf = NULL; /* Buffer to contain external link */
size_t buf_size; /* Size of buffer to hold external link */
uint8_t *p; /* Pointer into external link buffer */
@ -533,8 +534,12 @@ H5Lcreate_external(const char *file_name, const char *obj_name,
if(!link_name || !*link_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
/* Get normalized copy of the link target */
if(NULL == (norm_obj_name = H5G_normalize(obj_name)))
HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize object name")
/* Combine the filename and link name into a single buffer to give to the UD link */
buf_size = 1 + (HDstrlen(file_name) + 1) + (HDstrlen(obj_name) + 1);
buf_size = 1 + (HDstrlen(file_name) + 1) + (HDstrlen(norm_obj_name) + 1);
if(NULL == (ext_link_buf = H5MM_malloc(buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate udata buffer")
@ -543,14 +548,14 @@ H5Lcreate_external(const char *file_name, const char *obj_name,
*p++ = (H5L_EXT_VERSION << 4) | H5L_EXT_FLAGS_ALL; /* External link version & flags */
HDstrcpy((char *)p, file_name); /* Name of file containing external link's object */
p += HDstrlen(file_name) + 1;
HDstrcpy((char *)p, obj_name); /* External link's object */
HDstrcpy((char *)p, norm_obj_name); /* External link's object */
/* Create an external link */
if(H5L_create_ud(&link_loc, link_name, ext_link_buf, buf_size, H5L_TYPE_EXTERNAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
done:
if(ext_link_buf != NULL)
if(norm_obj_name)
H5MM_free(ext_link_buf);
FUNC_LEAVE_API(ret_value)

View File

@ -1794,6 +1794,30 @@ external_link_root(hid_t fapl, hbool_t new_format)
goto error;
}
/* Create external link to object in first file */
/* (add a few extra '/'s to make certain library normalizes external link object names) */
if(H5Lcreate_external(filename1, "///", fid, "ext_link2", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* Check information for external link */
if(H5Lget_info(fid, "ext_link", &linfo, H5P_DEFAULT) < 0) goto error;
if(H5L_TYPE_EXTERNAL != linfo.type) {
H5_FAILED();
puts(" Unexpected object type - should have been an external link");
goto error;
}
if(H5Lget_val(fid, "ext_link", objname, sizeof(objname), H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lunpack_elink_val(objname, linfo.u.val_size, NULL, &file, &path) < 0) TEST_ERROR
if(HDstrcmp(file, filename1)) {
H5_FAILED();
puts(" External link file name incorrect");
goto error;
}
if(HDstrcmp(path, "/")) {
H5_FAILED();
puts(" External link path incorrect");
goto error;
}
/* Close and re-open file to ensure that data is written to disk */
if(H5Fclose(fid) < 0) TEST_ERROR
if((fid = H5Fopen(filename2, H5F_ACC_RDWR, fapl)) < 0) TEST_ERROR
@ -3411,8 +3435,8 @@ external_link_reltar(hid_t fapl, hbool_t new_format)
h5_fixname(FILENAME[26], fapl, filename2, sizeof filename2);
/* Create the target file */
if((fid=H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((gid=H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
if((fid = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((gid = H5Gcreate2(fid, "A", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR
/* closing for target file */
if(H5Gclose(gid) < 0) TEST_ERROR
@ -3420,25 +3444,17 @@ external_link_reltar(hid_t fapl, hbool_t new_format)
/* Create the main file */
if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
if((fid = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
/* Create external link to target file */
if(H5Lcreate_external(filename2, "/A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
if(H5Lcreate_external(filename2, "///A", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* Open object through external link */
H5E_BEGIN_TRY {
gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT);
} H5E_END_TRY;
/*
* Should be able to find the target file from:
* main file's current working directory + pathname of external linked targetfile
*/
if (gid < 0) {
if((gid = H5Gopen2(fid, "ext_link", H5P_DEFAULT)) < 0) {
H5_FAILED();
puts(" Should have found the file in tmp directory.");
goto error;
}
} /* end if */
/* closing for main file */
if(H5Gclose(gid) < 0) TEST_ERROR
@ -5301,7 +5317,8 @@ external_link_query(hid_t fapl, hbool_t new_format)
if((fid=H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
/* Create external link */
if(H5Lcreate_external(filename2, "/dst", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* (add a few extra '/'s to make certain library normalizes external link object names) */
if(H5Lcreate_external(filename2, "///dst//", fid, "src", H5P_DEFAULT, H5P_DEFAULT) < 0) TEST_ERROR
/* Get size of buffer for external link */
if(H5Lget_info(fid, "src", &li, H5P_DEFAULT) < 0) TEST_ERROR