/* h5pAttrib.cc Antino Kim This utility will output information on h5part files accodring to the flags provided from the command line. The parser was imported from the example of h5dump utility with slight modifications. */ #include #include #include #include #include "H5hut.h" #define MAX_LEN 100 /* Function headers */ int get_option(int argc, const char **argv, const char *opts, const struct long_options *l_opts); static void print_help(); static void free_handler(struct arg_handler *hand, int len); static void print_all(h5_file_t* file); static void print_nstep(h5_file_t* file, char * garbage); static void print_file_attributes(h5_file_t* file, char * garbage); static void print_step_attributes(h5_file_t* file, char *attr); static void print_dataset(h5_file_t* file, char *attr); static struct arg_handler* function_assign(int argc, const char *argv[]); /* Global variables */ static int display_all = true; static int print_header = false; static const char* global_fname = NULL; /* `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 = NULL; /*flag argument (or value) */ /* indication whether the flag (option) requires an argument or not */ enum { no_arg = 0, /* doesn't take an argument */ require_arg, /* requires an argument */ }; /* struct for flags (options) */ 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; /* List of options in single characters */ static const char *s_opts = "hnAHa:d:"; /* List of options in full words */ static struct long_options l_opts[] = { { "help", no_arg, 'h' }, // Print help page { "nstep", no_arg, 'n' }, // Print number of steps { "fileA", no_arg, 'A' }, // Print file attributes { "stepA", require_arg, 'a' }, // Print step attributes & values for time step n { "dataset", require_arg, 'd' }, // Print data sets names & values for time step n { "header", require_arg, 'H' }, // Print shorter version without the values { NULL, 0, '\0' } }; /* a structure for handling the order command-line parameters come in */ struct arg_handler { void (*func)(h5_file_t *, char *); char *obj; }; /************************************************************************************ *********************************** FUNCTIONS ************************************* *************************************************************************************/ /* get_option is the parsing function that was majorly ported from h5dump utility */ 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]; 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; } /* Assigns functions according to the parsed result */ static struct arg_handler* function_assign(int argc, const char *argv[]) { struct arg_handler *hand = NULL; int i, option; /* this will be plenty big enough to hold the info */ hand = (arg_handler*)calloc((size_t)argc, sizeof(struct arg_handler)); /* set options according to the command line */ while ((option = get_option(argc, argv, s_opts, l_opts)) != EOF) { switch ((char)option) { case 'h': // Print help page print_help(); exit(1); case 'A': // Print file attributes display_all = 0; for (i = 0; i < argc; i++) { if (!hand[i].func) { hand[i].func = print_file_attributes; hand[i].obj = NULL; // inserting garabage value that we won't use. (For function interface compatibility) break; } } break; case 'a': // Print step attributes & values for time step n display_all = 0; for (i = 0; i < argc; i++) { if (!hand[i].func) { hand[i].func = print_step_attributes; hand[i].obj = strdup(opt_arg); break; } } break; case 'd': // Print data sets names & values for time step n display_all = 0; for (i = 0; i < argc; i++) { if (!hand[i].func) { hand[i].func = print_dataset; hand[i].obj = strdup(opt_arg); break; } } break; case 'n': // Print number of steps display_all = 0; for (i = 0; i < argc; i++) { if (!hand[i].func) { hand[i].func = print_nstep; hand[i].obj = NULL; // inserting garabage value that we won't use. (For function interface compatibility) break; } } break; case 'H': // Print shorter version without the values print_header = true; break; default: print_help(); exit(1); } } return hand; } /* For printing help page */ static void print_help() { fflush(stdout); fprintf(stdout, "\nusage: h5pAttrib [OPTIONS] file\n"); fprintf(stdout, "\n"); fprintf(stdout, " OPTIONS\n"); fprintf(stdout, " -h, --help Print help page\n"); fprintf(stdout, " -n, --nstep Print number of steps\n"); fprintf(stdout, " -A, --fileA Print file attributes\n"); fprintf(stdout, " -a n, --stepA n Print step attributes & values for time step n\n"); fprintf(stdout, " -d n, --dataset n Print data sets names & values for time step n\n"); fprintf(stdout, " -H, --header Print shorter version without the values\n"); fprintf(stdout, "\n"); fprintf(stdout, " Examples:\n"); fprintf(stdout, "\n"); fprintf(stdout, " 1) Show file attribute names & values of sample.h5part\n"); fprintf(stdout, "\n"); fprintf(stdout, " h5pAttrib -A sample.h5part\n"); fprintf(stdout, "\t\t\tOR\n"); fprintf(stdout, " h5pAttrib --fileA sample.h5part\n"); fprintf(stdout, "\n"); fprintf(stdout, " 2) Show step attribute names for time step 5 of sample.h5part\n"); fprintf(stdout, "\n"); fprintf(stdout, " h5pAttrib -a 5 -H sample.h5part\n"); fprintf(stdout, "\t\t\tOR\n"); fprintf(stdout, " h5pAttrib --stepA 5 -H sample.h5part\n"); fprintf(stdout, "\n"); } /* For priting everything (default option when no flags provided.) */ static void print_all(h5_file_t* file) { int nt; char file_attrib[MAX_LEN]; h5_int64_t type; h5_int64_t num_elem; h5_int64_t num_attrib; char step_attrib[MAX_LEN]; h5_int64_t i, j, k; h5_int64_t count; void* value = NULL; h5_int64_t timestep_ctr; char data_name[MAX_LEN]; h5_int64_t num_dataset; h5_int64_t nparticles; fprintf(stdout, "\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); fprintf(stdout, "\n"); nt=H5GetNumSteps(file); fprintf(stdout, "There are total %d number of timesteps.\n",nt); fprintf(stdout, "\nDump result for \"%s\"...\n\n", global_fname); fprintf(stdout, "FILE_ATTRIBUTES:\n"); if(print_header) { num_attrib = H5GetNumFileAttribs(file); for(i=0; i