summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorBill Wendling <wendling@ncsa.uiuc.edu>2001-03-08 20:18:42 (GMT)
committerBill Wendling <wendling@ncsa.uiuc.edu>2001-03-08 20:18:42 (GMT)
commit37957dfe1dcc08ec9a34ddc26fed2d9ae1dd4509 (patch)
treedccd8defda70053b747b1724c53657ebbcc51647 /tools
parent8e7f06a1fc019116f9b99a3b6a740318abf55376 (diff)
downloadhdf5-37957dfe1dcc08ec9a34ddc26fed2d9ae1dd4509.zip
hdf5-37957dfe1dcc08ec9a34ddc26fed2d9ae1dd4509.tar.gz
hdf5-37957dfe1dcc08ec9a34ddc26fed2d9ae1dd4509.tar.bz2
[svn-r3571] Purpose:
New Modules Description: Separated the "generic" functions out of the h5tools module into their own separate module to make things a bit nicer to deal with. Platforms tested: Linux
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/h5tools_utils.c648
-rw-r--r--tools/lib/h5tools_utils.h114
2 files changed, 762 insertions, 0 deletions
diff --git a/tools/lib/h5tools_utils.c b/tools/lib/h5tools_utils.c
new file mode 100644
index 0000000..df12a99
--- /dev/null
+++ b/tools/lib/h5tools_utils.c
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 2001 National Center for Supercomputing Applications
+ * All rights reserved.
+ *
+ * Programmer: Bill Wendling <wendling@ncsa.uiuc.edu>
+ * Tuesday, 6. March 2001
+ */
+
+/*
+ * Portions of this work are derived from _Obfuscated C and Other Mysteries_,
+ * by Don Libes, copyright (c) 1993 by John Wiley & Sons, Inc.
+ */
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "h5tools_utils.h"
+#include "H5private.h"
+
+/* global variables */
+int nCols = 80;
+
+/* ``get_option'' variables */
+int opt_err = 1; /*get_option prints errors if this is on */
+int opt_ind = 1; /*token pointer */
+const char *opt_arg; /*flag argument (or value) */
+
+/* local functions */
+static void add_obj(table_t *table, unsigned long *objno, char *objname);
+
+
+/*-------------------------------------------------------------------------
+ * Function: error_msg
+ *
+ * Purpose: Print a nicely formatted error message to stderr flushing the
+ * stdout stream first.
+ *
+ * Return: Nothing
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 20. February 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+error_msg(const char *progname, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fflush(stdout);
+ fprintf(stderr, "%s error: ", progname);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: warn_msg
+ *
+ * Purpose: Print a nicely formatted warning message to stderr flushing
+ * the stdout stream first.
+ *
+ * Return: Nothing
+ *
+ * Programmer: Bill Wendling
+ * Tuesday, 20. February 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+warn_msg(const char *progname, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ fflush(stdout);
+ fprintf(stderr, "%s warning: ", progname);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_option
+ *
+ * Purpose: Determine the command-line options a user specified. We can
+ * accept both short and long type command-lines.
+ *
+ * Return: Success: The short valued "name" of the command line
+ * parameter or EOF if there are no more
+ * parameters to process.
+ *
+ * Failure: A question mark.
+ *
+ * Programmer: Bill Wendling
+ * Friday, 5. January 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+get_option(int argc, const char **argv, const char *opts, const struct long_options *l_opts)
+{
+ static int sp = 1; /* character index in current token */
+ int opt_opt = '?'; /* option character passed back to user */
+
+ if (sp == 1) {
+ /* check for more flag-like tokens */
+ if (opt_ind >= argc || argv[opt_ind][0] != '-' || argv[opt_ind][1] == '\0') {
+ return EOF;
+ } else if (strcmp(argv[opt_ind], "--") == 0) {
+ opt_ind++;
+ return EOF;
+ }
+ }
+
+ if (sp == 1 && argv[opt_ind][0] == '-' && argv[opt_ind][1] == '-') {
+ /* long command line option */
+ const char *arg = &argv[opt_ind][2];
+ register int i;
+
+ for (i = 0; l_opts && l_opts[i].name; i++) {
+ size_t len = strlen(l_opts[i].name);
+
+ if (strncmp(arg, l_opts[i].name, len) == 0) {
+ /* we've found a matching long command line flag */
+ opt_opt = l_opts[i].shortval;
+
+ if (l_opts[i].has_arg != no_arg) {
+ if (arg[len] == '=') {
+ opt_arg = &arg[len + 1];
+ } else if (opt_ind < (argc - 1) && argv[opt_ind + 1][0] != '-') {
+ opt_arg = argv[++opt_ind];
+ } else if (l_opts[i].has_arg == require_arg) {
+ if (opt_err)
+ fprintf(stderr,
+ "%s: option required for \"--%s\" flag\n",
+ argv[0], arg);
+
+ opt_opt = '?';
+ }
+ } else {
+ if (arg[len] == '=') {
+ if (opt_err)
+ fprintf(stderr,
+ "%s: no option required for \"%s\" flag\n",
+ argv[0], arg);
+
+ opt_opt = '?';
+ }
+
+ opt_arg = NULL;
+ }
+
+ break;
+ }
+ }
+
+ if (l_opts[i].name == NULL) {
+ /* exhausted all of the l_opts we have and still didn't match */
+ if (opt_err)
+ fprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], arg);
+
+ opt_opt = '?';
+ }
+
+ opt_ind++;
+ sp = 1;
+ } else {
+ register char *cp; /* pointer into current token */
+
+ /* short command line option */
+ opt_opt = argv[opt_ind][sp];
+
+ if (opt_opt == ':' || (cp = strchr(opts, opt_opt)) == 0) {
+ if (opt_err)
+ fprintf(stderr, "%s: unknown option \"%c\"\n",
+ argv[0], opt_opt);
+
+ /* if no chars left in this token, move to next token */
+ if (argv[opt_ind][++sp] == '\0') {
+ opt_ind++;
+ sp = 1;
+ }
+
+ return '?';
+ }
+
+ if (*++cp == ':') {
+ /* if a value is expected, get it */
+ if (argv[opt_ind][sp + 1] != '\0') {
+ /* flag value is rest of current token */
+ opt_arg = &argv[opt_ind++][sp + 1];
+ } else if (++opt_ind >= argc) {
+ if (opt_err)
+ fprintf(stderr,
+ "%s: value expected for option \"%c\"\n",
+ argv[0], opt_opt);
+
+ opt_opt = '?';
+ } else {
+ /* flag value is next token */
+ opt_arg = argv[opt_ind++];
+ }
+
+ sp = 1;
+ } else {
+ /* set up to look at next char in token, next time */
+ if (argv[opt_ind][++sp] == '\0') {
+ /* no more in current token, so setup next token */
+ opt_ind++;
+ sp = 1;
+ }
+
+ opt_arg = NULL;
+ }
+ }
+
+ /* return the current flag character found */
+ return opt_opt;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: indentation
+ *
+ * Purpose: Print spaces for indentation
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+indentation(int x)
+{
+ if (x < nCols) {
+ while (x-- > 0)
+ printf(" ");
+ } else {
+ fprintf(stderr, "error: the indentation exceeds the number of cols.\n");
+ exit(1);
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_version
+ *
+ * Purpose: Print the program name and the version information which is
+ * defined the same as the HDF5 library version.
+ *
+ * Return: void
+ *
+ * Programmer: unknown
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+print_version(const char *progname)
+{
+ printf("%s: Version %u.%u.%u%s%s\n",
+ progname, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE,
+ H5_VERS_SUBRELEASE[0] ? "-" : "", H5_VERS_SUBRELEASE);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: init_table
+ *
+ * Purpose: allocate and initialize tables for shared groups, datasets,
+ * and committed types
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+init_table(table_t **tbl)
+{
+ int i;
+ table_t *table = malloc(sizeof(table_t));
+
+ table->size = 20;
+ table->nobjs = 0;
+ table->objs = malloc(table->size * sizeof(obj_t));
+
+ for (i = 0; i < table->size; i++) {
+ table->objs[i].objno[0] = table->objs[i].objno[1] = 0;
+ table->objs[i].displayed = 0;
+ table->objs[i].recorded = 0;
+ table->objs[i].objflag = 0;
+ }
+
+ *tbl = table;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: init_prefix
+ *
+ * Purpose: allocate and initialize prefix
+ *
+ * Return: void
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+init_prefix(char **prefix, int prefix_len)
+{
+ assert(prefix_len > 0);
+ *prefix = calloc((size_t)prefix_len, 1);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: free_table
+ *
+ * Purpose: free tables for shared groups, datasets,
+ * and committed types
+ *
+ * Return: void
+ *
+ * Programmer: Paul Harten
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+free_table(table_t **table)
+{
+ HDfree((*table)->objs);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: search_obj
+ *
+ * Purpose: search the object specified by objno in the table
+ *
+ * Return: Success: an integer, the location of the object
+ *
+ * Failure: FAIL if object is not found
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+search_obj(table_t *table, unsigned long *objno)
+{
+ register int i;
+
+ for (i = 0; i < table->nobjs; i++)
+ if (table->objs[i].objno[0] == *objno && table->objs[i].objno[1] == *(objno + 1))
+ return i;
+
+ return FAIL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: find_objs
+ *
+ * Purpose: Find objects, committed types and store them in tables
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+find_objs(hid_t group, const char *name, void *op_data)
+{
+ hid_t obj, type;
+ H5G_stat_t statbuf;
+ char *tmp;
+ find_objs_t *info = (find_objs_t*)op_data;
+ register int i;
+
+ if (info->threshold > 1)
+ /*will get an infinite loop if greater than 1*/
+ return FAIL;
+
+ H5Gget_objinfo(group, name, TRUE, &statbuf);
+
+ tmp = malloc(strlen(info->prefix) + strlen(name) + 2);
+ strcpy(tmp, info->prefix);
+
+ switch (statbuf.type) {
+ case H5G_GROUP:
+ if ((obj = H5Gopen(group, name)) >= 0) {
+ if (info->prefix_len < (int)(strlen(info->prefix) + strlen(name) + 2)) {
+ info->prefix_len *= 2;
+ info->prefix = realloc(info->prefix,
+ info->prefix_len * sizeof(char));
+ }
+
+ strcat(strcat(info->prefix,"/"), name);
+
+ if (statbuf.nlink > info->threshold) {
+ if (search_obj(info->group_table, statbuf.objno) == FAIL) {
+ add_obj(info->group_table, statbuf.objno, info->prefix);
+ H5Giterate(obj, ".", NULL, find_objs, (void *)info);
+ }
+ } else {
+ H5Giterate (obj, ".", NULL, find_objs, (void *)info);
+ }
+
+ strcpy(info->prefix, tmp);
+ H5Gclose (obj);
+ } else {
+ info->status = 1;
+ }
+
+ break;
+
+ case H5G_DATASET:
+ strcat(tmp,"/");
+ strcat(tmp,name); /* absolute name of the data set */
+
+ if (statbuf.nlink > info->threshold &&
+ search_obj(info->dset_table, statbuf.objno) == FAIL)
+ add_obj(info->dset_table, statbuf.objno, tmp);
+
+ if ((obj = H5Dopen (group, name)) >= 0) {
+ type = H5Dget_type(obj);
+
+ if (H5Tcommitted(type) > 0) {
+ H5Gget_objinfo(type, ".", TRUE, &statbuf);
+
+ if (search_obj(info->type_table, statbuf.objno) == FAIL) {
+ add_obj(info->type_table, statbuf.objno, tmp);
+ info->type_table->objs[info->type_table->nobjs - 1].objflag = 0;
+ }
+ }
+
+ H5Tclose(type);
+ H5Dclose (obj);
+ } else {
+ info->status = 1;
+ }
+
+ break;
+
+ case H5G_TYPE:
+ strcat(tmp,"/");
+ strcat(tmp,name); /* absolute name of the type */
+ i = search_obj(info->type_table, statbuf.objno);
+
+ if (i == FAIL) {
+ add_obj(info->type_table, statbuf.objno, tmp) ;
+
+ /* named data type */
+ info->type_table->objs[info->type_table->nobjs-1].recorded = 1;
+
+ /* named data type */
+ info->type_table->objs[info->type_table->nobjs-1].objflag = 1;
+ } else {
+ strcpy (info->type_table->objs[i].objname, tmp);
+ info->type_table->objs[i].recorded = 1;
+
+ /* named data type */
+ info->type_table->objs[info->type_table->nobjs-1].objflag = 1;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ free(tmp);
+ return SUCCEED;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: dump_table
+ *
+ * Purpose: display the contents of tables for debugging purposes
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+void
+dump_table(char* tablename, table_t *table)
+{
+ register int i;
+
+ printf("%s: # of entries = %d\n", tablename,table->nobjs);
+
+ for (i = 0; i < table->nobjs; i++)
+ printf("\t%lu %lu %s %d\n",
+ table->objs[i].objno[0],
+ table->objs[i].objno[1],
+ table->objs[i].objname,
+ table->objs[i].objflag);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_table_idx
+ *
+ * Purpose: Determine if objects are in a link loop
+ *
+ * Return: Success: table index of object detected to be in loop
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Paul Harten
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+get_table_idx(table_t *table, unsigned long *objno)
+{
+ return search_obj(table, objno);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_tableflag
+ *
+ * Purpose: Return the i'th element's flag setting
+ *
+ * Return: Boolean setting of the i'th element of the object table flag
+ *
+ * Programmer: Paul Harten
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+get_tableflag(table_t *table, int idx)
+{
+ return table->objs[idx].objflag;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: set_tableflag
+ *
+ * Purpose: Set the i'th element of the object table's flag to TRUE
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: N/A
+ *
+ * Programmer: Paul Harten
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+set_tableflag(table_t *table, int idx)
+{
+ table->objs[idx].objflag = TRUE;
+ return SUCCEED;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_objectname
+ *
+ * Purpose: Get name of i'th object in table
+ *
+ * Return: Success: strdup() of object name character string
+ *
+ * Failure: NULL and sets errno to ENOMEM
+ *
+ * Programmer: Paul Harten
+ *
+ *-------------------------------------------------------------------------
+ */
+char *
+get_objectname(table_t *table, int idx)
+{
+ return strdup(table->objs[idx].objname);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: add_obj
+ *
+ * Purpose: add a shared object to the table
+ * realloc the table if necessary
+ *
+ * Return: void
+ *
+ * Programmer: Ruey-Hsia Li
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void
+add_obj(table_t *table, unsigned long *objno, char *objname)
+{
+ register int i;
+
+ if (table->nobjs == table->size) {
+ table->size *= 2;
+ table->objs = realloc(table->objs, table->size * sizeof(obj_t));
+
+ for (i = table->nobjs; i < table->size; i++) {
+ table->objs[i].objno[0] = table->objs[i].objno[1] = 0;
+ table->objs[i].displayed = 0;
+ table->objs[i].recorded = 0;
+ table->objs[i].objflag = 0;
+ }
+ }
+
+ i = table->nobjs++;
+ table->objs[i].objno[0] = objno[0];
+ table->objs[i].objno[1] = objno[1];
+ strcpy(table->objs[i].objname, objname);
+}
diff --git a/tools/lib/h5tools_utils.h b/tools/lib/h5tools_utils.h
new file mode 100644
index 0000000..eda8e00b
--- /dev/null
+++ b/tools/lib/h5tools_utils.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2001 National Center for Supercomputing Applications
+ * All rights reserved.
+ *
+ * Programmer: Bill Wendling <wendling@ncsa.uiuc.edu>
+ * Tuesday, 6. March 2001
+ *
+ * Purpose: Support functions for the various tools.
+ */
+#ifndef H5TOOLS_UTILS_H__
+#define H5TOOLS_UTILS_H__
+
+#include "hdf5.h"
+
+/*
+ * begin get_option section
+ */
+extern int opt_err; /* getoption prints errors if this is on */
+extern int opt_ind; /* token pointer */
+extern const char *opt_arg; /* flag argument (or value) */
+
+enum {
+ no_arg = 0, /* doesn't take an argument */
+ require_arg, /* requires an argument */
+ optional_arg /* argument is optional */
+};
+
+/*
+ * get_option determines which options are specified on the command line and
+ * returns a pointer to any arguments possibly associated with the option in
+ * the ``opt_arg'' variable. get_option returns the shortname equivalent of
+ * the option. The long options are specified in the following way:
+ *
+ * struct long_options foo[] = {
+ * { "filename", require_arg, 'f' },
+ * { "append", no_arg, 'a' },
+ * { "width", require_arg, 'w' },
+ * { NULL, 0, 0 }
+ * };
+ *
+ * Long named options can have arguments specified as either:
+ *
+ * ``--param=arg'' or ``--param arg''
+ *
+ * Short named options can have arguments specified as either:
+ *
+ * ``-w80'' or ``-w 80''
+ *
+ * and can have more than one short named option specified at one time:
+ *
+ * -aw80
+ *
+ * in which case those options which expect an argument need to come at the
+ * end.
+ */
+typedef struct long_options {
+ const char *name; /* name of the long option */
+ int has_arg; /* whether we should look for an arg */
+ char shortval; /* the shortname equivalent of long arg
+ * this gets returned from get_option */
+} long_options;
+
+extern int get_option(int argc, const char **argv, const char *opt,
+ const struct long_options *l_opt);
+/*
+ * end get_option section
+ */
+
+/*struct taken from the dumper. needed in table struct*/
+typedef struct obj_t {
+ unsigned long objno[2];
+ char objname[1024];
+ int displayed;
+ int recorded;
+ int objflag;
+} obj_t;
+
+/*struct for the tables that the find_objs function uses*/
+typedef struct table_t {
+ int size;
+ int nobjs;
+ obj_t *objs;
+} table_t;
+
+/*this struct stores the information that is passed to the find_objs function*/
+typedef struct find_objs_t {
+ int prefix_len;
+ char *prefix;
+ unsigned int threshold; /* should be 0 or 1 */
+ table_t *group_table;
+ table_t *type_table;
+ table_t *dset_table;
+ int status;
+} find_objs_t;
+
+extern int nCols; /*max number of columns for outputting */
+
+/* Definitions of useful routines */
+extern void indentation(int);
+extern void print_version(const char *progname);
+extern void error_msg(const char *progname, const char *fmt, ...);
+extern void warn_msg(const char *progname, const char *fmt, ...);
+extern void free_table(table_t **table);
+extern void dump_table(char *name, table_t *table);
+extern int get_table_idx(table_t *table, unsigned long *);
+extern int get_tableflag(table_t*, int);
+extern int set_tableflag(table_t*, int);
+extern char *get_objectname(table_t*, int);
+extern herr_t find_objs(hid_t group, const char *name, void *op_data);
+extern int search_obj(table_t *temp, unsigned long *);
+extern void init_table(table_t **tbl);
+extern void init_prefix(char **temp, int);
+
+#endif /* H5TOOLS_UTILS_H__ */