1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14
15 #include "H5private.h"
16 #include "h5tools.h"
17 #include "h5tools_utils.h"
18
19 /* Name of tool */
20 #define PROGRAMNAME "h5mkgrp"
21
22 /* Exit status for tools library routines */
23 int d_status = EXIT_SUCCESS;
24
25 /* command-line options: short and long-named parameters */
26 static const char *s_opts = "hlpvV";
27 static struct long_options l_opts[] = {
28 { "help", no_arg, 'h' },
29 { "latest", no_arg, 'l' },
30 { "parents", no_arg, 'p' },
31 { "verbose", no_arg, 'v' },
32 { "version", no_arg, 'V' },
33 { NULL, 0, '\0' }
34 };
35
36 /* Command line parameter settings */
37 typedef struct {
38 char *fname; /* File name to operate on */
39 hbool_t latest; /* Whether file should use latest format versions */
40 hbool_t verbose; /* Whether output should be verbose */
41 hbool_t parents; /* Whether to create intermediate groups */
42 size_t ngroups; /* Number of groups to create */
43 char **groups; /* Pointer to array of group names */
44 } param_t;
45 param_t params; /* Command line parameter settings */
46
47
48 /*-------------------------------------------------------------------------
49 * Function: leave
50 *
51 * Purpose: Shutdown MPI and/or HDF5 and call exit()
52 *
53 * Return: Does not return
54 *
55 * Programmer: Quincey Koziol, 2/13/2007
56 *
57 *-------------------------------------------------------------------------
58 */
59 static void
leave(int ret)60 leave(int ret)
61 {
62 size_t curr_group;
63
64 if (params.fname)
65 HDfree (params.fname);
66 if (params.ngroups) {
67 for(curr_group = 0; curr_group < params.ngroups; curr_group++)
68 HDfree (params.groups[curr_group]);
69 HDfree (params.groups);
70 }
71 h5tools_close();
72 HDexit(ret);
73 } /* end leave() */
74
75
76 /*-------------------------------------------------------------------------
77 * Function: usage
78 *
79 * Purpose: Prints a usage message on stderr and then returns.
80 *
81 * Return: void
82 *
83 * Programmer: Quincey Koziol, 2/13/2007
84 *
85 *-------------------------------------------------------------------------
86 */
87 static void
usage(void)88 usage(void)
89 {
90 HDfprintf(stdout, "\
91 usage: h5mkgrp [OPTIONS] FILE GROUP...\n\
92 OPTIONS\n\
93 -h, --help Print a usage message and exit\n\
94 -l, --latest Use latest version of file format to create groups\n\
95 -p, --parents No error if existing, make parent groups as needed\n\
96 -v, --verbose Print information about OBJECTS and OPTIONS\n\
97 -V, --version Print version number and exit\n");
98 } /* end usage() */
99
100
101 /*-------------------------------------------------------------------------
102 * Function: parse_command_line
103 *
104 * Purpose: Parses command line and sets up global variable to control output
105 *
106 * Return: Success: 0
107 * Failure: -1
108 *
109 * Programmer: Quincey Koziol, 2/13/2007
110 *
111 *-------------------------------------------------------------------------
112 */
113 static int
parse_command_line(int argc,const char * argv[],param_t * parms)114 parse_command_line(int argc, const char *argv[], param_t *parms)
115 {
116 int opt; /* Option from command line */
117 size_t curr_group; /* Current group name to copy */
118
119 /* Check for empty command line */
120 if(argc == 1) {
121 usage();
122 leave(EXIT_SUCCESS);
123 } /* end if */
124
125 /* Parse command line options */
126 while((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
127 switch((char)opt) {
128 /* Display 'help' */
129 case 'h':
130 usage();
131 leave(EXIT_SUCCESS);
132 break;
133
134 /* Create objects with the latest version of the format */
135 case 'l':
136 parms->latest = TRUE;
137 break;
138
139 /* Create parent groups */
140 case 'p':
141 parms->parents = TRUE;
142 break;
143
144 /* Verbose output */
145 case 'v':
146 parms->verbose = TRUE;
147 break;
148
149 /* Display version */
150 case 'V':
151 print_version(h5tools_getprogname());
152 leave(EXIT_SUCCESS);
153 break;
154
155 /* Bad command line argument */
156 default:
157 usage();
158 leave(EXIT_FAILURE);
159 } /* end switch */
160 } /* end while */
161
162 /* Check for file name to be processed */
163 if(argc <= opt_ind) {
164 error_msg("missing file name\n");
165 usage();
166 leave(EXIT_FAILURE);
167 } /* end if */
168
169 /* Retrieve file name */
170 parms->fname = HDstrdup(argv[opt_ind]);
171 opt_ind++;
172
173 /* Check for group(s) to be created */
174 if(argc <= opt_ind) {
175 error_msg("missing group name(s)\n");
176 usage();
177 leave(EXIT_FAILURE);
178 } /* end if */
179
180 /* Allocate space for the group name pointers */
181 parms->ngroups = (size_t)(argc - opt_ind);
182 parms->groups = (char **)HDmalloc(parms->ngroups * sizeof(char *));
183
184 /* Retrieve the group names */
185 curr_group = 0;
186 while(opt_ind < argc) {
187 parms->groups[curr_group] = HDstrdup(argv[opt_ind]);
188 curr_group++;
189 opt_ind++;
190 } /* end while */
191
192 #ifdef QAK
193 HDfprintf(stderr, "parms->parents = %t\n", parms->parents);
194 HDfprintf(stderr, "parms->verbose = %t\n", parms->verbose);
195 HDfprintf(stderr, "parms->fname = '%s'\n", parms->fname);
196 HDfprintf(stderr, "parms->ngroups = %Zu\n", parms->ngroups);
197 for(curr_group = 0; curr_group < parms->ngroups; curr_group++)
198 HDfprintf(stderr, "parms->group[%Zu] = '%s'\n", curr_group, parms->groups[curr_group]);
199 #endif /* QAK */
200
201 return(0);
202 } /* parse_command_line() */
203
204
205 /*-------------------------------------------------------------------------
206 * Function: main
207 *
208 * Purpose: Create group(s) in an HDF5 file
209 *
210 * Programmer: Quincey Koziol, 2/13/2007
211 *
212 *-------------------------------------------------------------------------
213 */
214 int
main(int argc,const char * argv[])215 main(int argc, const char *argv[])
216 {
217 hid_t fid; /* HDF5 file ID */
218 hid_t fapl_id; /* File access property list ID */
219 hid_t lcpl_id; /* Link creation property list ID */
220 size_t curr_group; /* Current group to create */
221
222 h5tools_setprogname(PROGRAMNAME);
223 h5tools_setstatus(EXIT_SUCCESS);
224
225 /* Disable the HDF5 library's error reporting */
226 H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
227
228 /* Initialize h5tools lib */
229 h5tools_init();
230
231 /* Parse command line */
232 HDmemset(¶ms, 0, sizeof(params));
233 if(parse_command_line(argc, argv, ¶ms) < 0) {
234 error_msg("unable to parse command line arguments\n");
235 leave(EXIT_FAILURE);
236 } /* end if */
237
238 /* Create file access property list */
239 if((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) {
240 error_msg("Could not create file access property list\n");
241 leave(EXIT_FAILURE);
242 } /* end if */
243
244 /* Check for creating groups with new format version */
245 if(params.latest) {
246 /* Set the "use the latest version of the format" bounds */
247 if(H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) {
248 error_msg("Could not set property for using latest version of the format\n");
249 leave(EXIT_FAILURE);
250 } /* end if */
251
252 /* Display some output if requested */
253 if(params.verbose)
254 HDprintf("%s: Creating groups with latest version of the format\n", h5tools_getprogname());
255 } /* end if */
256
257 /* Attempt to open an existing HDF5 file first */
258 fid = h5tools_fopen(params.fname, H5F_ACC_RDWR, fapl_id, NULL, NULL, 0);
259
260 /* If we couldn't open an existing file, try creating file */
261 /* (use "EXCL" instead of "TRUNC", so we don't blow away existing non-HDF5 file) */
262 if(fid < 0)
263 fid = H5Fcreate(params.fname, H5F_ACC_EXCL, H5P_DEFAULT, fapl_id);
264
265 /* Test for error in opening file */
266 if(fid < 0) {
267 error_msg("Could not open output file '%s'\n", params.fname);
268 leave(EXIT_FAILURE);
269 } /* end if */
270
271 /* Create link creation property list */
272 if((lcpl_id = H5Pcreate(H5P_LINK_CREATE)) < 0) {
273 error_msg("Could not create link creation property list\n");
274 leave(EXIT_FAILURE);
275 } /* end if */
276
277 /* Check for creating intermediate groups */
278 if(params.parents) {
279 /* Set the intermediate group creation property */
280 if(H5Pset_create_intermediate_group(lcpl_id, TRUE) < 0) {
281 error_msg("Could not set property for creating parent groups\n");
282 leave(EXIT_FAILURE);
283 } /* end if */
284
285 /* Display some output if requested */
286 if(params.verbose)
287 HDprintf("%s: Creating parent groups\n", h5tools_getprogname());
288 } /* end if */
289
290 /* Loop over creating requested groups */
291 for(curr_group = 0; curr_group < params.ngroups; curr_group++) {
292 hid_t gid; /* Group ID */
293
294 /* Attempt to create a group */
295 if((gid = H5Gcreate2(fid, params.groups[curr_group], lcpl_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
296 error_msg("Could not create group '%s'\n", params.groups[curr_group]);
297 leave(EXIT_FAILURE);
298 } /* end if */
299
300 /* Close the group */
301 if(H5Gclose(gid) < 0) {
302 error_msg("Could not close group '%s'??\n", params.groups[curr_group]);
303 leave(EXIT_FAILURE);
304 } /* end if */
305
306 /* Display some output if requested */
307 if(params.verbose)
308 HDprintf("%s: created group '%s'\n", h5tools_getprogname(), params.groups[curr_group]);
309 } /* end for */
310
311 /* Close link creation property list */
312 if(H5Pclose(lcpl_id) < 0) {
313 error_msg("Could not close link creation property list\n");
314 leave(EXIT_FAILURE);
315 } /* end if */
316
317 /* Close file */
318 if(H5Fclose(fid) < 0) {
319 error_msg("Could not close output file '%s'??\n", params.fname);
320 leave(EXIT_FAILURE);
321 } /* end if */
322
323 /* Close file access property list */
324 if(H5Pclose(fapl_id) < 0) {
325 error_msg("Could not close file access property list\n");
326 leave(EXIT_FAILURE);
327 } /* end if */
328
329 leave(EXIT_SUCCESS);
330 } /* end main() */
331
332