/*------------------------------------------------------------------------- * Function: ud_link_compat * * Purpose: Ensure that User-defined links (introduced in 1.8) can be * handled by HDF5 1.6. * * Return: Success: 0 * Failure: -1 * * Programmer: James Laird * Tuesday, July 25, 2006 * *------------------------------------------------------------------------- */ static int ud_link_compat(hid_t fapl) { hid_t fid = (-1); H5G_stat_t sb; char * srcdir = getenv("srcdir"); /* The source directory */ char pathbuf[NAME_BUF_SIZE]; /* Path to the files */ char namebuf[NAME_BUF_SIZE]; TESTING("compatibility with User-defined links"); /* * Create the name of the file to open (in case we are using the --srcdir * option and the file is in a different directory from this test). */ if (srcdir && ((HDstrlen(srcdir) + 2) < sizeof(pathbuf)) ) { HDstrcpy(pathbuf, srcdir); HDstrcat(pathbuf, "/"); } else HDstrcpy(pathbuf, ""); if(HDstrlen(pathbuf) + HDstrlen(LE_FILENAME) >= sizeof(namebuf)) TEST_ERROR HDstrcpy(namebuf, pathbuf); HDstrcat(namebuf, LE_FILENAME); /* Open a file with an external link in it */ if((fid = H5Fopen(namebuf, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR /* Trying to open the link or get info about it should fail. */ H5E_BEGIN_TRY { if(H5Gopen(fid, "ext_link") >= 0) TEST_ERROR if(H5Gget_objinfo(fid, "ext_link", FALSE, &sb) >= 0) TEST_ERROR } H5E_END_TRY /* There isn't much more we can do with the link. We shouldn't try moving * it or deleting it. */ if(H5Fclose(fid) < 0) TEST_ERROR PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(fid); } H5E_END_TRY return -1; } /* end ud_link_compat() */
/*------------------------------------------------------------------------- * Function: h5_make_local_copy * * Purpose: Make copy of file. Some tests write to data files under that * are under version control. Those tests should make a copy of * the versioned file and write to the copy. This function * prepends srcdir to the name of the file to be copied and uses * the name of the copy as is. * * Return: Success: 0 * * Failure: -1 * * Programmer: Larry Knox * Monday, October 13, 2009 * * Modifications: * *------------------------------------------------------------------------- */ hid_t h5_make_local_copy(char *origfilename, char *local_copy_name) { int fd_old = (-1), fd_new = (-1); /* File descriptors for copying data */ ssize_t nread; /* Number of bytes read in */ char buf[READ_BUF_SIZE]; /* Buffer for copying data */ char filename[FILENAME_BUF_SIZE] = ""; #ifdef H5_VMS HDstrcat(filename, origfilename); #else char * srcdir = HDgetenv("srcdir"); /* The source directory */ if(srcdir && ((HDstrlen(srcdir) + HDstrlen(origfilename) + 6) < FILENAME_BUF_SIZE)) { HDstrcpy(filename, srcdir); HDstrcat(filename, "/"); } HDstrcat(filename, origfilename); #endif /* Copy old file into temporary file */ if((fd_old = HDopen(filename, O_RDONLY, 0666)) < 0) return -1; if((fd_new = HDopen(local_copy_name, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) return -1; /* Copy data */ while((nread = HDread(fd_old, buf, (size_t)READ_BUF_SIZE)) > 0) HDwrite(fd_new, buf, (size_t)nread); /* Close files */ if(HDclose(fd_old) < 0) return -1; if(HDclose(fd_new) < 0) return -1; return 0; }
/**************************************************************** ** ** liter_cb(): Custom link iteration callback routine. ** ****************************************************************/ static herr_t liter_cb(hid_t H5_ATTR_UNUSED group, const char *name, const H5L_info_t H5_ATTR_UNUSED *link_info, void *op_data) { iter_info *info = (iter_info *)op_data; static int count = 0; static int count2 = 0; HDstrcpy(info->name, name); switch(info->command) { case RET_ZERO: return(0); case RET_TWO: return(2); case RET_CHANGE: count++; return(count > 10 ? 1 : 0); case RET_CHANGE2: count2++; return(count2 > 10 ? 1 : 0); default: printf("invalid iteration command"); return(-1); } /* end switch */ } /* end liter_cb() */
/* NAME HDgettagsname -- return a text name of a tag USAGE char * HDgettagsname(tag) uint16 tag; IN: tag of element to find RETURNS Descriptive text or NULL DESCRIPTION Map a tag to a dynamically allocated text name of it. Checks for special elements now. --------------------------------------------------------------------------- */ char * HDgettagsname(uint16 tag) { CONSTR(FUNC, "HDgettagsname"); /* for HERROR */ char *ret = NULL; intn i; if (SPECIALTAG(tag)) ret = (char *) HDstrdup("Special "); tag = BASETAG(tag); for (i = 0; i < (intn)(sizeof(tag_descriptions) / sizeof(tag_descript_t)); i++) if (tag_descriptions[i].tag == tag) { if (ret == NULL) ret = (char *) HDstrdup(tag_descriptions[i].name); else { char *t; t = (char *) HDmalloc(HDstrlen(ret) + HDstrlen(tag_descriptions[i].name) + 2); if (t == NULL) { HDfree(ret); HRETURN_ERROR(DFE_NOSPACE, NULL) } /* end if */ HDstrcpy(t, ret); HDstrcat(t, tag_descriptions[i].name); HDfree(ret); ret = t; } /* end else */ } /* end if */
static void get_unique_name(void) { const char *prefix = NULL; const char *env = HDgetenv("HDF5_PREFIX"); if (env) prefix = env; if (option_prefix) prefix = option_prefix; if (prefix) /* 2 = 1 for '/' + 1 for null terminator */ filename = (char *) HDmalloc(HDstrlen(prefix) + HDstrlen(ZIP_PERF_FILE) + 2); else filename = (char *) HDmalloc(HDstrlen(ZIP_PERF_FILE) + 1); if (!filename) error("out of memory"); filename[0] = 0; if (prefix){ HDstrcpy(filename, prefix); HDstrcat(filename, "/"); } HDstrcat(filename, ZIP_PERF_FILE); }
/*------------------------------------------------------------------------- * Function: H5O_name_decode * * Purpose: Decode a name message and return a pointer to a new * native message struct. * * Return: Success: Ptr to new message in native struct. * * Failure: NULL * * Programmer: Robb Matzke * [email protected] * Aug 12 1997 * *------------------------------------------------------------------------- */ static void * H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, unsigned UNUSED mesg_flags, unsigned UNUSED *ioflags, const uint8_t *p) { H5O_name_t *mesg; void *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* check args */ HDassert(f); HDassert(p); /* decode */ if(NULL == (mesg = (H5O_name_t *)H5MM_calloc(sizeof(H5O_name_t))) || NULL == (mesg->s = (char *)H5MM_malloc(HDstrlen((const char *)p) + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDstrcpy(mesg->s, (const char *)p); /* Set return value */ ret_value = mesg; done: if(NULL == ret_value) { if(mesg) mesg = (H5O_name_t *)H5MM_xfree(mesg); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_name_decode() */
/*-------------------------------------------------------------------------- * Function: H5L_build_name * * Purpose: Prepend PREFIX to FILE_NAME and store in FULL_NAME * * Return: Non-negative on success/Negative on failure * * Programmer: Vailin Choi, April 2, 2008 * * Modification: Raymond Lu, 14 Jan. 2009 * Added support for OpenVMS pathname --------------------------------------------------------------------------*/ static herr_t H5L_build_name(char *prefix, char *file_name, char **full_name/*out*/) { size_t prefix_len; /* length of prefix */ size_t fname_len; /* Length of external link file name */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5L_build_name) prefix_len = HDstrlen(prefix); fname_len = HDstrlen(file_name); /* Allocate a buffer to hold the filename + prefix + possibly the delimiter + terminating null byte */ if(NULL == (*full_name = (char *)H5MM_malloc(prefix_len + fname_len + 2))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate filename buffer") /* Copy the prefix into the buffer */ HDstrcpy(*full_name, prefix); if (!CHECK_DELIMITER(prefix[prefix_len-1])) HDstrcat(*full_name, DIR_SEPS); /* Add the external link's filename to the prefix supplied */ HDstrcat(*full_name, file_name); done: FUNC_LEAVE_NOAPI(ret_value) } /* H5L_build_name() */
//-------------------------------------------------------------------------- // Function: CommonFG::getObjTypeByIdx ///\brief This is an overloaded member function, provided for convenience. /// It differs from the above function because it also provides /// the returned object type in text (char*) ///\param idx - IN: Transient index of the object ///\param type_name - IN: Object type in text ///\return Object type ///\exception H5::FileIException or H5::GroupIException // Programmer Binh-Minh Ribler - May, 2010 //-------------------------------------------------------------------------- H5G_obj_t CommonFG::getObjTypeByIdx(hsize_t idx, char* type_name) const { H5G_obj_t obj_type = H5Gget_objtype_by_idx(getLocId(), idx); switch (obj_type) { case H5G_LINK: HDstrcpy(type_name, "symbolic link"); break; case H5G_GROUP: HDstrcpy(type_name, "group"); break; case H5G_DATASET: HDstrcpy(type_name, "dataset"); break; case H5G_TYPE: HDstrcpy(type_name, "datatype"); break; case H5G_UNKNOWN: default: { throwException("getObjTypeByIdx", "H5Gget_objtype_by_idx failed"); } } return (obj_type); }
/*------------------------------------------------------------------------- * Function: test_family_opens * * Purpose: Private function for test_family() to tests wrong ways of * reopening family file. * * Return: Success: 0 * Failure: -1 * * Programmer: Raymond Lu * Thursday, May 19, 2005 * *------------------------------------------------------------------------- */ static herr_t test_family_opens(char *fname, hid_t fa_pl) { hid_t file; char first_name[1024]; char wrong_name[1024]; int i; /* Case 1: reopen file with 1st member file name and default property list */ HDsnprintf(first_name, sizeof(first_name), fname, 0); H5E_BEGIN_TRY { file = H5Fopen(first_name, H5F_ACC_RDWR, H5P_DEFAULT); } H5E_END_TRY; if(file >= 0) TEST_ERROR /* Case 2: reopen file with correct name template but default property list */ H5E_BEGIN_TRY { file = H5Fopen(fname, H5F_ACC_RDWR, H5P_DEFAULT); } H5E_END_TRY; if(file >= 0) TEST_ERROR /* Case 3: reopen file with wrong member size */ if(H5Pset_fapl_family(fa_pl, (hsize_t)128, H5P_DEFAULT) < 0) TEST_ERROR; H5E_BEGIN_TRY { file = H5Fopen(fname, H5F_ACC_RDWR, fa_pl); } H5E_END_TRY; if(file >= 0) TEST_ERROR /* Case 4: reopen file with wrong name template */ HDstrcpy(wrong_name, fname); for(i = 0; i < 1024; i++) if(wrong_name[i] == '5') { wrong_name[i] = '4'; break; } if(H5Pset_fapl_family(fa_pl, (hsize_t)FAMILY_SIZE, H5P_DEFAULT) < 0) TEST_ERROR; H5E_BEGIN_TRY { file = H5Fopen(wrong_name, H5F_ACC_RDWR, fa_pl); } H5E_END_TRY; if(file >= 0) TEST_ERROR return 0; error: return -1; } /* end test_family_opens() */
void test_an(void) { char labsds[MAXLEN_LAB], labris[MAXLEN_LAB], descsds[MAXLEN_DESC], descris[MAXLEN_DESC]; uint8 pal[768]; uint8 *image, *newimage; uint16 refnum; int32 ret; intn rank; int j; int32 dimsizes[2]; float *data; /* set up object labels and descriptions */ HDstrcpy(labsds, "Object label #1: sds"); HDstrcpy(labris, "Object label #2: image"); HDstrcpy(descsds, "Object Descr #1: 1 2 3 4 5 6 7 8 9 10 11 12 \n"); HDstrcat(descsds, " 13 14 15 16 17 18 19 20 **END SDS DESCR**\n"); HDstrcpy(descris, "Object Descr #2: A B C D E F G H I J K L \n"); HDstrcat(descris, " M N O **END IMAGE DESCR **\n"); /***** generate float array and image *****/ data = (float *) HDmalloc(ROWS * COLS * sizeof(float)); image = (uint8 *) HDmalloc(ROWS * COLS * sizeof(char)); newimage = (uint8 *) HDmalloc(ROWS * COLS * sizeof(char)); dimsizes[0] = ROWS; dimsizes[1] = COLS; gen2Dfloat(ROWS, COLS, data); genimage(ROWS, COLS, data, image); ret = DFSDsetdims(2, dimsizes); RESULT("DFSDsetdims"); /******** Write labels and descriptions *********/ MESSAGE(5, printf("*** Writing labels and descriptions with SDS and RIS ***\n"); );
pack_info_t* options_get_object(const char *path, pack_opttbl_t *table) { unsigned int i; char tbl_path[MAX_NC_NAME + 1]; /* +1 for start with "/" case */ for (i = 0; i < table->nelems; i++) { /* make full path (start with "/") to compare correctly */ if (HDstrncmp(table->objs[i].path, "/", 1)) { HDstrcpy(tbl_path, "/"); HDstrcat(tbl_path, table->objs[i].path); } else HDstrcpy(tbl_path, table->objs[i].path); /* found it */ if (HDstrcmp(tbl_path, path) == 0) { return (&table->objs[i]); } } return NULL; }
/* * Setup a test function and add it to the list of tests. * It must have no parameters and returns void. * TheName--short test name. * If the name starts with '-', do not run it by default. * TheCall--the test routine. * Cleanup--the cleanup routine for the test. * TheDescr--Long description of the test. * Parameters--pointer to extra parameters. Use NULL if none used. * Since only the pointer is copied, the contents should not change. * Return: Void * exit EXIT_FAILURE if error is encountered. */ void AddTest(const char *TheName, void (*TheCall) (void), void (*Cleanup) (void), const char *TheDescr, const void *Parameters) { /* Sanity checking */ if (Index >= MAXNUMOFTESTS) { printf("Too many tests added, increase MAXNUMOFTESTS(%d).\n", MAXNUMOFTESTS); exit(EXIT_FAILURE); } /* end if */ if (HDstrlen(TheDescr) >= MAXTESTDESC) { printf("Test description too long, increase MAXTESTDESC(%d).\n", MAXTESTDESC); exit(EXIT_FAILURE); } /* end if */ if (HDstrlen(TheName) >= MAXTESTNAME) { printf("Test name too long, increase MAXTESTNAME(%d).\n", MAXTESTNAME); exit(EXIT_FAILURE); } /* end if */ /* Set up test function */ HDstrcpy(Test[Index].Description, TheDescr); if (*TheName != '-'){ HDstrcpy(Test[Index].Name, TheName); Test[Index].SkipFlag = 0; } else { /* skip test by default */ HDstrcpy(Test[Index].Name, TheName+1); Test[Index].SkipFlag = 1; } Test[Index].Call = TheCall; Test[Index].Cleanup = Cleanup; Test[Index].NumErrors = -1; Test[Index].Parameters = Parameters; /* Increment test count */ Index++; }
void init_packobject(pack_info_t *obj) { int j, k; HDstrcpy(obj->path, "\0"); for (j = 0; j < H5_REPACK_MAX_NFILTERS; j++) { obj->filter[j].filtn = -1; for (k = 0; k < CD_VALUES; k++) obj->filter[j].cd_values[k] = 0; } obj->chunk.rank = -1; obj->refobj_id = -1; obj->layout = H5D_LAYOUT_ERROR; obj->nfilters = 0; }
/*------------------------------------------------------------------------- * Function: read_new * * Purpose: Test reading a file with "new style" (compact) groups * * Return: Success: 0 * * Failure: -1 * * Programmer: Quincey Koziol * Monday, October 24, 2005 * *------------------------------------------------------------------------- */ static int read_new(hid_t fapl) { hid_t fid = (-1); /* File ID */ hid_t gid = (-1); /* Group ID */ char *srcdir = HDgetenv("srcdir"); /*where the src code is located*/ char filename[512]=""; /* test file name */ TESTING("reading new groups"); /* Generate correct name for test file by prepending the source path */ if(srcdir && ((HDstrlen(srcdir) + HDstrlen(FILE_NEW_GROUPS) + 1) < sizeof(filename))) { HDstrcpy(filename, srcdir); HDstrcat(filename, "/"); } HDstrcat(filename, FILE_NEW_GROUPS); /* Open file */ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; /* Attempt to open root group */ if((gid = H5Gopen(fid, "/")) < 0) TEST_ERROR; /* Attempt to open new "empty" group (should fail) */ H5E_BEGIN_TRY { if(H5Gopen(gid, "empty") >= 0) TEST_ERROR; } H5E_END_TRY; /* Attempt to open new group with link messages (should fail) */ H5E_BEGIN_TRY { if(H5Gopen(gid, "links") >= 0) TEST_ERROR; } H5E_END_TRY; /* Close root group */ if(H5Gclose(gid) < 0) TEST_ERROR; /* Close first file */ if(H5Fclose(fid)<0) TEST_ERROR; PASSED(); return 0; error: H5E_BEGIN_TRY { H5Gclose(gid); H5Fclose(fid); } H5E_END_TRY; return 1; } /* end read_new() */
/**************************************************************** ** ** test_refstr_own(): Test basic H5RS (ref-counted strings) code. ** Tests transferring ownership of dynamically allocated strings ** to ref-counted strings. ** ****************************************************************/ static void test_refstr_own(void) { H5RS_str_t *rs; /* Ref-counted string created */ char *s; /* Pointer to string to transfer */ const char *t; /* Temporary pointers to string */ int cmp; /* Comparison value */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Transferring Ref-Counted Strings\n")); /* Initialize buffer */ s = (char *)H5FL_BLK_MALLOC(str_buf,HDstrlen("foo") + 1); CHECK(s, NULL, "H5FL_BLK_MALLOC"); HDstrcpy(s, "foo"); /* Transfer ownership of dynamically allocated string to ref-counted string */ rs=H5RS_own(s); CHECK(rs, NULL, "H5RS_own"); /* Get pointer to raw string in ref-counted string */ t=H5RS_get_str(rs); CHECK(t, NULL, "H5RS_get_str"); VERIFY(t, s, "transferring"); cmp=HDstrcmp(s,t); VERIFY(cmp, 0, "HDstrcmp"); /* Increment reference count (should NOT duplicate string) */ ret=H5RS_incr(rs); CHECK(ret, FAIL, "H5RS_incr"); /* Change the buffer initially wrapped */ *s='F'; /* Get pointer to raw string in ref-counted string */ t=H5RS_get_str(rs); CHECK(t, NULL, "H5RS_get_str"); VERIFY(t, s, "transferring"); cmp=HDstrcmp(t,s); VERIFY(cmp, 0, "HDstrcmp"); /* Decrement reference count for string */ ret=H5RS_decr(rs); CHECK(ret, FAIL, "H5RS_decr"); ret=H5RS_decr(rs); CHECK(ret, FAIL, "H5RS_decr"); } /* end test_refstr_own() */
/**************************************************************** ** ** test_refstr_wrap(): Test basic H5RS (ref-counted strings) code. ** Tests wrapping ref-counted strings around existing strings. ** ****************************************************************/ static void test_refstr_wrap(void) { H5RS_str_t *rs; /* Ref-counted string created */ const char *s; /* Pointer to raw string in ref-counted string */ char buf[16]; /* Buffer to wrap */ int cmp; /* Comparison value */ herr_t ret; /* Generic return value */ /* Output message about test being performed */ MESSAGE(5, ("Testing Wrapping Ref-Counted Strings\n")); /* Initialize buffer */ HDstrcpy(buf,"foo"); /* Wrap ref-counted string around existing buffer */ rs=H5RS_wrap(buf); CHECK(rs, NULL, "H5RS_wrap"); /* Get pointer to raw string in ref-counted string */ s=H5RS_get_str(rs); CHECK(s, NULL, "H5RS_get_str"); VERIFY(s, buf, "wrapping"); cmp=HDstrcmp(s,buf); VERIFY(cmp, 0, "HDstrcmp"); /* Increment reference count (should duplicate string) */ ret=H5RS_incr(rs); CHECK(ret, FAIL, "H5RS_incr"); /* Change the buffer initially wrapped */ buf[0]='F'; /* Get pointer to raw string in ref-counted string */ s=H5RS_get_str(rs); CHECK(s, NULL, "H5RS_get_str"); CHECK(s, buf, "wrapping"); cmp=HDstrcmp(s,buf); if(cmp<=0) TestErrPrintf("%d: string comparison incorrect!\n",__LINE__); /* Decrement reference count for string */ ret=H5RS_decr(rs); CHECK(ret, FAIL, "H5RS_decr"); ret=H5RS_decr(rs); CHECK(ret, FAIL, "H5RS_decr"); } /* end test_refstr_wrap() */
/*------------------------------------------------------------------------- * Function: H5MM_strdup * * Purpose: Duplicates a string. If the string to be duplicated is the * null pointer, then return null. If the string to be duplicated * is the empty string then return a new empty string. * * Return: Success: Ptr to a new string (or null if no string). * * Failure: abort() * * Programmer: Robb Matzke * [email protected] * Jul 10 1997 * * Modifications: * *------------------------------------------------------------------------- */ char * H5MM_strdup(const char *s) { char *ret_value; FUNC_ENTER_NOAPI(H5MM_strdup, NULL) if(!s) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "null string") if(NULL == (ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDstrcpy(ret_value, s); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5MM_strdup() */
/*------------------------------------------------------------------------- * Function: H5MM_xstrdup * * Purpose: Duplicates a string. If the string to be duplicated is the * null pointer, then return null. If the string to be duplicated * is the empty string then return a new empty string. * * Return: Success: Ptr to a new string (or null if no string). * * Failure: abort() * * Programmer: Robb Matzke * [email protected] * Jul 10 1997 * *------------------------------------------------------------------------- */ char * H5MM_xstrdup(const char *s) { char *ret_value = NULL; /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_xstrdup) if(s) { ret_value = (char *)H5MM_malloc(HDstrlen(s) + 1); HDassert(ret_value); HDstrcpy(ret_value, s); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5MM_xstrdup() */
/*------------------------------------------------------------------------- * Function: H5O_name_encode * * Purpose: Encodes a name message. * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke * [email protected] * Aug 12 1997 * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5O_name_encode(H5F_t H5_ATTR_UNUSED *f, hbool_t H5_ATTR_UNUSED disable_shared, uint8_t *p, const void *_mesg) { const H5O_name_t *mesg = (const H5O_name_t *) _mesg; FUNC_ENTER_NOAPI_NOINIT_NOERR /* check args */ HDassert(f); HDassert(p); HDassert(mesg && mesg->s); /* encode */ HDstrcpy((char*)p, mesg->s); FUNC_LEAVE_NOAPI(SUCCEED) }
int getTmpName(char **pname) { int length; static int count = 0; char s[32]; (void) sprintf(s, "%she%d.%d", TDIR, (int)getpid(), count); count++; length = (int)HDstrlen(s); if (length <= 0) return FAIL; *pname = (char *) HDmalloc(length + 1); HDstrcpy(*pname, s); return length; }
/*------------------------------------------------------------------------- * Function: H5MM_xstrdup * * Purpose: Duplicates a string. If the string to be duplicated is the * null pointer, then return null. If the string to be duplicated * is the empty string then return a new empty string. * * Return: Success: Ptr to a new string (or null if no string). * * Failure: abort() * * Programmer: Robb Matzke * [email protected] * Jul 10 1997 * * Modifications: * *------------------------------------------------------------------------- */ char * H5MM_xstrdup(const char *s) { char *ret_value=NULL; /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5MM_xstrdup); if (s) { ret_value = H5MM_malloc(HDstrlen(s) + 1); assert (ret_value); HDstrcpy(ret_value, s); } /* end if */ #ifdef LATER done: #endif /* LATER */ FUNC_LEAVE_NOAPI(ret_value); }
/*------------------------------------------------------------------------- * Function: generate_symbols * * Purpose: Initializes the global dataset infomration arrays. * * Parameters: N/A * * Return: Success: 0 * Failure: Can't fail * *------------------------------------------------------------------------- */ int generate_symbols(void) { unsigned u, v; /* Local index variables */ for(u = 0; u < NLEVELS; u++) { symbol_info[u] = (symbol_info_t *)HDmalloc(symbol_count[u] * sizeof(symbol_info_t)); for(v = 0; v < symbol_count[u]; v++) { char name_buf[64]; generate_name(name_buf, u, v); symbol_info[u][v].name = (char *)HDmalloc(HDstrlen(name_buf) + 1); HDstrcpy(symbol_info[u][v].name, name_buf); symbol_info[u][v].dsid = -1; symbol_info[u][v].nrecords = 0; } /* end for */ } /* end for */ return 0; } /* end generate_symbols() */
/*------------------------------------------------------------------------- * Function: H5_bandwidth * * Purpose: Prints the bandwidth (bytes per second) in a field 10 * characters wide widh four digits of precision like this: * * NaN If <=0 seconds * 1234. TB/s * 123.4 TB/s * 12.34 GB/s * 1.234 MB/s * 4.000 kB/s * 1.000 B/s * 0.000 B/s If NBYTES==0 * 1.2345e-10 For bandwidth less than 1 * 6.7893e+94 For exceptionally large values * 6.678e+106 For really big values * * Return: void * * Programmer: Robb Matzke * Wednesday, August 5, 1998 * * Modifications: * *------------------------------------------------------------------------- */ void H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds) { double bw; if (nseconds<=0.0) { HDstrcpy(buf, " NaN"); } else { bw = nbytes/nseconds; if (fabs(bw) < 0.0000000001) { /* That is == 0.0, but direct comparison between floats is bad */ HDstrcpy(buf, "0.000 B/s"); } else if (bw<1.0) { sprintf(buf, "%10.4e", bw); } else if (bw<1024.0) { sprintf(buf, "%05.4f", bw); HDstrcpy(buf+5, " B/s"); } else if (bw<1024.0*1024.0) { sprintf(buf, "%05.4f", bw/1024.0); HDstrcpy(buf+5, " kB/s"); } else if (bw<1024.0*1024.0*1024.0) { sprintf(buf, "%05.4f", bw/(1024.0*1024.0)); HDstrcpy(buf+5, " MB/s"); } else if (bw<1024.0*1024.0*1024.0*1024.0) { sprintf(buf, "%05.4f", bw/(1024.0*1024.0*1024.0)); HDstrcpy(buf+5, " GB/s"); } else if (bw<1024.0*1024.0*1024.0*1024.0*1024.0) { sprintf(buf, "%05.4f", bw/(1024.0*1024.0*1024.0*1024.0)); HDstrcpy(buf+5, " TB/s"); } else { sprintf(buf, "%10.4e", bw); if (HDstrlen(buf)>10) { sprintf(buf, "%10.3e", bw); } } } } /* end H5_bandwidth() */
static int parse_command_line(int argc, const char **argv, pack_opt_t* options) { int opt; int ret_value = 0; /* parse command line options */ while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) { switch ((char) opt) { /* -i for backward compability */ case 'i': infile = opt_arg; has_i_o = 1; break; /* -o for backward compability */ case 'o': outfile = opt_arg; has_i_o = 1; break; case 'h': usage(h5tools_getprogname()); h5tools_setstatus(EXIT_SUCCESS); ret_value = -1; goto done; case 'V': print_version(h5tools_getprogname()); h5tools_setstatus(EXIT_SUCCESS); ret_value = -1; goto done; case 'v': options->verbose = 1; break; case 'f': /* parse the -f filter option */ if (h5repack_addfilter(opt_arg, options) < 0) { error_msg("in parsing filter\n"); h5tools_setstatus(EXIT_FAILURE); ret_value = -1; goto done; } break; case 'l': /* parse the -l layout option */ if (h5repack_addlayout(opt_arg, options) < 0) { error_msg("in parsing layout\n"); h5tools_setstatus(EXIT_FAILURE); ret_value = -1; goto done; } break; case 'm': options->min_comp = HDatoi( opt_arg ); if ((int) options->min_comp <= 0) { error_msg("invalid minimum compress size <%s>\n", opt_arg); h5tools_setstatus(EXIT_FAILURE); ret_value = -1; goto done; } break; case 'e': ret_value = read_info(opt_arg, options); if (ret_value < 0) goto done; break; case 'n': options->use_native = 1; break; case 'L': options->latest = 1; break; case 'c': options->grp_compact = HDatoi( opt_arg ); if (options->grp_compact > 0) options->latest = 1; /* must use latest format */ break; case 'd': options->grp_indexed = HDatoi( opt_arg ); if (options->grp_indexed > 0) options->latest = 1; /* must use latest format */ break; case 's': { int idx = 0; int ssize = 0; char *msgPtr = HDstrchr( opt_arg, ':'); options->latest = 1; /* must use latest format */ if (msgPtr == NULL) { ssize = HDatoi( opt_arg ); for (idx = 0; idx < 5; idx++) options->msg_size[idx] = ssize; } else { char msgType[10]; HDstrcpy(msgType, msgPtr + 1); msgPtr[0] = '\0'; ssize = HDatoi( opt_arg ); if (HDstrncmp(msgType, "dspace",6) == 0) { options->msg_size[0] = ssize; } else if (HDstrncmp(msgType, "dtype", 5) == 0) { options->msg_size[1] = ssize; } else if (HDstrncmp(msgType, "fill", 4) == 0) { options->msg_size[2] = ssize; } else if (HDstrncmp(msgType, "pline", 5) == 0) { options->msg_size[3] = ssize; } else if (HDstrncmp(msgType, "attr", 4) == 0) { options->msg_size[4] = ssize; } } } break; case 'u': options->ublock_filename = opt_arg; break; case 'b': options->ublock_size = (hsize_t) HDatol( opt_arg ); break; case 'M': options->meta_block_size = (hsize_t) HDatol( opt_arg ); break; case 't': options->threshold = (hsize_t) HDatol( opt_arg ); break; case 'a': options->alignment = HDatol( opt_arg ); if (options->alignment < 1) { error_msg("invalid alignment size\n", opt_arg); h5tools_setstatus(EXIT_FAILURE); ret_value = -1; goto done; } break; default: break; } /* switch */ } /* while */ if (has_i_o == 0) { /* check for file names to be processed */ if (argc <= opt_ind || argv[opt_ind + 1] == NULL) { error_msg("missing file names\n"); usage(h5tools_getprogname()); h5tools_setstatus(EXIT_FAILURE); ret_value = -1; } } done: return ret_value; }
/* * test_objnames * Tests that UTF-8 can be used for object names in the file. * Tests groups, datasets, named datatypes, and soft links. * Note that this test doesn't actually mark the names as being * in UTF-8. At the time this test was written, that feature * didn't exist in HDF5, and when the character encoding property * was added to links it didn't change how they were stored in the file, * -JML 2/2/2006 */ void test_objnames(hid_t fid, const char* string) { hid_t grp_id, grp1_id, grp2_id, grp3_id; hid_t type_id, dset_id, space_id; char read_buf[MAX_STRING_LENGTH]; char path_buf[MAX_PATH_LENGTH]; hsize_t dims=1; hobj_ref_t obj_ref; herr_t ret; /* Create a group with a UTF-8 name */ grp_id = H5Gcreate2(fid, string, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp_id, FAIL, "H5Gcreate2"); /* Set a comment on the group to test that we can access the group * Also test that UTF-8 comments can be read. */ ret = H5Oset_comment_by_name(fid, string, string, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oset_comment_by_name"); ret = H5Oget_comment_by_name(fid, string, read_buf, (size_t)MAX_STRING_LENGTH, H5P_DEFAULT); CHECK(ret, FAIL, "H5Oget_comment_by_name"); ret = H5Gclose(grp_id); CHECK(ret, FAIL, "H5Gclose"); VERIFY(HDstrcmp(string, read_buf), 0, "strcmp"); /* Create a new dataset with a UTF-8 name */ grp1_id = H5Gcreate2(fid, GROUP1_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp1_id, FAIL, "H5Gcreate2"); space_id = H5Screate_simple(RANK, &dims, NULL); CHECK(space_id, FAIL, "H5Screate_simple"); dset_id = H5Dcreate2(grp1_id, string, H5T_NATIVE_INT, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(dset_id, FAIL, "H5Dcreate2"); /* Make sure that dataset can be opened again */ ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Sclose(space_id); CHECK(ret, FAIL, "H5Sclose"); dset_id = H5Dopen2(grp1_id, string, H5P_DEFAULT); CHECK(ret, FAIL, "H5Dopen2"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Gclose(grp1_id); CHECK(ret, FAIL, "H5Gclose"); /* Do the same for a named datatype */ grp2_id = H5Gcreate2(fid, GROUP2_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp2_id, FAIL, "H5Gcreate2"); type_id = H5Tcreate(H5T_OPAQUE, (size_t)1); CHECK(type_id, FAIL, "H5Tcreate"); ret = H5Tcommit2(grp2_id, string, type_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(type_id, FAIL, "H5Tcommit2"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); type_id = H5Topen2(grp2_id, string, H5P_DEFAULT); CHECK(type_id, FAIL, "H5Topen2"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); /* Don't close the group -- use it to test that object references * can refer to objects named in UTF-8 */ space_id = H5Screate_simple(RANK, &dims, NULL); CHECK(space_id, FAIL, "H5Screate_simple"); dset_id = H5Dcreate2(grp2_id, DSET3_NAME, H5T_STD_REF_OBJ, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Dcreate2"); /* Create reference to named datatype */ ret = H5Rcreate(&obj_ref, grp2_id, string, H5R_OBJECT, -1); CHECK(ret, FAIL, "H5Rcreate"); /* Write selection and read it back*/ ret = H5Dwrite(dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &obj_ref); CHECK(ret, FAIL, "H5Dwrite"); ret = H5Dread(dset_id, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &obj_ref); CHECK(ret, FAIL, "H5Dread"); /* Ensure that we can open named datatype using object reference */ type_id = H5Rdereference2(dset_id, H5P_DEFAULT, H5R_OBJECT, &obj_ref); CHECK(type_id, FAIL, "H5Rdereference2"); ret = H5Tcommitted(type_id); VERIFY(ret, 1, "H5Tcommitted"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); ret = H5Dclose(dset_id); CHECK(ret, FAIL, "H5Dclose"); ret = H5Sclose(space_id); CHECK(ret, FAIL, "H5Sclose"); ret = H5Gclose(grp2_id); CHECK(ret, FAIL, "H5Gclose"); /* Create "group3". Build a hard link from group3 to group2, which has * a datatype with the UTF-8 name. Create a soft link in group3 * pointing through the hard link to the datatype. Give the soft * link a name in UTF-8. Ensure that the soft link works. */ grp3_id = H5Gcreate2(fid, GROUP3_NAME, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); CHECK(grp3_id, FAIL, "H5Gcreate2"); ret = H5Lcreate_hard(fid, GROUP2_NAME, grp3_id, GROUP2_NAME, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lcreate_hard"); HDstrcpy(path_buf, GROUP2_NAME); HDstrcat(path_buf, "/"); HDstrcat(path_buf, string); ret = H5Lcreate_hard(grp3_id, path_buf, H5L_SAME_LOC, string, H5P_DEFAULT, H5P_DEFAULT); CHECK(ret, FAIL, "H5Lcreate_hard"); /* Open named datatype using soft link */ type_id = H5Topen2(grp3_id, string, H5P_DEFAULT); CHECK(type_id, FAIL, "H5Topen2"); ret = H5Tclose(type_id); CHECK(type_id, FAIL, "H5Tclose"); ret = H5Gclose(grp3_id); CHECK(ret, FAIL, "H5Gclose"); }
/*------------------------------------------------------------------------- * Function: options_add_filter * * Purpose: add a compression -f option to the option list * * Return: 0, ok, -1, fail * *------------------------------------------------------------------------- */ int options_add_filter(obj_list_t *obj_list, unsigned n_objs, filter_info_t filt, pack_opttbl_t *table) { unsigned int i, j, I; unsigned added = 0; hbool_t found = FALSE; /* increase the size of the collection by N_OBJS if necessary */ if (table->nelems + n_objs >= table->size) if (aux_inctable(table, n_objs) < 0) return -1; /* search if this object is already in the table; "path" is the key */ if (table->nelems > 0) { /* go tru the supplied list of names */ for (j = 0; j < n_objs; j++) { /* linear table search */ for (i = 0; i < table->nelems; i++) { /*already on the table */ if (HDstrcmp(obj_list[j].obj, table->objs[i].path) == 0) { /* insert */ aux_tblinsert_filter(table, i, filt); found = TRUE; break; } /* if */ } /* i */ if (!found) { /* keep the grow in a temp var */ I = table->nelems + added; added++; HDstrcpy(table->objs[I].path, obj_list[j].obj); aux_tblinsert_filter(table, I, filt); } /* cases where we have an already inserted name but there is a new name also example: -l dset1:CHUNK=20x20 -f dset1,dset2:GZIP=1 dset1 is already inserted, but dset2 must also be */ else if(found && HDstrcmp(obj_list[j].obj,table->objs[i].path) != 0) { /* keep the grow in a temp var */ I = table->nelems + added; added++; HDstrcpy(table->objs[I].path, obj_list[j].obj); aux_tblinsert_filter(table, I, filt); } } /* j */ } /* first time insertion */ else { /* go tru the supplied list of names */ for (j = 0; j < n_objs; j++) { I = table->nelems + added; added++; HDstrcpy(table->objs[I].path, obj_list[j].obj); aux_tblinsert_filter(table, I, filt); } } table->nelems += added; return 0; }
/*------------------------------------------------------------------------- * Function: options_add_layout * * Purpose: add a layout option to the option list * * Return: 0, ok, -1, fail * *------------------------------------------------------------------------- */ int options_add_layout(obj_list_t *obj_list, unsigned n_objs, pack_info_t *pack, pack_opttbl_t *table) { unsigned i, j, I; unsigned added = 0; hbool_t found = FALSE; /* increase the size of the collection by N_OBJS if necessary */ if (table->nelems + n_objs >= table->size) if (aux_inctable(table, n_objs) < 0) return -1; /* search if this object is already in the table; "path" is the key */ if (table->nelems > 0) { /* go tru the supplied list of names */ for (j = 0; j < n_objs; j++) { /* linear table search */ for (i = 0; i < table->nelems; i++) { /*already on the table */ if (HDstrcmp(obj_list[j].obj,table->objs[i].path) == 0) { /* already chunk info inserted for this one; exit */ if (table->objs[i].chunk.rank > 0) { error_msg("chunk information already inserted for <%s>\n", obj_list[j].obj); HDexit(EXIT_FAILURE); } /* insert the layout info */ else { aux_tblinsert_layout(table, i, pack); found = TRUE; break; } } /* if */ } /* i */ if (!found) { /* keep the grow in a temp var */ I = table->nelems + added; added++; HDstrcpy(table->objs[I].path, obj_list[j].obj); aux_tblinsert_layout(table, I, pack); } /* cases where we have an already inserted name but there is a new name also example: -f dset1:GZIP=1 -l dset1,dset2:CHUNK=20x20 dset1 is already inserted, but dset2 must also be */ else if(found && HDstrcmp(obj_list[j].obj,table->objs[i].path) != 0) { /* keep the grow in a temp var */ I = table->nelems + added; added++; HDstrcpy(table->objs[I].path, obj_list[j].obj); aux_tblinsert_layout(table, I, pack); } } /* j */ } /* first time insertion */ else { /* go tru the supplied list of names */ for (j = 0; j < n_objs; j++) { I = table->nelems + added; added++; HDstrcpy(table->objs[I].path, obj_list[j].obj); aux_tblinsert_layout(table, I, pack); } } table->nelems += added; return 0; }
/*------------------------------------------------------------------------- * Function: main * * Purpose: H5O_mtime_decode() test. * * Return: Success: * * Failure: * * Programmer: Robb Matzke * Thursday, July 30, 1998 * * Modifications: * Added checks for old and new modification time messages * in pre-created datafiles (generated with gen_old_mtime.c and * gen_new_mtime.c). * Quincey Koziol * Friday, January 3, 2003 * *------------------------------------------------------------------------- */ int main(void) { hid_t fapl, file, space, dset; hsize_t size[1] = {2}; time_t now; struct tm *tm; H5O_info_t oi1, oi2; signed char buf1[32], buf2[32]; char filename[1024]; h5_reset(); fapl = h5_fileaccess(); TESTING("modification time messages"); /* Create the file, create a dataset, then close the file */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; if((space = H5Screate_simple(1, size, NULL)) < 0) TEST_ERROR; if((dset = H5Dcreate2(file, "dset", H5T_NATIVE_SCHAR, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; now = HDtime(NULL); if(H5Dclose(dset) < 0) TEST_ERROR; if(H5Sclose(space) < 0) TEST_ERROR; if(H5Fclose(file) < 0) TEST_ERROR; /* * Open the file and get the modification time. We'll test the * H5Oget_info() arguments too: being able to stat something without * knowing its name. */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; if(H5Oget_info_by_name(file, "dset", &oi1, H5P_DEFAULT) < 0) TEST_ERROR; if((dset = H5Dopen2(file, "dset", H5P_DEFAULT)) < 0) TEST_ERROR; if(H5Oget_info(dset, &oi2) < 0) TEST_ERROR; if(H5Dclose(dset) < 0) TEST_ERROR; if(H5Fclose(file) < 0) TEST_ERROR; /* Compare addresses & times from the two ways of calling H5Oget_info() */ if(oi1.addr != oi2.addr || oi1.mtime != oi2.mtime) { H5_FAILED(); puts(" Calling H5Oget_info() with the dataset ID returned"); puts(" different values than calling it with a file and dataset"); puts(" name."); goto error; } /* Compare times -- they must be within 60 seconds of one another */ if(0 == oi1.mtime) { SKIPPED(); puts(" The modification time could not be decoded on this OS."); puts(" Modification times will be mantained in the file but"); puts(" cannot be queried on this system. See H5O_mtime_decode()."); return 0; } else if(HDfabs(HDdifftime(now, oi1.mtime)) > 60.0) { H5_FAILED(); tm = HDlocaltime(&(oi1.mtime)); HDstrftime((char*)buf1, sizeof buf1, "%Y-%m-%d %H:%M:%S", tm); tm = HDlocaltime(&now); HDstrftime((char*)buf2, sizeof buf2, "%Y-%m-%d %H:%M:%S", tm); printf(" got: %s\n ans: %s\n", buf1, buf2); goto error; } PASSED(); /* Check opening existing file with old-style modification time information * and make certain that the time is correct */ TESTING("accessing old modification time messages"); { char testfile[512]=""; char *srcdir = HDgetenv("srcdir"); if(srcdir && ((HDstrlen(srcdir) + strlen(TESTFILE1) + 1) < sizeof(testfile))){ HDstrcpy(testfile, srcdir); HDstrcat(testfile, "/"); } HDstrcat(testfile, TESTFILE1); file = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT); if(file >= 0){ if(H5Oget_info_by_name(file, "/Dataset1", &oi1, H5P_DEFAULT) < 0) TEST_ERROR; if(oi1.mtime != MTIME1) { H5_FAILED(); /* If this fails, examine H5Omtime.c. Modification time is very * system dependant (e.g., on Windows DST must be hardcoded). */ puts(" Old modification time incorrect"); goto error; } if(H5Fclose(file) < 0) TEST_ERROR; } else { H5_FAILED(); printf("***cannot open the pre-created old modification test file (%s)\n", testfile); goto error; } /* end else */ } PASSED(); /* Check opening existing file with new-style modification time information * and make certain that the time is correct */ TESTING("accessing new modification time messages"); { char testfile[512]=""; char *srcdir = HDgetenv("srcdir"); if(srcdir && ((HDstrlen(srcdir) + strlen(TESTFILE2) + 1) < sizeof(testfile))){ HDstrcpy(testfile, srcdir); HDstrcat(testfile, "/"); } HDstrcat(testfile, TESTFILE2); file = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT); if(file >= 0){ if(H5Oget_info_by_name(file, "/Dataset1", &oi2, H5P_DEFAULT) < 0) TEST_ERROR; if(oi2.mtime != MTIME2) { H5_FAILED(); puts(" Modification time incorrect."); goto error; } if(H5Fclose(file) < 0) TEST_ERROR; } else { H5_FAILED(); printf("***cannot open the pre-created old modification test file (%s)\n", testfile); goto error; } /* end else */ } PASSED(); /* All looks good */ puts("All modification time tests passed."); h5_cleanup(FILENAME, fapl); return 0; /* Something broke */ error: return 1; }
/*------------------------------------------------------------------------- * Function: h5_fixname * * Purpose: Create a file name from a file base name like `test' and * return it through the FULLNAME (at most SIZE characters * counting the null terminator). The full name is created by * prepending the contents of HDF5_PREFIX (separated from the * base name by a slash) and appending a file extension based on * the driver supplied, resulting in something like * `ufs:/u/matzke/test.h5'. * * Return: Success: The FULLNAME pointer. * * Failure: NULL if BASENAME or FULLNAME is the null * pointer or if FULLNAME isn't large enough for * the result. * * Programmer: Robb Matzke * Thursday, November 19, 1998 * *------------------------------------------------------------------------- */ char * h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size) { const char *prefix = NULL; const char *suffix = ".h5"; /* suffix has default */ char *ptr, last = '\0'; size_t i, j; hid_t driver = -1; int isppdriver = 0; /* if the driver is MPI parallel */ if (!base_name || !fullname || size < 1) return NULL; HDmemset(fullname, 0, size); /* figure out the suffix */ if(H5P_DEFAULT != fapl) { if((driver = H5Pget_driver(fapl)) < 0) return NULL; if(H5FD_FAMILY == driver) suffix = "%05d.h5"; else if (H5FD_MULTI == driver) suffix = NULL; } /* Must first check fapl is not H5P_DEFAULT (-1) because H5FD_XXX * could be of value -1 if it is not defined. */ isppdriver = H5P_DEFAULT != fapl && (H5FD_MPIO==driver); /* Check HDF5_NOCLEANUP environment setting. * (The #ifdef is needed to prevent compile failure in case MPI is not * configured.) */ if(isppdriver) { #ifdef H5_HAVE_PARALLEL if(getenv_all(MPI_COMM_WORLD, 0, "HDF5_NOCLEANUP")) SetTestNoCleanup(); #endif /* H5_HAVE_PARALLEL */ } else { if(HDgetenv("HDF5_NOCLEANUP")) SetTestNoCleanup(); } /* Check what prefix to use for test files. Process HDF5_PARAPREFIX and * HDF5_PREFIX. * Use different ones depending on parallel or serial driver used. * (The #ifdef is needed to prevent compile failure in case MPI is not * configured.) */ if(isppdriver) { #ifdef H5_HAVE_PARALLEL /* * For parallel: * First use command line option, then the environment * variable, then try the constant */ static int explained = 0; prefix = (paraprefix ? paraprefix : getenv_all(MPI_COMM_WORLD, 0, "HDF5_PARAPREFIX")); if (!prefix && !explained) { /* print hint by process 0 once. */ int mpi_rank; MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); if (mpi_rank == 0) printf("*** Hint ***\n" "You can use environment variable HDF5_PARAPREFIX to " "run parallel test files in a\n" "different directory or to add file type prefix. E.g.,\n" " HDF5_PARAPREFIX=pfs:/PFS/user/me\n" " export HDF5_PARAPREFIX\n" "*** End of Hint ***\n"); explained = TRUE; #ifdef HDF5_PARAPREFIX prefix = HDF5_PARAPREFIX; #endif /* HDF5_PARAPREFIX */ } #endif /* H5_HAVE_PARALLEL */ } else { /* * For serial: * First use the environment variable, then try the constant */ prefix = HDgetenv("HDF5_PREFIX"); #ifdef HDF5_PREFIX if (!prefix) prefix = HDF5_PREFIX; #endif /* HDF5_PREFIX */ } /* Prepend the prefix value to the base name */ if (prefix && *prefix) { if (isppdriver) { /* This is a parallel system */ char *subdir; if (!HDstrcmp(prefix, HDF5_PARAPREFIX)) { /* * If the prefix specifies the HDF5_PARAPREFIX directory, then * default to using the "/tmp/$USER" or "/tmp/$LOGIN" * directory instead. */ char *user, *login; user = HDgetenv("USER"); login = HDgetenv("LOGIN"); subdir = (user ? user : login); if (subdir) { for (i = 0; i < size && prefix[i]; i++) fullname[i] = prefix[i]; fullname[i++] = '/'; for (j = 0; i < size && subdir[j]; ++i, ++j) fullname[i] = subdir[j]; } } if (!fullname[0]) { /* We didn't append the prefix yet */ HDstrncpy(fullname, prefix, size); fullname[size -1] = '\0'; } if (HDstrlen(fullname) + HDstrlen(base_name) + 1 < size) { /* * Append the base_name with a slash first. Multiple * slashes are handled below. */ h5_stat_t buf; if (HDstat(fullname, &buf) < 0) /* The directory doesn't exist just yet */ if (HDmkdir(fullname, (mode_t)0755) < 0 && errno != EEXIST) /* * We couldn't make the "/tmp/${USER,LOGIN}" * subdirectory. Default to PREFIX's original * prefix value. */ HDstrcpy(fullname, prefix); HDstrcat(fullname, "/"); HDstrcat(fullname, base_name); } else { /* Buffer is too small */ return NULL; } } else { if (HDsnprintf(fullname, size, "%s/%s", prefix, base_name) == (int)size) /* Buffer is too small */ return NULL; } } else if (HDstrlen(base_name) >= size) { /* Buffer is too small */ return NULL; } else { HDstrcpy(fullname, base_name); } /* Append a suffix */ if (suffix) { if (HDstrlen(fullname) + HDstrlen(suffix) >= size) return NULL; HDstrcat(fullname, suffix); } /* Remove any double slashes in the filename */ for (ptr = fullname, i = j = 0; ptr && i < size; i++, ptr++) { if (*ptr != '/' || last != '/') fullname[j++] = *ptr; last = *ptr; } return fullname; }
/*------------------------------------------------------------------------- * Function: traverse_cb * * Purpose: Iterator callback for traversing objects in file * * Programmer: Quincey Koziol, [email protected] * * Date: September 1, 2007 * *------------------------------------------------------------------------- */ static herr_t traverse_cb(hid_t loc_id, const char *path, const H5L_info_t *linfo, void *_udata) { trav_ud_traverse_t *udata = (trav_ud_traverse_t *)_udata; /* User data */ char *new_name = NULL; const char *full_name; const char *already_visited = NULL; /* Whether the link/object was already visited */ /* Create the full path name for the link */ if(udata->is_absolute) { 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 = (char*)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 full_name = path; /* Perform the correct action for different types of links */ if(linfo->type == H5L_TYPE_HARD) { H5O_info_t oinfo; /* Get information about the object */ if(H5Oget_info_by_name(loc_id, path, &oinfo, H5P_DEFAULT) < 0) { if(new_name) HDfree(new_name); return(H5_ITER_ERROR); } /* If the object has multiple links, add it to the list of addresses * already visited, if it isn't there already */ if(oinfo.rc > 1) if(NULL == (already_visited = trav_addr_visited(udata->seen, oinfo.addr))) trav_addr_add(udata->seen, oinfo.addr, full_name); /* Make 'visit object' callback */ if(udata->visitor->visit_obj) if((*udata->visitor->visit_obj)(full_name, &oinfo, already_visited, udata->visitor->udata) < 0) { if(new_name) HDfree(new_name); return(H5_ITER_ERROR); } } /* end if */ else { /* Make 'visit link' callback */ if(udata->visitor->visit_lnk) if((*udata->visitor->visit_lnk)(full_name, linfo, udata->visitor->udata) < 0) { if(new_name) HDfree(new_name); return(H5_ITER_ERROR); } } /* end else */ if(new_name) HDfree(new_name); return(H5_ITER_CONT); } /* end traverse_cb() */