diff options
-rwxr-xr-x | bin/snapshot | 2 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | src/H5D.c | 61 | ||||
-rw-r--r-- | src/H5Dprivate.h | 1 | ||||
-rw-r--r-- | src/H5G.c | 220 | ||||
-rw-r--r-- | src/H5Gprivate.h | 15 | ||||
-rw-r--r-- | src/H5Gpublic.h | 18 | ||||
-rw-r--r-- | src/H5O.c | 49 | ||||
-rw-r--r-- | src/H5Oprivate.h | 1 | ||||
-rw-r--r-- | src/H5RA.c | 61 | ||||
-rw-r--r-- | src/H5RAprivate.h | 1 | ||||
-rw-r--r-- | src/H5T.c | 35 | ||||
-rw-r--r-- | src/H5Tprivate.h | 1 | ||||
-rw-r--r-- | src/H5config.h.in | 5 | ||||
-rw-r--r-- | tools/h5ls.c | 66 | ||||
-rw-r--r-- | tools/h5tools.c | 15 | ||||
-rw-r--r-- | tools/h5tools.h | 8 |
17 files changed, 498 insertions, 63 deletions
diff --git a/bin/snapshot b/bin/snapshot index d87dd3a..ef49c29 100755 --- a/bin/snapshot +++ b/bin/snapshot @@ -42,7 +42,7 @@ snapshot=yes if [ -d ${COMPARE}/previous ]; then if (diff -c ${COMPARE}/previous/MANIFEST ${COMPARE}/current/MANIFEST); then snapshot=no - for src in `grep '^\.' ${COMPARE}/current/MANIFEST|expand|cut -f1`; do + for src in `grep '^\.' ${COMPARE}/current/MANIFEST|expand|cut -f1 -d' '`; do if (diff -I H5_VERS_RELEASE -I " released on " \ ${COMPARE}/previous/$src ${COMPARE}/current/$src); then else diff --git a/configure.in b/configure.in index c26a3c3..0999e01 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -dnl Process this file with autoconf to produce configure. -*-indented-text-*- +dnl Process this file with autoconf to produce configure. dnl dnl Copyright (C) 1997 National Center for Supercomputing Applications. dnl All rights reserved. @@ -1101,7 +1101,57 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- + * Function: H5D_isa + * + * Purpose: Determines if an object has the requisite messages for being + * a dataset. + * + * Return: Success: TRUE if the required dataset messages are + * present; FALSE otherwise. + * + * Failure: FAIL if the existence of certain messages + * cannot be determined. + * + * Programmer: Robb Matzke + * Monday, November 2, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5D_isa(H5G_entry_t *ent) +{ + htri_t exists; + + FUNC_ENTER(H5D_isa, FAIL); + assert(ent); + + /* Data type */ + if ((exists=H5O_exists(ent, H5O_DTYPE, 0))<0) { + HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, + "unable to read object header"); + } else if (!exists) { + HRETURN(FALSE); + } + + /* Layout */ + if ((exists=H5O_exists(ent, H5O_LAYOUT, 0))<0) { + HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, + "unable to read object header"); + } else if (!exists) { + HRETURN(FALSE); + } + + + + FUNC_LEAVE(TRUE); +} + +/* + *------------------------------------------------------------------------- * Function: H5D_open * * Purpose: Finds a dataset named NAME in file F and builds a descriptor @@ -1130,7 +1180,7 @@ H5D_open(H5G_entry_t *loc, const char *name) { H5D_t *dataset = NULL; /*the dataset which was found */ H5D_t *ret_value = NULL; /*return value */ - H5G_entry_t ent; /* Dataset symbol table entry */ + H5G_entry_t ent; /*dataset symbol table entry */ FUNC_ENTER(H5D_open, NULL); @@ -1173,10 +1223,10 @@ done: H5D_t * H5D_open_oid(H5G_entry_t *ent) { - H5D_t *dataset = NULL; /* New dataset struct */ - H5D_t *ret_value = NULL; /*return value */ + H5D_t *dataset = NULL; /*new dataset struct */ + H5D_t *ret_value = NULL; /*return value */ + H5S_t *space = NULL; /*data space */ intn i; - H5S_t *space = NULL; FUNC_ENTER(H5D_open_oid, NULL); @@ -1290,8 +1340,7 @@ H5D_open_oid(H5G_entry_t *ent) ret_value = dataset; done: - if (space) - H5S_close (space); + if (space) H5S_close (space); if (ret_value==NULL && dataset) { if (H5F_addr_defined(&(dataset->ent.header))) { H5O_close(&(dataset->ent)); diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index bdf66f7..3a30731 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -71,6 +71,7 @@ H5D_t *H5D_create (H5G_entry_t *loc, const char *name, const H5T_t *type, const H5S_t *space, const H5D_create_t *create_parms); H5D_t *H5D_open (H5G_entry_t *loc, const char *name); herr_t H5D_close (H5D_t *dataset); +htri_t H5D_isa(H5G_entry_t *ent); herr_t H5D_read (H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, const H5S_t *file_space, const H5D_xfer_t *xfer_parms, void *buf/*out*/); @@ -95,6 +95,9 @@ static hbool_t interface_initialize_g = FALSE; #define INTERFACE_INIT H5G_init_interface static herr_t H5G_init_interface(void); static void H5G_term_interface(void); +static H5G_typeinfo_t *H5G_type_g = NULL; /*object typing info */ +static size_t H5G_ntypes_g = 0; /*entries in type table */ +static size_t H5G_atypes_g = 0; /*entries allocated */ /*------------------------------------------------------------------------- @@ -523,8 +526,9 @@ H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, * most SIZE characters (counting the null terminator) are * copied to the BUF result buffer. * - * Return: Non-negative on success (the link value is in BUF.) /Negative on - * failure + * Return: Success: Non-negative with the link value in BUF. + * + * Failure: Negative * * Programmer: Robb Matzke * Monday, April 13, 1998 @@ -684,6 +688,17 @@ H5G_init_interface(void) HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface"); } + + /* + * Initialize the type info table. Begin with the most general types and + * end with the most specific. For instance, any object that has a data + * type message is a data type but only some of them are datasets. + */ + H5G_register_type(H5G_TYPE, H5T_isa, "data type"); + H5G_register_type(H5G_GROUP, H5G_isa, "group"); + H5G_register_type(H5G_DATASET, H5D_isa, "dataset"); + H5G_register_type(H5G_RAGGED, H5RA_isa, "ragged array"); + FUNC_LEAVE(SUCCEED); } @@ -710,6 +725,85 @@ H5G_term_interface(void) /*------------------------------------------------------------------------- + * Function: H5G_register_type + * + * Purpose: Register a new object type so H5G_get_type() can detect it. + * One should always register a general type before a more + * specific type. For instance, any object that has a data type + * message is a data type, but only some of those objects are + * datasets. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, November 4, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_register_type(intn type, htri_t(*isa)(H5G_entry_t*), const char *_desc) +{ + char *desc = NULL; + size_t i; + herr_t ret_value = FAIL; + + FUNC_ENTER(H5G_register_type, FAIL); + assert(type>=0); + assert(isa); + assert(_desc); + + /* Copy the description */ + if (NULL==(desc=H5MM_strdup(_desc))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for object type description"); + } + + /* + * If the type is already registered then just update its entry without + * moving it to the end + */ + for (i=0; i<H5G_ntypes_g; i++) { + if (H5G_type_g[i].type==type) { + H5G_type_g[i].isa = isa; + H5MM_xfree(H5G_type_g[i].desc); + H5G_type_g[i].desc = desc; + ret_value = SUCCEED; + goto done; + } + } + + /* Increase table size */ + if (H5G_ntypes_g>=H5G_atypes_g) { + size_t n = MAX(32, 2*H5G_atypes_g); + H5G_typeinfo_t *x = H5MM_realloc(H5G_type_g, + n*sizeof(H5G_typeinfo_t)); + if (!x) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for objec type table"); + } + H5G_atypes_g = n; + H5G_type_g = x; + } + + /* Add a new entry */ + H5G_type_g[H5G_ntypes_g].type = type; + H5G_type_g[H5G_ntypes_g].isa = isa; + H5G_type_g[H5G_ntypes_g].desc = desc; /*already copied*/ + H5G_ntypes_g++; + + ret_value = SUCCEED; + + done: + if (ret_value<0) H5MM_xfree(desc); + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5G_component * * Purpose: Returns the pointer to the first component of the @@ -842,14 +936,14 @@ H5G_basename(const char *name, size_t *size_p) * * Errors: * - * Return: Success: Non-negative if name can be fully resolved. See - * above for values of REST, GRP_ENT, and + * Return: Success: Non-negative if name can be fully resolved. + * See above for values of REST, GRP_ENT, and * OBJ_ENT. NLINKS has been decremented for * each symbolic link that was followed. * - * Failure: Negative if the name could not be fully resolved. - * See above for values of REST, GRP_ENT, and - * OBJ_ENT. + * Failure: Negative if the name could not be fully + * resolved. See above for values of REST, + * GRP_ENT, and OBJ_ENT. * * Programmer: Robb Matzke * matzke@llnl.gov @@ -1191,6 +1285,42 @@ H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint) grp->nref = 1; FUNC_LEAVE(grp); } + + +/*------------------------------------------------------------------------- + * Function: H5G_isa + * + * Purpose: Determines if an object has the requisite messages for being + * a group. + * + * Return: Success: TRUE if the required group messages are + * present; FALSE otherwise. + * + * Failure: FAIL if the existence of certain messages + * cannot be determined. + * + * Programmer: Robb Matzke + * Monday, November 2, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5G_isa(H5G_entry_t *ent) +{ + htri_t exists; + + FUNC_ENTER(H5G_isa, FAIL); + assert(ent); + + if ((exists=H5O_exists(ent, H5O_STAB, 0))<0) { + HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, + "unable to read object header"); + } + FUNC_LEAVE(exists); +} + /*------------------------------------------------------------------------- * Function: H5G_open @@ -1431,8 +1561,8 @@ H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent) * * Errors: * - * Return: Success: Non-negative, see above for values of GRP_ENT and - * OBJ_ENT. + * Return: Success: Non-negative, see above for values of GRP_ENT + * and OBJ_ENT. * * Failure: Negative * @@ -1761,12 +1891,54 @@ H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name, /*------------------------------------------------------------------------- + * Function: H5G_get_type + * + * Purpose: Returns the type of object pointed to by `ent'. + * + * Return: Success: An object type defined in H5Gpublic.h + * + * Failure: H5G_UNKNOWN + * + * Programmer: Robb Matzke + * Wednesday, November 4, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +intn +H5G_get_type(H5G_entry_t *ent) +{ + htri_t isa; + size_t i; + + FUNC_ENTER(H5G_get_type, H5G_UNKNOWN); + + for (i=H5G_ntypes_g; i>0; --i) { + if ((isa=(H5G_type_g[i-1].isa)(ent))<0) { + HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, + "unable to determine object type"); + } else if (isa) { + HRETURN(H5G_type_g[i-1].type); + } + } + + if (0==i) { + HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, + "unable to determine object type"); + } + FUNC_LEAVE(H5G_UNKNOWN); +} + + +/*------------------------------------------------------------------------- * Function: H5G_get_objinfo * * Purpose: Returns information about an object. * - * Return: Success: Non-negative with info about the object returned - * through STATBUF if it isn't the null pointer. + * Return: Success: Non-negative with info about the object + * returned through STATBUF if it isn't the null + * pointer. * * Failure: Negative * @@ -1784,9 +1956,6 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, H5O_stab_t stab_mesg; H5G_entry_t grp_ent, obj_ent; const char *s = NULL; - H5D_t *temp_dset = NULL; - H5G_t *temp_grp = NULL; - H5T_t *temp_type = NULL; FUNC_ENTER (H5G_get_objinfo, FAIL); @@ -1833,24 +2002,7 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, H5E_clear(); statbuf->mtime = 0; } - - /* - * Determining the type of an object is a rather expensive - * operation compared to the other stuff here. It's also not - * very flexible. - */ - if (NULL!=(temp_dset=H5D_open (loc, name))) { - statbuf->type = H5G_DATASET; - H5D_close (temp_dset); - } 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; - } + statbuf->type = H5G_get_type(&obj_ent); H5E_clear(); /*clear errors resulting from checking type*/ } } @@ -1864,8 +2016,8 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, * * Purpose: Returns the value of a symbolic link. * - * Return: Success: Non-negative, with at most SIZE bytes of the link - * value copied into the BUF buffer. If the + * Return: Success: Non-negative, with at most SIZE bytes of the + * link value copied into the BUF buffer. If the * link value is larger than SIZE characters * counting the null terminator then the BUF * result will not be null terminated. diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 1cf448f..ac430c1 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -96,9 +96,22 @@ typedef struct H5G_entry_t { typedef struct H5G_t H5G_t; /* + * This table contains a list of object types, descriptions, and the + * functions that determine if some object is a particular type. The table + * is allocated dynamically. + */ +typedef struct H5G_typeinfo_t { + intn type; /*one of the public H5G_* types */ + htri_t (*isa)(H5G_entry_t*); /*function to determine type */ + char *desc; /*description of object type */ +} H5G_typeinfo_t; + +/* * Library prototypes... These are the ones that other packages routinely * call. */ +herr_t H5G_register_type(intn type, htri_t(*isa)(H5G_entry_t*), + const char *desc); H5G_entry_t *H5G_loc (hid_t loc_id); herr_t H5G_mkroot (H5F_t *f, H5G_entry_t *root_entry); H5G_entry_t *H5G_entof (H5G_t *grp); @@ -108,8 +121,10 @@ H5G_t *H5G_open (H5G_entry_t *loc, const char *name); H5G_t *H5G_reopen (H5G_t *grp); herr_t H5G_close (H5G_t *grp); H5G_t *H5G_rootof(H5F_t *f); +htri_t H5G_isa(H5G_entry_t *ent); herr_t H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name, const char *new_name, uintn namei_flags); +intn H5G_get_type(H5G_entry_t *ent); herr_t H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/); herr_t H5G_linkval (H5G_entry_t *loc, const char *name, size_t size, diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index cc3cc7d..32fc1d4 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -34,13 +34,27 @@ typedef enum H5G_link_t { H5G_LINK_SOFT = 1 } H5G_link_t; -/* An object has a certain type */ +/* + * An object has a certain type. The first few numbers are reserved for use + * internally by HDF5. Users may add their own types with higher values. The + * values are never stored in the file -- they only exist while an + * application is running. An object may satisfy the `isa' function for more + * than one type. + */ #define H5G_UNKNOWN (-1) /* Unknown object type */ #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 */ -#define H5G_NTYPES 4 /* THIS MUST BE LAST */ +#define H5G_RAGGED 4 /* Object is a ragged array */ +#define H5G_RESERVED_5 5 /* Reserved for future use */ +#define H5G_RESERVED_6 6 /* Reserved for future use */ +#define H5G_RESERVED_7 7 /* Reserved for future use */ + +#define H5G_NTYPES 256 /* Max possible number of types */ +#define H5G_NLIBTYPES 8 /* Number of internal types */ +#define H5G_NUSERTYPES (H5G_NTYPES-H5G_NLIBTYPES) +#define H5G_USERTYPE(X) (8+(X)) /* User defined types */ /* Information about an object */ typedef struct H5G_stat_t { @@ -878,6 +878,55 @@ H5O_count (H5G_entry_t *ent, const H5O_class_t *type) /*------------------------------------------------------------------------- + * Function: H5O_exists + * + * Purpose: Determines if a particular message exists in an object + * header without trying to decode the message. + * + * Return: Success: FALSE if the message does not exist; TRUE if + * th message exists. + * + * Failure: FAIL if the existence of the message could + * not be determined due to some error such as + * not being able to read the object header. + * + * Programmer: Robb Matzke + * Monday, November 2, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5O_exists(H5G_entry_t *ent, const H5O_class_t *type, intn sequence) +{ + H5O_t *oh=NULL; + intn i; + + FUNC_ENTER(H5O_exists, FAIL); + assert(ent); + assert(ent->file); + assert(type); + assert(sequence>=0); + + /* Load the object header */ + if (NULL==(oh=H5AC_find(ent->file, H5AC_OHDR, &(ent->header), + NULL, NULL))) { + HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, + "unable to load object header"); + } + + /* Scan through the messages looking for the right one */ + for (i=0; i<oh->nmesgs; i++) { + if (type->id!=oh->mesg[i].type->id) continue; + if (--sequence<0) break; + } + + FUNC_LEAVE(sequence<0); +} + + +/*------------------------------------------------------------------------- * Function: H5O_read * * Purpose: Reads a message from an object header and returns a pointer diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 7dff3c9..16fbded 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -273,6 +273,7 @@ herr_t H5O_open (H5G_entry_t *ent); herr_t H5O_close (H5G_entry_t *ent); intn H5O_link (H5G_entry_t *ent, intn adjust); intn H5O_count (H5G_entry_t *ent, const H5O_class_t *type); +htri_t H5O_exists(H5G_entry_t *ent, const H5O_class_t *type, intn sequence); void *H5O_read (H5G_entry_t *ent, const H5O_class_t *type, intn sequence, void *mesg); intn H5O_modify (H5G_entry_t *ent, const H5O_class_t *type, intn overwrite, @@ -398,6 +398,67 @@ H5RAopen(hid_t loc_id, const char *name) /*------------------------------------------------------------------------- + * Function: H5RA_isa + * + * Purpose: Determines if an object is a ragged array. + * + * Return: Success: TRUE if the object is a ragged array; FALSE + * otherwise. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, November 4, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5RA_isa(H5G_entry_t *ent) +{ + htri_t exists; + H5G_entry_t d_ent; + + FUNC_ENTER(H5RA_isa, FAIL); + + /* Open the container group */ + if ((exists=H5G_isa(ent))<0) { + HRETURN_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL, + "unable to read object header"); + } else if (!exists) { + HRETURN(FALSE); + } + + /* Is `raw' a dataset? */ + if (H5G_find(ent, "raw", NULL, &d_ent)<0 || + (exists=H5D_isa(&d_ent))<0) { + HRETURN_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found"); + } else if (!exists) { + HRETURN(FALSE); + } + + /* Is `over' a dataset? */ + if (H5G_find(ent, "over", NULL, &d_ent)<0 || + (exists=H5D_isa(&d_ent))<0) { + HRETURN_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found"); + } else if (!exists) { + HRETURN(FALSE); + } + + /* Is `meta' a dataset? */ + if (H5G_find(ent, "meta", NULL, &d_ent)<0 || + (exists=H5D_isa(&d_ent))<0) { + HRETURN_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found"); + } else if (!exists) { + HRETURN(FALSE); + } + + FUNC_LEAVE(TRUE); +} + + +/*------------------------------------------------------------------------- * Function: H5RA_open * * Purpose: Open a ragged array. The name of the array is the same as diff --git a/src/H5RAprivate.h b/src/H5RAprivate.h index 19e11d7..89e83db 100644 --- a/src/H5RAprivate.h +++ b/src/H5RAprivate.h @@ -19,6 +19,7 @@ herr_t H5RA_close(H5RA_t *ra); H5RA_t *H5RA_create(H5G_entry_t *loc, const char *name, H5T_t *type, const H5D_create_t *dcpl); H5RA_t *H5RA_open(H5G_entry_t *loc, const char *name); +htri_t H5RA_isa(H5G_entry_t *ent); herr_t H5RA_write(H5RA_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type, hsize_t size[], void *buf[]); herr_t H5RA_read(H5RA_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type, @@ -3466,6 +3466,41 @@ H5T_create(H5T_class_t type, size_t size) /*------------------------------------------------------------------------- + * Function: H5T_isa + * + * Purpose: Determines if an object has the requisite messages for being + * a data type. + * + * Return: Success: TRUE if the required data type messages are + * present; FALSE otherwise. + * + * Failure: FAIL if the existence of certain messages + * cannot be determined. + * + * Programmer: Robb Matzke + * Monday, November 2, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +htri_t +H5T_isa(H5G_entry_t *ent) +{ + htri_t exists; + + FUNC_ENTER(H5T_isa, FAIL); + assert(ent); + + if ((exists=H5O_exists(ent, H5O_DTYPE, 0))<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to read object header"); + } + FUNC_LEAVE(exists); +} + + +/*------------------------------------------------------------------------- * Function: H5T_open * * Purpose: Open a named data type. diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 25d4f6d..3b602a1 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -44,6 +44,7 @@ typedef enum H5T_copy_t { /* Private functions */ herr_t H5T_init (void); herr_t H5T_init_interface (void); +htri_t H5T_isa(H5G_entry_t *ent); H5T_t *H5T_open (H5G_entry_t *loc, const char *name); H5T_t *H5T_create (H5T_class_t type, size_t size); H5T_t *H5T_copy (const H5T_t *old_dt, H5T_copy_t method); diff --git a/src/H5config.h.in b/src/H5config.h.in index 755ec7e..a08c7e2 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -44,7 +44,7 @@ /* Define if it's safe to use `long long' for hsize_t and hssize_t */ #undef HAVE_LARGE_HSIZET -/* The width parameter for printf formats for type `long long', us. `ll' */ +/* Width for printf() for type `long long' or `__int64', us. `ll' */ #undef PRINTF_LL_WIDTH /* Define if `tm_gmtoff' is a member of `struct tm' */ @@ -56,6 +56,9 @@ /* Define if `struct timezone' is defined */ #undef HAVE_STRUCT_TIMEZONE +/* Define if `struct stat' has the `st_blocks' field */ +#undef HAVE_STAT_ST_BLOCKS + /* The number of bytes in a __int64. */ #undef SIZEOF___INT64 diff --git a/tools/h5ls.c b/tools/h5ls.c index 39124b8..3d7b845 100644 --- a/tools/h5ls.c +++ b/tools/h5ls.c @@ -5,14 +5,15 @@ * Programmer: Robb Matzke <matzke@llnl.gov> * Monday, March 23, 1998 */ -#include <ctype.h> -#include <h5tools.h> -#include <hdf5.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> + +/* + * We include the private header file so we can get to the uniform + * programming environment it declares. + */ #include <H5private.h> +#include <h5tools.h> + #ifndef HAVE_ATTRIBUTE # undef __attribute__ # define __attribute__(X) /*void*/ @@ -25,6 +26,7 @@ static int verbose_g = 0; static int dump_g = 0; static int width_g = 80; +static int string_g = FALSE; /* Information about how to display each type of object */ static struct dispatch_t { @@ -68,6 +70,7 @@ usage: %s [OPTIONS] FILE [OBJECTS...]\n\ OPTIONS\n\ -h, -?, --help Print a usage message and exit\n\ -d, --dump Print the values of datasets\n\ + -s, --string Print 1-byte integer datasets as ASCII\n\ -wN, --width=N Set the number of columns of output\n\ -v, --verbose Generate more verbose output\n\ -V, --version Print version number and exit\n\ @@ -112,9 +115,11 @@ dump_dataset_values(hid_t dset) /* * If the dataset is a 1-byte integer type then format it as an ASCI - * character string instead of integers. + * character string instead of integers if the `-s' or `--string' + * command-line option was given. */ - if (1==size && H5T_INTEGER==H5Tget_class(f_type)) { + if (string_g && 1==size && H5T_INTEGER==H5Tget_class(f_type)) { + info.ascii = TRUE; info.elmt_suf1 = ""; info.elmt_suf2 = ""; info.idx_fmt = " (%s) \""; @@ -286,6 +291,34 @@ dataset_list2(hid_t dset) /*------------------------------------------------------------------------- + * Function: ragged_list2 + * + * Purpose: List information about a ragged array which should appear + * after information which is general to all objects. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, November 5, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +ragged_list2(hid_t __unused__ ra) +{ + if (dump_g) { + puts(" Data: Not implemented yet (see values of member"); + puts(" datasets `raw', `over', and `meta')"); + } + return -1; +} + + +/*------------------------------------------------------------------------- * Function: link_open * * Purpose: This gets called to open a symbolic link. Since symbolic @@ -399,7 +432,6 @@ list (hid_t group, const char *name, void __unused__ *cd) return 0; } - /*------------------------------------------------------------------------- * Function: main @@ -426,6 +458,7 @@ main (int argc, char *argv[]) const char *s; char *rest; int argno; + H5G_stat_t sb; DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose, dataset_list1, dataset_list2); @@ -435,6 +468,8 @@ main (int argc, char *argv[]) NULL, NULL); DISPATCH(H5G_LINK, "-> ", link_open, NULL, NULL, NULL); + DISPATCH(H5G_RAGGED, "Ragged Array", H5Gopen, H5Gclose, + NULL, ragged_list2); /* Name of this program without the path */ if ((progname=strrchr (argv[0], '/'))) progname++; @@ -451,6 +486,8 @@ main (int argc, char *argv[]) exit(0); } else if (!strcmp(argv[argno], "--dump")) { dump_g++; + } else if (!strcmp(argv[argno], "--string")) { + string_g = TRUE; } else if (!strncmp(argv[argno], "--width=", 8)) { width_g = strtol(argv[argno]+8, &rest, 0); if (width_g<=0 || *rest) { @@ -488,6 +525,9 @@ main (int argc, char *argv[]) case 'd': /* --dump */ dump_g++; break; + case 's': + string_g = TRUE; + break; case 'v': /* --verbose */ verbose_g++; break; @@ -531,17 +571,15 @@ main (int argc, char *argv[]) H5Giterate(file, "/", NULL, list, NULL); } else { for (/*void*/; argno<argc; argno++) { - H5E_BEGIN_TRY { - root = H5Gopen (file, argv[argno]); - } H5E_END_TRY; - if (root>=0) { + if (H5Gget_objinfo(file, argv[argno], TRUE, &sb)>=0 && + H5G_GROUP==sb.type) { H5Giterate(file, argv[argno], NULL, list, NULL); } else if ((root=H5Gopen(file, "/"))<0) { exit(1); } else { list(root, argv[argno], NULL); + if (H5Gclose(root)<0) exit(1); } - if (H5Gclose(root)<0) exit(1); } } diff --git a/tools/h5tools.c b/tools/h5tools.c index d3c9615..83915b3 100644 --- a/tools/h5tools.c +++ b/tools/h5tools.c @@ -22,7 +22,7 @@ * size of that temporary buffer in bytes. For efficiency's sake, choose the * largest value suitable for your machine (for testing use a small value). */ -#if 0 +#if 1 #define H5DUMP_BUFSIZE (1024*1024) #else #define H5DUMP_BUFSIZE (1024) @@ -126,8 +126,9 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp) } else if (H5Tequal(type, H5T_NATIVE_FLOAT)) { sprintf(temp, "%g", *((float*)vp)); - } else if (H5Tequal(type, H5T_NATIVE_CHAR) || - H5Tequal(type, H5T_NATIVE_UCHAR)) { + } else if (info->ascii && + (H5Tequal(type, H5T_NATIVE_CHAR) || + H5Tequal(type, H5T_NATIVE_UCHAR))) { switch (*((char*)vp)) { case '"': strcpy(temp, "\\\""); @@ -223,7 +224,13 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp) } } if (quote) sprintf(temp+strlen(temp), "%c", quote); - + + } else if (H5Tequal(type, H5T_NATIVE_CHAR)) { + sprintf(temp, "%d", *((signed char*)vp)); + + } else if (H5Tequal(type, H5T_NATIVE_UCHAR)) { + sprintf(temp, "%u", *((unsigned char*)vp)); + } else if (H5Tequal(type, H5T_NATIVE_SHORT)) { sprintf(temp, "%d", *((short*)vp)); diff --git a/tools/h5tools.h b/tools/h5tools.h index 374bb71..54017aa 100644 --- a/tools/h5tools.h +++ b/tools/h5tools.h @@ -58,6 +58,13 @@ typedef struct h5dump_t { /* * Fields associated with the individual elements. * + * ascii: If set then print 1-byte integer values as an ASCII + * character (no quotes). If the character is one of the + * standard C escapes then print the escaped version. If + * the character is unprintable then print a 3-digit octal + * escape. If `ascii' is zero then then 1-byte integers are + * printed as numeric values. The default is zero. + * * fmt: A printf(3c) format to use to print the value string * after it has been rendered. The default is "%s". * @@ -69,6 +76,7 @@ typedef struct h5dump_t { * are followed on the same line by another element. The * default is a single space. */ + int ascii; const char *elmt_fmt; const char *elmt_suf1; const char *elmt_suf2; |