1 /*
2 Copyright (c) 1994 - 2010, Lawrence Livermore National Security, LLC.
3 LLNL-CODE-425250.
4 All rights reserved.
5
6 This file is part of Silo. For details, see silo.llnl.gov.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 * Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the disclaimer below.
14 * Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the disclaimer (as noted
16 below) in the documentation and/or other materials provided with
17 the distribution.
18 * Neither the name of the LLNS/LLNL nor the names of its
19 contributors may be used to endorse or promote products derived
20 from this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LAWRENCE
26 LIVERMORE NATIONAL SECURITY, LLC, THE U.S. DEPARTMENT OF ENERGY OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
35 This work was produced at Lawrence Livermore National Laboratory under
36 Contract No. DE-AC52-07NA27344 with the DOE.
37
38 Neither the United States Government nor Lawrence Livermore National
39 Security, LLC nor any of their employees, makes any warranty, express
40 or implied, or assumes any liability or responsibility for the
41 accuracy, completeness, or usefulness of any information, apparatus,
42 product, or process disclosed, or represents that its use would not
43 infringe privately-owned rights.
44
45 Any reference herein to any specific commercial products, process, or
46 services by trade name, trademark, manufacturer or otherwise does not
47 necessarily constitute or imply its endorsement, recommendation, or
48 favoring by the United States Government or Lawrence Livermore
49 National Security, LLC. The views and opinions of authors expressed
50 herein do not necessarily state or reflect those of the United States
51 Government or Lawrence Livermore National Security, LLC, and shall not
52 be used for advertising or product endorsement purposes.
53 */
54
55 /* File-wide modifications:
56 *
57 * Sean Ahern, Mon Mar 3 15:38:51 PST 1997 Rearranged most functions, adding
58 * local storage of the return value, to facilitate instrumenting each
59 * function. (e.g. timing routines)
60 *
61 * Sean Ahern, Thu Apr 29 15:41:27 PDT 1999
62 * Made all function definitions ANSI. Removed unused local variables.
63 *
64 * Jeremy Meredith, Fri May 21 10:04:25 PDT 1999
65 * Added a global _uzl structure.
66 *
67 * Brad Whitlock, Mon Apr 8 15:17:17 PST 2002
68 * Changed some headers to allow compilation under windows.
69 *
70 * Thomas R. Treadway, Fri Jan 5 13:46:26 PST 2007
71 * Added backward compatible symbols
72 */
73
74 /* Private SILO functions. */
75 #include "config.h" /* For a possible redefinition of setjmp/longjmp.
76 Also for SDX driver detection. */
77 #include <stdio.h>
78 #include <float.h>
79 #include <math.h>
80 #if HAVE_STDLIB_H
81 #include <stdlib.h> /* For abort(). */
82 #endif
83 #if !defined(_WIN32)
84 #include <sys/file.h> /* For R_OK and F_OK definitions. */
85 #endif
86 #include <errno.h> /* For errno definitions. */
87 #if HAVE_STRING_H
88 #include <string.h> /* For strerror */
89 #endif
90 #if HAVE_STRINGS_H
91 #include <strings.h>
92 #endif
93 #if !defined(_WIN32)
94 #include <sys/errno.h> /* For errno definitions. */
95 #endif
96 #if HAVE_SYS_TYPES_H
97 #include <sys/types.h>
98 #endif
99 #if HAVE_SYS_STAT_H
100 #include <sys/stat.h>
101 #endif
102 #include <ctype.h> /* For isalnum */
103 #if HAVE_SYS_FCNTL_H
104 #include <sys/fcntl.h> /* for O_RDONLY */
105 #endif
106 #if HAVE_FCNTL_H
107 #include <fcntl.h> /* for O_RDONLY */
108 #endif
109 #ifdef _WIN32
110 #include <windows.h> /* for FileInfo funcs */
111 #include <io.h> /* for FileInfo funcs */
112 #endif
113
114 /* DB_MAIN must be defined before including silo_private.h. */
115 #define DB_MAIN
116 #include "silo_private.h"
117 #include "silo_drivers.h"
118
119 /* The Silo_version_* variable is used to guarantee that code can't include
120 * one version of silo.h and link with a different version of libsilo.a. This
121 * variable's name must change with every version of Silo.
122 *
123 * I would ordinary have silo.h be generated by configure so that the
124 * version number will automatically get compiled in. But this isn't good
125 * for development with clearmake, since that would make silo.h be a
126 * view-private file. Thus, any object that depends on silo.h would be
127 * invalid as a wink-in candidate. */
128 int SILO_VERS_TAG = 0;
129
130 /* Specify versions which are backward compatible with the current. */
131 /* No lines of the form 'int Silo_version_Maj_Min_Pat = 0;' below
132 here indicates that this version is not backwards compatible with
133 any previous versions.*/
134 int Silo_version_4_10 = 0;
135 int Silo_version_4_10_0 = 0;
136 int Silo_version_4_10_1 = 0;
137
138 /* Symbols for error handling */
139 PUBLIC int DBDebugAPI = 0; /*file desc for API debug messages */
140 PUBLIC int db_errno = 0; /*last error number */
141 PUBLIC char db_errfunc[64]; /*name of erring function */
142 PUBLIC char *_db_err_list[] =
143 {
144 "No error", /*00 */
145 "Bad file format type", /*01 */
146 "Not implemented", /*02 */
147 "File not found or invalid permissions", /*03 */
148 "<<Reserved>>", /*04 */
149 "Internal error", /*05 */
150 "Not enough memory", /*06 */
151 "Invalid argument", /*07 */
152 "Low-level function call failed", /*08 */
153 "Object not found", /*09 */
154 "Taurus database state error", /*10 */
155 "Too many server connections", /*11 */
156 "Protocol error", /*12 */
157 "Not a directory", /*13 */
158 "Too many open files", /*14 */
159 "Requested filter(s) not found", /*15 */
160 "Too many filters registered", /*16 */
161 "File already exists", /*17 */
162 "Specified file is actually a directory", /*18 */
163 "File lacks read permission", /*19 */
164 "System level error occured", /*20 */
165 "File lacks write permission", /*21 */
166 "Invalid variable name - only alphanumeric and `_'", /* 22 */
167 "Overwrite not allowed. See DBSetAllowOverwrites()", /* 23 */
168 "Checksum failure.", /* 24 */
169 "Compression failure.", /* 25 */
170 "Grab driver enabled.", /* 26 */
171 "File was closed or never opened/created.",/* 27 */
172 "File multiply opened w/>1 not read-only.", /* 28 */
173 "Specified driver cannot open this file.",/* 29 */
174 "Optlist contains options for wrong class.",/* 30 */
175 "Feature not enabled in this build.", /* 31 */
176 "Too many file options sets (missing DBUnregisterFileOptionsSet?).", /* 32 */
177 "\nYou have tried to open or create a Silo file using\n"
178 "the HDF5 driver. However, the installation of Silo\n"
179 "you are using does not have the HDF5 driver enabled.\n"
180 "You need to configure the Silo library using the\n"
181 "--with-hdf5=<INC,LIB> option and re-compile and\n"
182 "re-install Silo. If you do not have an installation\n"
183 "of HDF5 already on your sytem, you will also need\n"
184 "to obtain HDF5 from www.hdfgroup.org and install it.", /* 33 */
185 "Empty objects not permitted. See DBSetAllowEmptyObjects()." /* 34 */
186 "No more tiny array buffer space for custom object." /* 35 */
187 };
188
189 PRIVATE unsigned char _db_fstatus[DB_NFILES]; /*file status */
190 typedef struct reg_status_t {
191 DBfile *f;
192 unsigned int n;
193 int w;
194 } reg_status_t;
195 PRIVATE reg_status_t _db_regstatus[DB_NFILES] = /* DB_NFILES triples of zeros */
196 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
197 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
198 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
199 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
200 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
201 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
202 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
203 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
204 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
205 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
206 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
207 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
208 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
209 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
210 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
211 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
212 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
213 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
214 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
215 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
216 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
217 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
218 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
219 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
220
221 PRIVATE filter_t _db_filter[DB_NFILTERS];
222 const static char *api_dummy = 0;
223
224 /* stat struct definition */
225 typedef struct db_silo_stat_t {
226 #ifndef SIZEOF_OFF64_T
227 #error missing definition for SIZEOF_OFF64_T in silo_private.h
228 #else
229 struct stat s;
230 #endif
231 #ifdef _WIN32
232 DWORD fileindexlo;
233 DWORD fileindexhi;
234 #endif
235 } db_silo_stat_t;
236
237 /* This function is used in API_BEGIN macros and so we forward declare it */
238 PRIVATE int db_isregistered_file(DBfile *dbfile, const db_silo_stat_t *filestate);
239
240 /* Global structures for option lists. */
241 struct _ma _ma;
242 struct _ms _ms;
243 struct _csgm _csgm;
244 struct _pm _pm;
245 struct _qm _qm;
246 struct _um _um;
247 struct _uzl _uzl;
248 struct _phzl _phzl;
249 struct _csgzl _csgzl;
250 struct _mm _mm;
251 struct _cu _cu;
252 struct _dv _dv;
253 struct _mrgt _mrgt;
254
255 SILO_Globals_t SILO_Globals = {
256 DBAll, /* dataReadMask */
257 TRUE, /* allowOverwrites */
258 FALSE, /* allowEmptyObjects */
259 FALSE, /* enableChecksums */
260 FALSE, /* enableFriendlyHDF5Names */
261 FALSE, /* enableGrabDriver */
262 3, /* maxDeprecateWarnings */
263 0, /* compressionParams (null) */
264 2.0, /* compressionMinratio */
265 0, /* compressionErrmode (fallback) */
266 { /* file options sets [32 of them] */
267 0, 0, 0, 0, 0, 0, 0, 0,
268 0, 0, 0, 0, 0, 0, 0, 0,
269 0, 0, 0, 0, 0, 0, 0, 0,
270 0, 0, 0, 0, 0, 0, 0, 0
271 },
272 DB_TOP,/* _db_err_level */
273 0, /* _db_err_func */
274 DB_NONE,/* _db_err_level_drvr */
275 0, /* Jstk */
276 DEFAULT_DRIVER_PRIORITIES
277 };
278
279 INTERNAL int
db_FullyDeprecatedConvention(const char * name)280 db_FullyDeprecatedConvention(const char *name)
281 {
282 if (strcmp(name, "_visit_defvars") == 0)
283 {
284 DEPRECATE_MSG(name,4,6,"DBPutDefvars")
285 }
286 else if (strcmp(name, "_visit_domain_groups") == 0)
287 {
288 DEPRECATE_MSG(name,4,6,"DBPutMrgtree")
289 }
290 else if (strcmp(name, "_disjoint_elements") == 0)
291 {
292 DEPRECATE_MSG(name,4,6,"DBOPT_DISJOINT_MODE option")
293 }
294 else if (strncmp(name, "MultivarToMultimeshMap_",23) == 0)
295 {
296 DEPRECATE_MSG(name,4,6,"DBOPT_MMESH_NAME option for DBPutMultivar")
297 }
298 return 0;
299 }
300
301 /*-------------------------------------------------------------------------
302 * Function: db_perror
303 *
304 * Purpose: Print error message to standard error
305 *
306 * Return: Success: -1
307 *
308 * Failure: never fails
309 *
310 * Programmer: matzke@viper
311 * Thu Nov 3 15:16:42 PST 1994
312 *
313 * Modifications:
314 * Robb Matzke, Tue Dec 20 20:55:14 EST 1994
315 * If s is "" then we use the previous value of s.
316 *-------------------------------------------------------------------------*/
317 INTERNAL int
db_perror(char const * s,int errorno,char const * fname)318 db_perror(char const *s, int errorno, char const *fname)
319 {
320 int call_abort = 0;
321 static char old_s[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
322 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
323 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
324 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
325 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
326 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
327 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
328 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
329
330 /*
331 * Save error number and function name so application
332 * can read them later.
333 */
334 db_errno = errorno;
335 if (fname)
336 strncpy(db_errfunc, fname, sizeof(db_errfunc) - 1);
337 db_errfunc[sizeof(db_errfunc) - 1] = '\0';
338
339 /*
340 * If `s' is an empty string, then use the same string
341 * as last time.
342 */
343 if (s && !*s) {
344 s = old_s;
345 }
346 else if (s) {
347 strncpy(old_s, s, sizeof(old_s));
348 old_s[sizeof(old_s) - 1] = '\0';
349 }
350 else {
351 old_s[0] = '\0';
352 }
353
354 switch (SILO_Globals._db_err_level) {
355 case DB_NONE:
356 if (SILO_Globals.Jstk)
357 longjmp(SILO_Globals.Jstk->jbuf, -1);
358 return -1;
359 case DB_TOP:
360 if (SILO_Globals.Jstk)
361 longjmp(SILO_Globals.Jstk->jbuf, -1);
362 break;
363 case DB_ALL:
364 break;
365 case DB_ABORT:
366 call_abort = 1;
367 break;
368 default:
369 call_abort = 1;
370 break;
371 }
372
373 /*
374 * Issue the error message to standard error or by calling
375 * the indicated error handling routine.
376 */
377 if (SILO_Globals._db_err_func) {
378 int flen = 0, elen = 0, slen = 0;
379 char *better_s;
380
381 elen = strlen(db_strerror(errorno));
382 if (fname && *fname) flen = strlen(fname) + 2;
383 if (s && *s) slen = strlen(s) + 2;
384 better_s = (char *) malloc(elen + flen + slen + 1);
385
386 if (fname && *fname)
387 sprintf(better_s, "%s: ", fname);
388 sprintf(better_s + flen, "%s", db_strerror(errorno));
389 if (s && *s)
390 sprintf(better_s + flen + elen, ": %s", s);
391
392 SILO_Globals._db_err_func((char*)better_s);
393
394 free(better_s);
395 }
396 else {
397 if (fname && *fname)
398 fprintf(stderr, "%s: ", fname);
399 fprintf(stderr, "%s", db_strerror(errorno));
400 if (s && *s)
401 fprintf(stderr, ": %s", s);
402 putc('\n', stderr);
403 }
404
405 if (call_abort) {
406 fflush(stdout);
407 fprintf(stderr, "SILO Aborting...\n");
408 fflush(stderr);
409 abort();
410 }
411
412 return -1;
413 }
414
415 /*-------------------------------------------------------------------------
416 * Function: db_strerror
417 *
418 * Purpose: Return message associated with error number
419 *
420 * Return: Success: ptr to string
421 *
422 * Failure: ptr to "No error"
423 *
424 * Programmer: matzke@viper
425 * Thu Nov 3 15:18:15 PST 1994
426 *
427 * Modifications:
428 * Robb Matzke, Tue Feb 28 11:08:47 EST 1995
429 * If error number is out of range, we make a new error message that
430 * has the error number. That makes this function act like DBErrString
431 * and allows for the use of user-defined error numbers that are
432 * larger than E_NERRORS or less than zero.
433 *-------------------------------------------------------------------------*/
434 INTERNAL char *
db_strerror(int errorno)435 db_strerror(int errorno)
436 {
437 static char s[32];
438
439 if (errorno < 0 || errorno >= NELMTS(_db_err_list)) {
440 sprintf(s, "Error %d", errorno);
441 return s;
442 }
443 return _db_err_list[errorno];
444 }
445
446 /*----------------------------------------------------------------------
447 * Function db_strndup
448 *
449 * Purpose
450 *
451 * Return a duplicate of the given string (with length), where
452 * default mem-mgr was used to allocate the necessary space.
453 *
454 * Modified
455 * Robb Matzke, Thu Nov 10 12:27:10 EST 1994
456 * Added error mechanism
457 *
458 * Eric Brugger, Wed Jul 25 14:57:28 PDT 2001
459 * Renamed the routine.
460 *
461 *---------------------------------------------------------------------*/
462 INTERNAL char *
db_strndup(const char * string,int len)463 db_strndup(const char *string, int len)
464 {
465 char *out = NULL;
466 char *me = "strndup";
467
468 if (string == NULL || len <= 0)
469 return (NULL);
470
471 if (NULL == (out = ALLOC_N(char, len + 1))) {
472 db_perror(NULL, E_NOMEM, me);
473 return NULL;
474 }
475
476 strncpy(out, string, len);
477 out[len] = '\0';
478
479 return (out);
480 }
481
482 /*----------------------------------------------------------------------
483 * Function: DBVariableNameValid
484 *
485 * Purpose Check the validity of a Silo variable name.
486 *
487 * Author: Sean Ahern, Tue Sep 28 10:47:52 PDT 1999
488 *
489 * Returns: 1 if the name is valid
490 * 0 otherwise
491 *
492 * Modified:
493 * Sean Ahern, Fri Oct 1 11:36:34 PDT 1999
494 * Added '/' to the list of allowed characters. We need this for putting
495 * variables in subdirectories.
496 *
497 * Sean Ahern, Tue Oct 5 13:51:07 PDT 1999
498 * Added ':' processing so that we can reference variables in other files.
499 *
500 * Lisa J. Roberts, Thu Dec 16 17:33:26 PST 1999
501 * Removed the abort called if the name validation fails.
502 *
503 * Robb Matzke, 2000-06-02
504 * Omit printing error message if error handling mode is DB_NONE. After
505 * all, some applications check return values and then print their own
506 * error message.
507 *
508 * Hank Childs, Thu Sep 7 14:17:13 PDT 2000
509 * Allow variable names to be relative. [HYPer02087]
510 *
511 * Mark C. Miller, Mon Oct 22 22:08:09 PDT 2007
512 * Made it part of the public API.
513 *
514 *---------------------------------------------------------------------*/
515 PUBLIC int
DBVariableNameValid(const char * s)516 DBVariableNameValid(const char *s)
517 {
518 int len;
519 int i;
520 char *p = NULL;
521
522 /* If there's a ':' in the name, allow anything before the ':'. After the
523 * ':' we have to be more strict. */
524
525 p = (char *)strchr(s,':');
526 if (p == NULL)
527 p = (char *)s;
528 else
529 p++; /* Move one character past the ':'. */
530
531 len = strlen(p);
532
533 /* Every character has to be alphanumeric or the `_' character. */
534 for(i=0;i<len;i++)
535 {
536 int okay = 0;
537
538 if (isalnum(p[i]) || (p[i] == '_') || (p[i] == '/'))
539 {
540 okay = 1;
541 }
542
543 /* Don't need to check for the end of the string because of the
544 * short circuit rule and the null character at end of string. */
545 if ((p[i] == '.') && (p[i+1] == '.') && (p[i+2] == '/'))
546 {
547 okay = 1;
548 i += 2; /* 2 = strlen("../") - 1 (from `for' loop's i++) */
549 }
550
551 if (! okay)
552 {
553 if (DB_NONE!=SILO_Globals._db_err_level)
554 {
555 fprintf(stderr,"\"%s\" is an invalid name. Silo variable\n"
556 "names may contain only alphanumeric characters\n"
557 "or the _ character.\n", s);
558 }
559 return 0;
560 }
561 }
562
563 return 1;
564 }
565 /* kept this to deal with non-const qualified API */
566 INTERNAL int
db_VariableNameValid(char const * s)567 db_VariableNameValid(char const *s)
568 {
569 return DBVariableNameValid(s);
570 }
571
572
573 /*----------------------------------------------------------------------
574 * Routine _DBQQCalcStride
575 *
576 * Purpose
577 *
578 * Calculate the strides given the dimensions and major-order.
579 *
580 * Works for 1D, 2D and 3D variables/meshes, collinear or
581 * non-collinear, materials, too.
582 *
583 *--------------------------------------------------------------------*/
584 INTERNAL void
_DBQQCalcStride(int stride[],int dims[],int ndims,int major_order)585 _DBQQCalcStride(int stride[], int dims[], int ndims, int major_order)
586 {
587 int i;
588
589 /*------------------------------------------------------
590 * Define strides for accessing adjacent elements based
591 * on whether arrays are stored row-major or column-major.
592 *-----------------------------------------------------*/
593
594 if (major_order == DB_ROWMAJOR) {
595 stride[0] = 1;
596
597 for (i = 1; i < ndims; i++) {
598 stride[i] = stride[i - 1] * dims[i - 1];
599 }
600 }
601 else {
602 stride[ndims - 1] = 1;
603
604 for (i = ndims - 2; i >= 0; i--) {
605 stride[i] = stride[i + 1] * dims[i + 1];
606 }
607 }
608 }
609
610 /*----------------------------------------------------------------------
611 * Routine _DBQMSetStride
612 *
613 * Purpose
614 *
615 * Set the stride component for the given quad mesh.
616 *
617 * Works for 1D, 2D and 3D meshes, collinear or non-collinear.
618 *
619 * Modified
620 * Robb Matzke, Wed Jan 11 06:35:33 PST 1995
621 * Changed name from QM_SetStride because it conflicted with MeshTV.
622 *--------------------------------------------------------------------*/
623 INTERNAL void
_DBQMSetStride(DBquadmesh * qmesh)624 _DBQMSetStride(DBquadmesh *qmesh)
625 {
626 _DBQQCalcStride(qmesh->stride, qmesh->dims, qmesh->ndims,
627 qmesh->major_order);
628 }
629
630 /*----------------------------------------------------------------------
631 * Routine SW_GetDatatypeString
632 *
633 * Function
634 *
635 * Return the string representation of the given SWAT data type.
636 *
637 * Modified
638 * Robb Matzke, Thu Nov 10 12:28:44 EST 1994
639 * Added error mechanism
640 *
641 * Robb Matzke, Thu Nov 10 12:30:43 EST 1994
642 * An invalid `type' is now an error.
643 *
644 * Mark C. Miller, Mon Sep 21 15:17:08 PDT 2009
645 * Adding support for long long type.
646 *
647 * Mark C. Miller, Fri Nov 13 15:32:02 PST 2009
648 * Changed name of "long long" type to "longlong" as PDB is
649 * sensitive to spaces in type names.
650 *
651 * Mark C. Miller, Tue Nov 17 22:29:35 PST 2009
652 * Fixed memory error by extending length of alloc'd string to
653 * support "long_long". Changed name of long long data type
654 * to match what PDB proper does.
655 *
656 * Mark C. Miller, Mon Dec 7 09:50:19 PST 2009
657 * Conditionally compile long long support only when its
658 * different from long.
659 *
660 * Mark C. Miller, Mon Jan 11 16:02:16 PST 2010
661 * Made long long support UNconditionally compiled.
662 *---------------------------------------------------------------------*/
663 INTERNAL char *
db_GetDatatypeString(int type)664 db_GetDatatypeString(int type)
665 {
666 char *str = NULL;
667 char *me = "db_GetDatatypeString";
668
669 if (NULL == (str = ALLOC_N(char, 10))) {
670 db_perror(NULL, E_NOMEM, me);
671 return NULL;
672 }
673
674 switch (type) {
675 case DB_INT:
676 strcpy(str, "integer");
677 break;
678 case DB_SHORT:
679 strcpy(str, "short");
680 break;
681 case DB_LONG:
682 strcpy(str, "long");
683 break;
684 case DB_LONG_LONG:
685 strcpy(str, "long_long");
686 break;
687 case DB_FLOAT:
688 strcpy(str, "float");
689 break;
690 case DB_DOUBLE:
691 strcpy(str, "double");
692 break;
693 case DB_CHAR:
694 strcpy(str, "char");
695 break;
696 default:
697 db_perror("type", E_BADARGS, me);
698 FREE(str);
699 return NULL;
700 }
701
702 return (str);
703 }
704
705 /*-------------------------------------------------------------------------
706 * Function: silo_db_close
707 *
708 * Purpose: Free public parts of DBfile. This function is called
709 * after the file has been closed and the private parts
710 * have been freed.
711 *
712 * Return: Success: NULL
713 *
714 * Failure: never fails
715 *
716 * Programmer: matzke@viper
717 * Wed Nov 2 13:55:22 PST 1994
718 *
719 * Modifications:
720 * Mark C. Miller, Tue Feb 3 09:53:53 PST 2009
721 * Changed name to silo_db_close to avoid collision with popular BRLCAD
722 * libs. Added stuff to free GrabId and set Grab related stuff to zero.
723 *-------------------------------------------------------------------------*/
724 INTERNAL DBfile *
silo_db_close(DBfile * dbfile)725 silo_db_close(DBfile *dbfile)
726 {
727 if (dbfile) {
728 db_FreeToc(dbfile);
729 FREE(dbfile->pub.GrabId);
730 dbfile->pub.GrabId = 0;
731 dbfile->pub.Grab = FALSE;
732 FREE(dbfile->pub.name);
733 FREE(dbfile);
734 }
735
736 return NULL;
737 }
738
739 /*-------------------------------------------------------------------------
740 * Function: db_AllocToc
741 *
742 * Purpose: Allocate an empty table of contents for a new file.
743 *
744 * Return: Success: ptr to new DBtoc
745 *
746 * Failure: NULL, db_errno set.
747 *
748 * Modifications:
749 * Eric Brugger, Thu Feb 9 14:43:50 PST 1995
750 * I modified the routine to handle the obj in the table of contents.
751 *
752 * Sean Ahern, Fri Aug 23 16:59:02 PDT 1996
753 * Added multimats.
754 *
755 * Jeremy Meredith, Sept 18 1998
756 * Added multi-block material species.
757 *-------------------------------------------------------------------------*/
758 INTERNAL DBtoc *
db_AllocToc(void)759 db_AllocToc(void)
760 {
761 DBtoc *toc = NULL;
762 char *me = "db_AllocToc";
763
764 if (NULL == (toc = ALLOC(DBtoc))) {
765 db_perror(NULL, E_NOMEM, me);
766 return NULL;
767 }
768
769 toc->curve_names = NULL;
770 toc->ncurve = 0;
771
772 toc->csgmesh_names = NULL;
773 toc->ncsgmesh = 0;
774
775 toc->csgvar_names = NULL;
776 toc->ncsgvar = 0;
777
778 toc->defvars_names = NULL;
779 toc->ndefvars = 0;
780
781 toc->multimesh_names = NULL;
782 toc->nmultimesh = 0;
783
784 toc->multimeshadj_names = NULL;
785 toc->nmultimeshadj = 0;
786
787 toc->multivar_names = NULL;
788 toc->nmultivar = 0;
789
790 toc->multimat_names = NULL;
791 toc->nmultimat = 0;
792
793 toc->multimatspecies_names = NULL;
794 toc->nmultimatspecies = 0;
795
796 toc->qmesh_names = NULL;
797 toc->nqmesh = 0;
798
799 toc->qvar_names = NULL;
800 toc->nqvar = 0;
801
802 toc->ucdmesh_names = NULL;
803 toc->nucdmesh = 0;
804
805 toc->ucdvar_names = NULL;
806 toc->nucdvar = 0;
807
808 toc->ptmesh_names = NULL;
809 toc->nptmesh = 0;
810
811 toc->ptvar_names = NULL;
812 toc->nptvar = 0;
813
814 toc->var_names = NULL;
815 toc->nvar = 0;
816
817 toc->mat_names = NULL;
818 toc->nmat = 0;
819
820 toc->obj_names = NULL;
821 toc->nobj = 0;
822
823 toc->dir_names = NULL;
824 toc->ndir = 0;
825
826 toc->array_names = NULL;
827 toc->narray = 0;
828
829 toc->mrgtree_names = NULL;
830 toc->nmrgtree = 0;
831
832 toc->groupelmap_names = NULL;
833 toc->ngroupelmap = 0;
834
835 toc->mrgvar_names = NULL;
836 toc->nmrgvar = 0;
837
838 return(toc);
839 }
840
841 /*-------------------------------------------------------------------------
842 * Function: db_FreeToc
843 *
844 * Purpose: Free the table of contents associated with a file.
845 *
846 * Return: Success: 0
847 *
848 * Failure: -1
849 *
850 * Modifications:
851 * Robb Matzke, Thu Dec 1 10:22:11 PST 1994
852 * Errors in device drivers might leave the table of
853 * contents in a not-fully-initialized state. Therefore,
854 * this routine always checks for nil pointers before
855 * dereferencing them.
856 *
857 * Robb Matzke, Fri Dec 2 13:13:01 PST 1994
858 * Removed all references to SCORE memory management.
859 *
860 * Eric Brugger, Thu Feb 9 14:43:50 PST 1995
861 * I modified the routine to handle the obj in the table of contents.
862 *
863 * Sean Ahern, Fri Jun 21 10:56:15 PDT 1996
864 * Added handling for multimats.
865 *
866 * Jeremy Meredith, Sept 18 1998
867 * Added multi-block species.
868 *-------------------------------------------------------------------------*/
869 INTERNAL int
db_FreeToc(DBfile * dbfile)870 db_FreeToc(DBfile *dbfile)
871 {
872 int i;
873 DBtoc *toc = NULL;
874 char *me = "db_FreeToc";
875
876 if (!dbfile)
877 return db_perror(NULL, E_NOFILE, me);
878 if (!dbfile->pub.toc)
879 return 0;
880
881 toc = dbfile->pub.toc;
882
883 if (toc->ncurve > 0) {
884 if (toc->curve_names) {
885 for (i = 0; i < toc->ncurve; i++) {
886 FREE(toc->curve_names[i]);
887 }
888 FREE(toc->curve_names);
889 }
890 }
891
892 if (toc->nmultimesh > 0) {
893 if (toc->multimesh_names) {
894 for (i = 0; i < toc->nmultimesh; i++) {
895 FREE(toc->multimesh_names[i]);
896 }
897 FREE(toc->multimesh_names);
898 }
899 }
900
901 if (toc->nmultimeshadj > 0) {
902 if (toc->multimeshadj_names) {
903 for (i = 0; i < toc->nmultimeshadj; i++) {
904 FREE(toc->multimeshadj_names[i]);
905 }
906 FREE(toc->multimeshadj_names);
907 }
908 }
909
910 if (toc->nmultivar > 0) {
911 if (toc->multivar_names) {
912 for (i = 0; i < toc->nmultivar; i++) {
913 FREE(toc->multivar_names[i]);
914 }
915 FREE(toc->multivar_names);
916 }
917 }
918
919 if (toc->nmultimat > 0) {
920 if (toc->multimat_names) {
921 for(i=0; i < toc->nmultimat; i++) {
922 FREE(toc->multimat_names[i]);
923 }
924 FREE(toc->multimat_names);
925 }
926 }
927
928 if (toc->nmultimatspecies > 0) {
929 if (toc->multimatspecies_names) {
930 for(i=0; i < toc->nmultimatspecies; i++) {
931 FREE(toc->multimatspecies_names[i]);
932 }
933 FREE(toc->multimatspecies_names);
934 }
935 }
936
937 if (toc->ncsgmesh > 0) {
938 if (toc->csgmesh_names) {
939 for (i = 0; i < toc->ncsgmesh; i++) {
940 FREE(toc->csgmesh_names[i]);
941 }
942 FREE(toc->csgmesh_names);
943 }
944 }
945 if (toc->ncsgvar > 0) {
946 if (toc->csgvar_names) {
947 for (i = 0; i < toc->ncsgvar; i++) {
948 FREE(toc->csgvar_names[i]);
949 }
950 FREE(toc->csgvar_names);
951 }
952 }
953
954 if (toc->ndefvars > 0) {
955 if (toc->defvars_names) {
956 for (i = 0; i < toc->ndefvars; i++) {
957 FREE(toc->defvars_names[i]);
958 }
959 FREE(toc->defvars_names);
960 }
961 }
962
963 if (toc->nqmesh > 0) {
964 if (toc->qmesh_names) {
965 for (i = 0; i < toc->nqmesh; i++) {
966 FREE(toc->qmesh_names[i]);
967 }
968 FREE(toc->qmesh_names);
969 }
970 }
971
972 if (toc->nqvar > 0) {
973 if (toc->qvar_names) {
974 for (i = 0; i < toc->nqvar; i++) {
975 FREE(toc->qvar_names[i]);
976 }
977 FREE(toc->qvar_names);
978 }
979 }
980
981 if (toc->nptmesh > 0) {
982 if (toc->ptmesh_names) {
983 for (i = 0; i < toc->nptmesh; i++) {
984 FREE(toc->ptmesh_names[i]);
985 }
986 FREE(toc->ptmesh_names);
987 }
988 }
989
990 if (toc->nptvar > 0) {
991 if (toc->ptvar_names) {
992 for (i = 0; i < toc->nptvar; i++) {
993 FREE(toc->ptvar_names[i]);
994 }
995 FREE(toc->ptvar_names);
996 }
997 }
998
999 if (toc->nmat > 0) {
1000 if (toc->mat_names) {
1001 for (i = 0; i < toc->nmat; i++) {
1002 FREE(toc->mat_names[i]);
1003 }
1004 FREE(toc->mat_names);
1005 }
1006 }
1007
1008 if (toc->nucdmesh > 0) {
1009 if (toc->ucdmesh_names) {
1010 for (i = 0; i < toc->nucdmesh; i++) {
1011 FREE(toc->ucdmesh_names[i]);
1012 }
1013 FREE(toc->ucdmesh_names);
1014 }
1015 }
1016
1017 if (toc->nucdvar > 0) {
1018 if (toc->ucdvar_names) {
1019 for (i = 0; i < toc->nucdvar; i++) {
1020 FREE(toc->ucdvar_names[i]);
1021 }
1022 FREE(toc->ucdvar_names);
1023 }
1024 }
1025
1026 if (toc->nvar > 0) {
1027 if (toc->var_names) {
1028 for (i = 0; i < toc->nvar; i++) {
1029 FREE(toc->var_names[i]);
1030 }
1031 FREE(toc->var_names);
1032 }
1033 }
1034
1035 if (toc->nobj > 0) {
1036 if (toc->obj_names) {
1037 for (i = 0; i < toc->nobj; i++) {
1038 FREE(toc->obj_names[i]);
1039 }
1040 FREE(toc->obj_names);
1041 }
1042 }
1043
1044 if (toc->ndir > 0) {
1045 if (toc->dir_names) {
1046 for (i = 0; i < toc->ndir; i++) {
1047 FREE(toc->dir_names[i]);
1048 }
1049 FREE(toc->dir_names);
1050 }
1051 }
1052
1053 if (toc->narray > 0) {
1054 if (toc->array_names) {
1055 for (i = 0; i < toc->narray; i++) {
1056 FREE(toc->array_names[i]);
1057 }
1058 FREE(toc->array_names);
1059 }
1060 }
1061
1062 if (toc->nmrgtree > 0) {
1063 if (toc->mrgtree_names) {
1064 for (i = 0; i < toc->nmrgtree; i++) {
1065 FREE(toc->mrgtree_names[i]);
1066 }
1067 FREE(toc->mrgtree_names);
1068 }
1069 }
1070
1071 if (toc->ngroupelmap > 0) {
1072 if (toc->groupelmap_names) {
1073 for (i = 0; i < toc->ngroupelmap; i++) {
1074 FREE(toc->groupelmap_names[i]);
1075 }
1076 FREE(toc->groupelmap_names);
1077 }
1078 }
1079
1080 if (toc->nmrgvar > 0) {
1081 if (toc->mrgvar_names) {
1082 for (i = 0; i < toc->nmrgvar; i++) {
1083 FREE(toc->mrgvar_names[i]);
1084 }
1085 FREE(toc->mrgvar_names);
1086 }
1087 }
1088
1089 FREE(dbfile->pub.toc);
1090 return 0;
1091 }
1092
1093 /*----------------------------------------------------------------------
1094 * Routine silo_GetMachDataSize
1095 *
1096 * Purpose
1097 *
1098 * Return the byte length of the given data type ON THE CURRENT
1099 * MACHINE.
1100 *
1101 * Notes
1102 *
1103 * Modified
1104 * Robb Matzke, Thu Nov 10 12:33:44 EST 1994
1105 * Added error mechanism. An invalid `datatype' is an error.
1106 *
1107 * Mark C. Miller, Mon Sep 21 15:17:08 PDT 2009
1108 * Adding support for long long type.
1109 *
1110 * Mark C. Miller, Mon Dec 7 09:50:19 PST 2009
1111 * Conditionally compile long long support only when its
1112 * different from long.
1113 *
1114 * Mark C. Miller, Mon Jan 11 16:02:16 PST 2010
1115 * Made long long support UNconditionally compiled.
1116 *--------------------------------------------------------------------*/
1117 INTERNAL int
db_GetMachDataSize(int datatype)1118 db_GetMachDataSize(int datatype)
1119 {
1120 int size;
1121 char *me = "db_GetMachDataSize";
1122
1123 switch (datatype)
1124 {
1125 case DB_CHAR: size = sizeof(char); break;
1126 case DB_SHORT: size = sizeof(short); break;
1127 case DB_INT: size = sizeof(int); break;
1128 case DB_LONG: size = sizeof(long); break;
1129 case DB_LONG_LONG: size = sizeof(long long); break;
1130 case DB_FLOAT: size = sizeof(float); break;
1131 case DB_DOUBLE: size = sizeof(double); break;
1132 default: return db_perror("datatype", E_BADARGS, me);
1133 }
1134 return (size);
1135 }
1136
1137 /*----------------------------------------------------------------------
1138 * Routine db_GetDatatypeID
1139 *
1140 * Purpose
1141 *
1142 * Return the SILO integer definition for the provided ascii datatype
1143 * description. That is, convert "float" to SWAT_FLOAT (i.e., 19).
1144 *
1145 * Notes
1146 *
1147 * Modified
1148 * Robb Matzke, Thu Nov 10 12:35:24 EST 1994
1149 * Added error mechanism. An invalid `dataname' is an error.
1150 *
1151 * Mark C. Miller, Mon Sep 21 15:17:08 PDT 2009
1152 * Adding support for long long type.
1153 *
1154 * Mark C. Miller, Fri Nov 13 15:32:02 PST 2009
1155 * Changed name of "long long" type to "longlong" as PDB is
1156 * sensitive to spaces in type names.
1157 *
1158 * Mark C. Miller, Tue Nov 17 22:30:30 PST 2009
1159 * Changed name of long long datatype to match PDB proper.
1160 *
1161 * Mark C. Miller, Mon Dec 7 09:50:19 PST 2009
1162 * Conditionally compile long long support only when its
1163 * different from long.
1164 *
1165 * Mark C. Miller, Mon Jan 11 16:02:16 PST 2010
1166 * Made long long support UNconditionally compiled.
1167 *--------------------------------------------------------------------*/
1168 INTERNAL int
db_GetDatatypeID(char const * const dataname)1169 db_GetDatatypeID(char const * const dataname)
1170 {
1171 int size;
1172 char *me = "db_GetDatatypeID";
1173
1174 if (STR_BEGINSWITH(dataname, "integer"))
1175 size = DB_INT;
1176 else if (STR_BEGINSWITH(dataname, "short"))
1177 size = DB_SHORT;
1178 else if (STR_BEGINSWITH(dataname, "long_long"))
1179 size = DB_LONG_LONG;
1180 else if (STR_BEGINSWITH(dataname, "long"))
1181 size = DB_LONG;
1182 else if (STR_BEGINSWITH(dataname, "float"))
1183 size = DB_FLOAT;
1184 else if (STR_BEGINSWITH(dataname, "double"))
1185 size = DB_DOUBLE;
1186 else if (STR_BEGINSWITH(dataname, "char"))
1187 size = DB_CHAR;
1188 else
1189 return db_perror("dataname", E_BADARGS, me);
1190
1191 return (size);
1192 }
1193
1194 /*----------------------------------------------------------------------
1195 * Routine DBGetObjtypeTag
1196 *
1197 * Purpose
1198 *
1199 * Return the tag (integer ID) for the given object type.
1200 *
1201 * Programmer
1202 *
1203 * Jeffery W. Long, NSSD-B
1204 *
1205 * Parameters
1206 *
1207 * type_name {In} {Name of object type to inquire about}
1208 *
1209 * Notes
1210 *
1211 * This function and it's counterpart, DBGetObjtypeName(), must
1212 * stay in sync. Changes to this function must be mirrored in
1213 * the other.
1214 *
1215 * Modifications
1216 * Al Leibee,Mon Aug 1 16:16:00 PDT 1994
1217 * Added material species.
1218 *
1219 * Robb Matzke, Tue Oct 25 08:57:56 PDT 1994
1220 * Added compound array.
1221 *
1222 * Robb Matzke, Wed Nov 9 14:04:23 EST 1994
1223 * Added error mechanism.
1224 *
1225 * Robb Matzke, Fri Dec 2 09:58:51 PST 1994
1226 * Added `zonelist' and `facelist' and `edgelist'
1227 *
1228 * Eric Brugger, Tue Feb 7 11:05:39 PST 1995
1229 * I modified the routine to return DB_USERDEF if the type_name
1230 * is not known.
1231 *
1232 * Katherine Price, Thu May 25 10:00:50 PDT 1995
1233 * Added multi-block material.
1234 *
1235 * Jeremy Meredith, Sept 18 1998
1236 * Added multi-block material species.
1237 *--------------------------------------------------------------------*/
1238 PUBLIC int
DBGetObjtypeTag(char const * type_name)1239 DBGetObjtypeTag(char const *type_name)
1240 {
1241 int tag;
1242 char *me = "DBGetObjtypeTag";
1243
1244 if (!type_name || !*type_name)
1245 return db_perror("type name", E_BADARGS, me);
1246
1247 if (type_name[0] == 'D' && type_name[1] == 'B')
1248 type_name += 2;
1249
1250 if (STR_EQUAL(type_name, "multiblockmesh") ||
1251 STR_EQUAL(type_name, "multimesh"))
1252 tag = DB_MULTIMESH;
1253
1254 else if (STR_EQUAL(type_name, "multimeshadj"))
1255 tag = DB_MULTIMESHADJ;
1256
1257 else if (STR_EQUAL(type_name, "multiblockvar") ||
1258 STR_EQUAL(type_name, "multivar"))
1259 tag = DB_MULTIVAR;
1260
1261 else if (STR_EQUAL(type_name, "multiblockmat") ||
1262 STR_EQUAL(type_name, "multimat"))
1263 tag = DB_MULTIMAT;
1264
1265 else if (STR_EQUAL(type_name, "multimatspecies"))
1266 tag = DB_MULTIMATSPECIES;
1267
1268 else if (STR_EQUAL(type_name, "quadmesh-rect"))
1269 tag = DB_QUAD_RECT;
1270
1271 else if (STR_EQUAL(type_name, "quadmesh-curv"))
1272 tag = DB_QUAD_CURV;
1273
1274 else if (STR_EQUAL(type_name, "csgmesh"))
1275 tag = DB_CSGMESH;
1276
1277 else if (STR_EQUAL(type_name, "csgvar"))
1278 tag = DB_CSGVAR;
1279
1280 else if (STR_EQUAL(type_name, "defvars"))
1281 tag = DB_DEFVARS;
1282
1283 else if (STR_EQUAL(type_name, "quadmesh"))
1284 tag = DB_QUADMESH;
1285
1286 else if (STR_EQUAL(type_name, "quadvar"))
1287 tag = DB_QUADVAR;
1288
1289 else if (STR_EQUAL(type_name, "ucdmesh"))
1290 tag = DB_UCDMESH;
1291
1292 else if (STR_EQUAL(type_name, "ucdvar"))
1293 tag = DB_UCDVAR;
1294
1295 else if (STR_EQUAL(type_name, "pointmesh"))
1296 tag = DB_POINTMESH;
1297
1298 else if (STR_EQUAL(type_name, "pointvar"))
1299 tag = DB_POINTVAR;
1300
1301 else if (STR_EQUAL(type_name, "curve"))
1302 tag = DB_CURVE;
1303
1304 else if (STR_EQUAL(type_name, "material"))
1305 tag = DB_MATERIAL;
1306
1307 else if (STR_EQUAL(type_name, "matspecies"))
1308 tag = DB_MATSPECIES;
1309
1310 else if (STR_EQUAL(type_name, "compoundarray"))
1311 tag = DB_ARRAY;
1312
1313 else if (STR_EQUAL(type_name, "facelist"))
1314 tag = DB_FACELIST;
1315
1316 else if (STR_EQUAL(type_name, "zonelist"))
1317 tag = DB_ZONELIST;
1318
1319 else if (STR_EQUAL(type_name, "polyhedral-zonelist"))
1320 tag = DB_PHZONELIST;
1321
1322 else if (STR_EQUAL(type_name, "csgzonelist"))
1323 tag = DB_CSGZONELIST;
1324
1325 else if (STR_EQUAL(type_name, "edgelist"))
1326 tag = DB_EDGELIST;
1327
1328 else if (STR_EQUAL(type_name, "mrgtree"))
1329 tag = DB_MRGTREE;
1330
1331 else if (STR_EQUAL(type_name, "groupelmap"))
1332 tag = DB_GROUPELMAP;
1333
1334 else if (STR_EQUAL(type_name, "mrgvar"))
1335 tag = DB_MRGVAR;
1336
1337 else
1338 tag = DB_USERDEF;
1339
1340 return (tag);
1341 }
1342
1343 /*----------------------------------------------------------------------
1344 * Routine DBGetObjtypeName
1345 *
1346 * Purpose
1347 *
1348 * Return the name associated with an object of the given type.
1349 *
1350 * Programmer
1351 *
1352 * Jeffery W. Long, NSSD-B
1353 *
1354 * Parameters
1355 *
1356 * type {In} {Type of object to inquire about}
1357 *
1358 * Notes
1359 *
1360 * The calling routine should NOT attempt to free the memory
1361 * associated with the returned string.
1362 *
1363 * Modifications
1364 * Al Leibee, Tue Jul 26 08:44:01 PDT 1994
1365 * Replaced composition by matspecies.
1366 *
1367 * Robb Matzke, Fri Oct 21 15:23:18 EST 1994
1368 * Added DB_ARRAY for Compound Array type.
1369 *
1370 * Eric Brugger, Tue Feb 7 11:05:39 PST 1995
1371 * I modified the routine to return "unknown" if the type is
1372 * DB_USERDEF.
1373 *
1374 * Katherine Price, Thu May 25 10:00:50 PDT 1995
1375 * Added DB_MULTIMAT for Multi-Block Material type.
1376 *
1377 * Jeremy Meredith, Sept 18 1998
1378 * Added DB_MULTIMATSPECIES for Multi-block Species.
1379 *--------------------------------------------------------------------*/
1380 INTERNAL char *
DBGetObjtypeName(int type)1381 DBGetObjtypeName(int type)
1382 {
1383 char *me = "DBGetObjtypeName";
1384
1385 switch (type) {
1386 case DB_CSGMESH:
1387 return ("csgmesh");
1388 case DB_CSGVAR:
1389 return ("csgvar");
1390 case DB_CSGZONELIST:
1391 return ("csgzonelist");
1392 case DB_DEFVARS:
1393 return ("defvars");
1394 case DB_QUADMESH:
1395 return ("quadmesh");
1396 case DB_QUAD_RECT:
1397 return ("quadmesh-rect");
1398 case DB_QUAD_CURV:
1399 return ("quadmesh-curv");
1400 case DB_QUADVAR:
1401 return ("quadvar");
1402 case DB_UCDMESH:
1403 return ("ucdmesh");
1404 case DB_UCDVAR:
1405 return ("ucdvar");
1406 case DB_POINTMESH:
1407 return ("pointmesh");
1408 case DB_POINTVAR:
1409 return ("pointvar");
1410 case DB_MULTIMESH:
1411 return ("multiblockmesh");
1412 case DB_MULTIMESHADJ:
1413 return ("multimeshadj");
1414 case DB_MULTIVAR:
1415 return ("multiblockvar");
1416 case DB_MULTIMAT:
1417 return ("multiblockmat");
1418 case DB_MULTIMATSPECIES:
1419 return ("multimatspecies");
1420 case DB_MATERIAL:
1421 return ("material");
1422 case DB_MATSPECIES:
1423 return ("matspecies");
1424 case DB_FACELIST:
1425 return ("facelist");
1426 case DB_ZONELIST:
1427 return ("zonelist");
1428 case DB_PHZONELIST:
1429 return ("polyhedral-zonelist");
1430 case DB_EDGELIST:
1431 return ("edgelist");
1432 case DB_CURVE:
1433 return ("curve");
1434 case DB_ARRAY:
1435 return ("compoundarray");
1436 case DB_MRGTREE:
1437 return ("mrgtree");
1438 case DB_GROUPELMAP:
1439 return ("groupelmap");
1440 case DB_MRGVAR:
1441 return ("mrgvar");
1442 case DB_USERDEF:
1443 return ("unknown");
1444 }
1445
1446 db_perror("type-number", E_BADARGS, me);
1447 return ("unknown");
1448 }
1449
1450 /*-------------------------------------------------------------------------
1451 * Function: db_ListDir2
1452 *
1453 * Purpose: Lists the contents of the given directories based on the
1454 * listing options set in the `args' array. Directory path
1455 * arguments can be either absolute or relative. The standard
1456 * Unix directory syntax is understood: `..' is shorthand for
1457 * the parent of te current directory and `.' is shorthand
1458 * for the current directory.
1459 *
1460 * Return: Success: 0
1461 *
1462 * Failure: -1
1463 *
1464 * Arguments:
1465 * args Argument array
1466 * nargs Number of arguments
1467 * build_list Sentinel: 1:build list instead of printing
1468 * list List of varnames matching request
1469 * nlist Returned length of list
1470 *
1471 * Programmer: robb@cloud
1472 * Tue Nov 15 15:07:26 EST 1994
1473 *
1474 * Modifications:
1475 * Eric Brugger, Thu Feb 9 14:43:50 PST 1995
1476 * I modified the routine to handle the obj in the table of contents.
1477 *
1478 * Jeremy Meredith, Sept 18 1998
1479 * Added multimatspecies to the toc
1480 *-------------------------------------------------------------------------*/
1481 INTERNAL int
db_ListDir2(DBfile * _dbfile,char * args[],int nargs,int build_list,char * list[],int * nlist)1482 db_ListDir2(DBfile *_dbfile, char *args[], int nargs, int build_list,
1483 char *list[], int *nlist)
1484 {
1485 int i, k, npaths, nopts;
1486 int ls_mesh, ls_var, ls_dir;
1487 int ls_multimesh, ls_multivar, ls_multimat, ls_curve, ls_mat;
1488 int ls_matspecies, ls_multimatspecies, ls_low, ls_array;
1489 char opts[256], cwd[256], orig_dir[256], *paths[64];
1490 DBtoc *toc = NULL;
1491 int left_margin, col_margin, line_width;
1492 char *me = "db_ListDir2";
1493
1494 /*----------------------------------------
1495 * Parse input options and pathnames.
1496 *----------------------------------------*/
1497
1498 if (!list || !nlist) return -1;
1499
1500 npaths = 0;
1501 nopts = 0;
1502
1503 for (i = 0; i < nargs; i++) {
1504
1505 switch (args[i][0]) {
1506 case '-':
1507
1508 strcpy(&opts[nopts], &args[i][1]);
1509 nopts += strlen(args[i]) - 1;
1510 break;
1511
1512 default:
1513
1514 paths[npaths++] = args[i];
1515 break;
1516 }
1517 }
1518
1519 /*----------------------------------------
1520 * Set listing options based on input.
1521 *----------------------------------------*/
1522 if (nopts > 0) {
1523 ls_mesh = ls_var = ls_dir = FALSE;
1524 ls_curve = ls_mat = ls_matspecies = ls_low = ls_array = FALSE;
1525 ls_multimat = ls_multimatspecies = FALSE;
1526 }
1527 else {
1528 /* Default values */
1529 ls_mesh = ls_var = ls_dir = ls_multimesh = ls_multivar = TRUE;
1530 ls_curve = ls_mat = ls_matspecies = ls_low = ls_array = FALSE;
1531 ls_multimat = ls_multimatspecies = FALSE;
1532 }
1533
1534 for (i = 0; i < nopts; i++) {
1535
1536 switch (opts[i]) {
1537 case 'a':
1538 ls_curve = TRUE;
1539 ls_dir = TRUE;
1540 ls_low = TRUE;
1541 ls_mat = TRUE;
1542 ls_matspecies = TRUE;
1543 ls_mesh = TRUE;
1544 ls_var = TRUE;
1545 ls_multimesh = TRUE;
1546 ls_multivar = TRUE;
1547 ls_multimat = TRUE;
1548 ls_multimatspecies = TRUE;
1549 ls_array = TRUE;
1550 break;
1551 case 'A':
1552 ls_array = TRUE;
1553 break;
1554 case 'c':
1555 ls_curve = TRUE;
1556 break;
1557 case 'd':
1558 ls_dir = TRUE;
1559 break;
1560 case 'm':
1561 ls_mesh = TRUE;
1562 break;
1563 case 'M':
1564 ls_multimesh = TRUE;
1565 ls_multivar = TRUE;
1566 ls_multimat = TRUE;
1567 ls_multimatspecies = TRUE;
1568 break;
1569 case 'r':
1570 ls_mat = TRUE;
1571 break;
1572 case 's':
1573 ls_matspecies = TRUE;
1574 break;
1575 case 'v':
1576 ls_var = TRUE;
1577 break;
1578 case 'x':
1579 ls_low = TRUE;
1580 break;
1581 default:
1582 return db_perror("invalid list option", E_BADARGS, me);
1583 }
1584 }
1585
1586 /*----------------------------------------
1587 * List all requested objects/dirs
1588 *----------------------------------------*/
1589
1590 DBGetDir(_dbfile, orig_dir);
1591
1592 if (npaths <= 0) {
1593 npaths = 1;
1594 paths[0] = ".";
1595 }
1596
1597 left_margin = 10;
1598 col_margin = 5;
1599 line_width = 80;
1600
1601 if (nlist)
1602 *nlist = 0;
1603
1604 for (k = 0; k < npaths; k++) {
1605
1606 DBGetDir(_dbfile, cwd);
1607
1608 /* Change to requested directory, if necessary */
1609 if (!STR_EQUAL(".", paths[k]) &&
1610 !STR_EQUAL(cwd, paths[k]))
1611 DBSetDir(_dbfile, paths[k]);
1612
1613 toc = DBGetToc(_dbfile);
1614 if (!toc)
1615 return db_perror("unable to get toc", E_INTERNAL, me);
1616
1617 if (ls_curve && toc->ncurve > 0) {
1618 if (build_list) {
1619 for (i = 0; i < toc->ncurve; i++) {
1620 list[*nlist] = ALLOC_N(char,
1621 strlen (toc->curve_names[i]) + 1);
1622
1623 strcpy(list[(*nlist)++], toc->curve_names[i]);
1624 }
1625 }
1626 else {
1627 printf("%7d curves:\n", toc->ncurve);
1628 _DBstrprint(stdout, toc->curve_names, toc->ncurve,
1629 'c', left_margin, col_margin, line_width);
1630 printf("\n");
1631 }
1632 }
1633
1634 if (ls_low && toc->nvar > 0) {
1635 if (build_list) {
1636 for (i = 0; i < toc->nvar; i++) {
1637 list[*nlist] = ALLOC_N(char,
1638 strlen (toc->var_names[i]) + 1);
1639
1640 strcpy(list[(*nlist)++], toc->var_names[i]);
1641 }
1642 }
1643 else {
1644 printf("%7d miscellaneous vars:\n", toc->nvar);
1645 _DBstrprint(stdout, toc->var_names, toc->nvar,
1646 'c', left_margin, col_margin, line_width);
1647 printf("\n");
1648 }
1649 }
1650
1651 if (ls_mat && toc->nmat > 0) {
1652 if (build_list) {
1653 for (i = 0; i < toc->nmat; i++) {
1654 list[*nlist] = ALLOC_N(char,
1655 strlen (toc->mat_names[i]) + 1);
1656
1657 strcpy(list[(*nlist)++], toc->mat_names[i]);
1658 }
1659 }
1660 else {
1661 printf("%7d material vars:\n", toc->nmat);
1662 _DBstrprint(stdout, toc->mat_names, toc->nmat,
1663 'c', left_margin, col_margin, line_width);
1664 printf("\n");
1665 }
1666 }
1667
1668 if (ls_matspecies && toc->nmatspecies > 0) {
1669 if (build_list) {
1670 for (i = 0; i < toc->nmatspecies; i++) {
1671 list[*nlist] = ALLOC_N(char,
1672 strlen (toc->matspecies_names[i]) + 1);
1673
1674 strcpy(list[(*nlist)++], toc->matspecies_names[i]);
1675 }
1676 }
1677 else {
1678 printf("%7d material species vars:\n", toc->nmatspecies);
1679 _DBstrprint(stdout, toc->matspecies_names,
1680 toc->nmatspecies,
1681 'c', left_margin, col_margin, line_width);
1682 printf("\n");
1683 }
1684 }
1685
1686 if (ls_array && toc->narray > 0) {
1687 if (build_list) {
1688 for (i = 0; i < toc->narray; i++) {
1689 list[*nlist] = ALLOC_N(char,
1690 strlen (toc->array_names[i]) + 1);
1691
1692 strcpy(list[(*nlist)++], toc->array_names[i]);
1693 }
1694 }
1695 else {
1696 printf("%7d compound arrays:\n", toc->narray);
1697 _DBstrprint(stdout, toc->array_names, toc->narray,
1698 'c', left_margin, col_margin, line_width);
1699 printf("\n");
1700 }
1701 }
1702
1703 if (ls_dir && toc->ndir > 0) {
1704 if (build_list) {
1705 for (i = 0; i < toc->ndir; i++) {
1706 list[*nlist] = ALLOC_N(char,
1707 strlen (toc->dir_names[i]) + 1);
1708
1709 strcpy(list[(*nlist)++], toc->dir_names[i]);
1710 }
1711 }
1712 else {
1713 printf("%7d directories:\n", toc->ndir);
1714 _DBstrprint(stdout, toc->dir_names, toc->ndir,
1715 'c', left_margin, col_margin, line_width);
1716 printf("\n");
1717 }
1718 }
1719
1720 if (ls_multimesh && toc->nmultimesh > 0) {
1721 if (build_list) {
1722 for (i = 0; i < toc->nmultimesh; i++) {
1723 list[*nlist] = ALLOC_N(char,
1724 strlen (toc->multimesh_names[i]) + 1);
1725
1726 strcpy(list[(*nlist)++], toc->multimesh_names[i]);
1727 }
1728 }
1729 else {
1730 printf("%7d multi-block meshes:\n", toc->nmultimesh);
1731 _DBstrprint(stdout, toc->multimesh_names, toc->nmultimesh,
1732 'c', left_margin, col_margin, line_width);
1733 printf("\n");
1734 }
1735 }
1736
1737 if (ls_mesh && toc->nqmesh > 0) {
1738 if (build_list) {
1739 for (i = 0; i < toc->nqmesh; i++) {
1740 list[*nlist] = ALLOC_N(char,
1741 strlen (toc->qmesh_names[i]) + 1);
1742
1743 strcpy(list[(*nlist)++], toc->qmesh_names[i]);
1744 }
1745 }
1746 else {
1747 printf("%7d quad meshes:\n", toc->nqmesh);
1748 _DBstrprint(stdout, toc->qmesh_names, toc->nqmesh,
1749 'c', left_margin, col_margin, line_width);
1750 printf("\n");
1751 }
1752 }
1753 if (ls_mesh && toc->nucdmesh > 0) {
1754 if (build_list) {
1755 for (i = 0; i < toc->nucdmesh; i++) {
1756 list[*nlist] = ALLOC_N(char,
1757 strlen (toc->ucdmesh_names[i]) + 1);
1758
1759 strcpy(list[(*nlist)++], toc->ucdmesh_names[i]);
1760 }
1761 }
1762 else {
1763 printf("%7d UCD meshes:\n", toc->nucdmesh);
1764 _DBstrprint(stdout, toc->ucdmesh_names, toc->nucdmesh,
1765 'c', left_margin, col_margin, line_width);
1766 printf("\n");
1767 }
1768 }
1769 if (ls_mesh && toc->nptmesh > 0) {
1770 if (build_list) {
1771 for (i = 0; i < toc->nptmesh; i++) {
1772 list[*nlist] = ALLOC_N(char,
1773 strlen (toc->ptmesh_names[i]) + 1);
1774
1775 strcpy(list[(*nlist)++], toc->ptmesh_names[i]);
1776 }
1777 }
1778 else {
1779 printf("%7d Point meshes:\n", toc->nptmesh);
1780 _DBstrprint(stdout, toc->ptmesh_names, toc->nptmesh,
1781 'c', left_margin, col_margin, line_width);
1782 printf("\n");
1783 }
1784 }
1785
1786 if (ls_multivar && toc->nmultivar > 0) {
1787 if (build_list) {
1788 for (i = 0; i < toc->nmultivar; i++) {
1789 list[*nlist] = ALLOC_N(char,
1790 strlen (toc->multivar_names[i]) + 1);
1791
1792 strcpy(list[(*nlist)++], toc->multivar_names[i]);
1793 }
1794 }
1795 else {
1796 printf("%7d multi-block vars:\n", toc->nmultivar);
1797 _DBstrprint(stdout, toc->multivar_names, toc->nmultivar,
1798 'c', left_margin, col_margin, line_width);
1799 printf("\n");
1800 }
1801 }
1802
1803 if (ls_multimat && toc->nmultimat > 0) {
1804 if (build_list) {
1805 for (i = 0; i < toc->nmultimat; i++) {
1806 list[*nlist] = ALLOC_N (char,
1807 strlen (toc->multimat_names[i]) + 1);
1808 strcpy (list[(*nlist)++], toc->multimat_names[i]);
1809 }
1810 }
1811 else {
1812 printf("%7d multi-block materials:\n", toc->nmultimat);
1813 _DBstrprint (stdout, toc->multimat_names, toc->nmultimat,
1814 'c', left_margin, col_margin, line_width);
1815 printf("\n");
1816 }
1817 }
1818
1819 if (ls_multimatspecies && toc->nmultimatspecies > 0) {
1820 if (build_list) {
1821 for (i = 0; i < toc->nmultimatspecies; i++) {
1822 list[*nlist] = ALLOC_N (char,
1823 strlen (toc->multimatspecies_names[i]) + 1);
1824 strcpy (list[(*nlist)++], toc->multimatspecies_names[i]);
1825 }
1826 }
1827 else {
1828 printf("%7d multi-block material species:\n", toc->nmultimatspecies);
1829 _DBstrprint (stdout, toc->multimatspecies_names,
1830 toc->nmultimatspecies,
1831 'c', left_margin, col_margin, line_width);
1832 printf("\n");
1833 }
1834 }
1835
1836 if (ls_var && toc->nqvar > 0) {
1837 if (build_list) {
1838 for (i = 0; i < toc->nqvar; i++) {
1839 list[*nlist] = ALLOC_N(char,
1840 strlen (toc->qvar_names[i]) + 1);
1841
1842 strcpy(list[(*nlist)++], toc->qvar_names[i]);
1843 }
1844 }
1845 else {
1846 printf("%7d quad vars:\n", toc->nqvar);
1847 _DBstrprint(stdout, toc->qvar_names, toc->nqvar,
1848 'c', left_margin, col_margin, line_width);
1849 printf("\n");
1850 }
1851 }
1852 if (ls_var && toc->nucdvar > 0) {
1853 if (build_list) {
1854 for (i = 0; i < toc->nucdvar; i++) {
1855 list[*nlist] = ALLOC_N(char,
1856 strlen (toc->ucdvar_names[i]) + 1);
1857
1858 strcpy(list[(*nlist)++], toc->ucdvar_names[i]);
1859 }
1860 }
1861 else {
1862 printf("%7d UCD vars:\n", toc->nucdvar);
1863 _DBstrprint(stdout, toc->ucdvar_names, toc->nucdvar,
1864 'c', left_margin, col_margin, line_width);
1865 printf("\n");
1866 }
1867 }
1868 if (ls_var && toc->nptvar > 0) {
1869 if (build_list) {
1870 for (i = 0; i < toc->nptvar; i++) {
1871 list[*nlist] = ALLOC_N(char,
1872 strlen (toc->ptvar_names[i]) + 1);
1873
1874 strcpy(list[(*nlist)++], toc->ptvar_names[i]);
1875 }
1876 }
1877 else {
1878 printf("%7d Point vars:\n", toc->nptvar);
1879 _DBstrprint(stdout, toc->ptvar_names, toc->nptvar,
1880 'c', left_margin, col_margin, line_width);
1881 printf("\n");
1882 }
1883 }
1884 if (ls_var && toc->nobj > 0) {
1885 if (build_list) {
1886 for (i = 0; i < toc->nobj; i++) {
1887 list[*nlist] = ALLOC_N(char,
1888 strlen (toc->obj_names[i]) + 1);
1889
1890 strcpy(list[(*nlist)++], toc->obj_names[i]);
1891 }
1892 }
1893 else {
1894 printf("%7d miscellaneous objects:\n", toc->nobj);
1895 _DBstrprint(stdout, toc->obj_names, toc->nobj,
1896 'c', left_margin, col_margin, line_width);
1897 printf("\n");
1898 }
1899 }
1900
1901 /*
1902 * Return to original directory, since next path may
1903 * be relative to it.
1904 */
1905 DBSetDir(_dbfile, orig_dir);
1906
1907 }
1908
1909 return 0;
1910 }
1911
1912 /*-------------------------------------------------------------------------
1913 * Function: context_switch
1914 *
1915 * Purpose: Many of the DB...() functions take an object name as a
1916 * parameter. The old protocol didn't specify whether the
1917 * name could include a path, so some drivers allow one and
1918 * other don't. To fix the problem, each of the API functions
1919 * that allow a name will call this routine to change to
1920 * the specified directory and will call context_restore()
1921 * to change back.
1922 *
1923 * Bugs: This function doesn't protect calls to the other API
1924 * directory setting/retrieving functions and thus might
1925 * leak memory if one of those calls fail with a non-local
1926 * return.
1927 *
1928 * Return: Success: ptr to the previous context. This ptr
1929 * should be passed to context_restore().
1930 *
1931 * Failure: NULL, db_perror called.
1932 *
1933 * Arguments:
1934 * base output parameter
1935 *
1936 * Programmer: matzke@viper
1937 * Sun Jan 29 11:42:47 PST 1995
1938 *
1939 * Modifications:
1940 *-------------------------------------------------------------------------*/
1941 INTERNAL context_t *
context_switch(DBfile * dbfile,char const * name,char const ** base)1942 context_switch(DBfile *dbfile, char const *name, char const **base)
1943 {
1944 char const *me = "context_switch";
1945 char s[256], *b;
1946 context_t *old = ALLOC(context_t);
1947
1948 /*
1949 * Save the old information. If the name doesn't contain a `/' then
1950 * we don't have to do anything. We will mark this case by storing
1951 * NULL as the context name.
1952 */
1953 *base = name;
1954 if (!strchr(name, '/')) {
1955 old->dirid = 0;
1956 old->name = NULL;
1957 return old;
1958 }
1959 if (DBGetDir(dbfile, s) < 0) {
1960 FREE(old);
1961 return NULL;
1962 }
1963 old->dirid = dbfile->pub.dirid;
1964 old->name = STRDUP(s);
1965
1966 /*
1967 * Split the name into a path and a base name. The base name
1968 * is the stuff after the last `/'. If the base name is empty
1969 * then we should raise an E_NOTFOUND right away.
1970 */
1971 b = (char *)strrchr(name, '/');
1972 if (!b || !b[1]) {
1973 FREE(old->name);
1974 FREE(old);
1975 db_perror(name, E_NOTFOUND, me);
1976 return NULL;
1977 }
1978 *base = b + 1;
1979 if (b == name) {
1980 /*
1981 * This is the root directory.
1982 */
1983 if (DBSetDir(dbfile, "/") < 0) {
1984 FREE(old->name);
1985 FREE(old);
1986 return NULL;
1987 }
1988 }
1989 else {
1990 /*
1991 * The path is everything before (not including) the last
1992 * `/'. We would like to just change that slash to a null
1993 * terminator temporarily, but the name might be a static
1994 * string in a read-only data section, so we have to do it
1995 * the long way. We assume (like the rest of SILO and most
1996 * drivers) that the name will not be longer than 255
1997 * characters.
1998 */
1999 strncpy(s, name, b - name);
2000 s[b - name] = '\0';
2001 if (DBSetDir(dbfile, s) < 0) {
2002 FREE(old->name);
2003 FREE(old);
2004 return NULL;
2005 }
2006 }
2007
2008 return old;
2009 }
2010
2011 /*-------------------------------------------------------------------------
2012 * Function: context_restore
2013 *
2014 * Purpose: Restore a previously saved context. If the driver can
2015 * change directories based on a directory ID, we do that.
2016 * Otherwise, we change directories based on the old directory
2017 * name.
2018 *
2019 * Return: Success: 0
2020 *
2021 * Failure: -1, db_perror called.
2022 *
2023 * Programmer: matzke@viper
2024 * Sun Jan 29 12:01:21 PST 1995
2025 *
2026 * Modifications:
2027 *-------------------------------------------------------------------------*/
2028 INTERNAL int
context_restore(DBfile * dbfile,context_t * old)2029 context_restore(DBfile *dbfile, context_t *old)
2030 {
2031 if (!dbfile || !old)
2032 return 0;
2033 if (!old->name) {
2034 FREE(old);
2035 return 0;
2036 }
2037
2038 DBSetDir(dbfile, old->name);
2039
2040 FREE(old->name);
2041 FREE(old);
2042 return 0;
2043 }
2044
2045 /*-------------------------------------------------------------------------
2046 * Function: db_get_fileid
2047 *
2048 * Purpose: Obtain a file ID number which is unique with respect to
2049 * all other open files.
2050 *
2051 * Return: Success: ID number, [0..DB_NFILES-1]
2052 *
2053 * Failure: -1, too many files are open.
2054 *
2055 * Programmer: robb@cloud
2056 * Tue Feb 28 11:00:04 EST 1995
2057 *
2058 * Modifications:
2059 *-------------------------------------------------------------------------*/
2060 PRIVATE int
db_get_fileid(int flags)2061 db_get_fileid ( int flags )
2062 {
2063 static int vhand = 0;
2064 int i;
2065
2066 for (i = 0; i < DB_NFILES; i++) {
2067 if (!_db_fstatus[(vhand + i) % DB_NFILES]) {
2068 i = (vhand + i) % DB_NFILES;
2069 _db_fstatus[i] = flags | DB_ISOPEN;
2070 vhand = (i + 1) % DB_NFILES;
2071 return i;
2072 }
2073 }
2074 return -1;
2075 }
2076
2077 /*-------------------------------------------------------------------------
2078 Function: bjhash
2079
2080 Purpose: Hash a variable length stream of bytes into a 32-bit value.
2081
2082 Programmer: By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net.
2083
2084 You may use this code any way you wish, private, educational, or
2085 commercial. It's free. However, do NOT use for cryptographic purposes.
2086
2087 See http://burtleburtle.net/bob/hash/evahash.html
2088 *-------------------------------------------------------------------------*/
2089
2090 #define bjhash_mix(a,b,c) \
2091 { \
2092 a -= b; a -= c; a ^= (c>>13); \
2093 b -= c; b -= a; b ^= (a<<8); \
2094 c -= a; c -= b; c ^= (b>>13); \
2095 a -= b; a -= c; a ^= (c>>12); \
2096 b -= c; b -= a; b ^= (a<<16); \
2097 c -= a; c -= b; c ^= (b>>5); \
2098 a -= b; a -= c; a ^= (c>>3); \
2099 b -= c; b -= a; b ^= (a<<10); \
2100 c -= a; c -= b; c ^= (b>>15); \
2101 }
2102
bjhash(register const unsigned char * k,register unsigned int length,register unsigned int initval)2103 static unsigned int bjhash(register const unsigned char *k, register unsigned int length, register unsigned int initval)
2104 {
2105 register unsigned int a,b,c,len;
2106
2107 len = length;
2108 a = b = 0x9e3779b9;
2109 c = initval;
2110
2111 while (len >= 12)
2112 {
2113 a += (k[0] +((unsigned int)k[1]<<8) +((unsigned int)k[2]<<16) +((unsigned int)k[3]<<24));
2114 b += (k[4] +((unsigned int)k[5]<<8) +((unsigned int)k[6]<<16) +((unsigned int)k[7]<<24));
2115 c += (k[8] +((unsigned int)k[9]<<8) +((unsigned int)k[10]<<16)+((unsigned int)k[11]<<24));
2116 bjhash_mix(a,b,c);
2117 k += 12; len -= 12;
2118 }
2119
2120 c += length;
2121
2122 switch(len)
2123 {
2124 case 11: c+=((unsigned int)k[10]<<24);
2125 case 10: c+=((unsigned int)k[9]<<16);
2126 case 9 : c+=((unsigned int)k[8]<<8);
2127 case 8 : b+=((unsigned int)k[7]<<24);
2128 case 7 : b+=((unsigned int)k[6]<<16);
2129 case 6 : b+=((unsigned int)k[5]<<8);
2130 case 5 : b+=k[4];
2131 case 4 : a+=((unsigned int)k[3]<<24);
2132 case 3 : a+=((unsigned int)k[2]<<16);
2133 case 2 : a+=((unsigned int)k[1]<<8);
2134 case 1 : a+=k[0];
2135 }
2136
2137 bjhash_mix(a,b,c);
2138
2139 return c;
2140 }
2141
2142
2143 /*-------------------------------------------------------------------------
2144 * Functions: db_register_file, db_unregister_file, db_isregistered_file
2145 *
2146 * Purpose: Maintain list of files returned by DBCreate/DBOpen as well
2147 * as closed by DBClose in order to detect possible operation
2148 * on closed files.
2149 *
2150 * Return: -1 if file limit exceeded. Otherwise [0..DB_NFILES-1]
2151 * representing position in fixed size list.
2152 *
2153 * Programmer: Mark C. Miller, Wed Jul 23 00:14:00 PDT 2008
2154 *
2155 * Modifications:
2156 * Mark C. Miller, Wed Feb 25 23:46:44 PST 2009
2157 * Replaced name of file which can be very different but still represent
2158 * the same file stat structure. We wind up using st_dev/st_ino members
2159 * of stat struct to identify a file. In fact, we use a bjhash of those
2160 * members. This is not foolproof. Non posix filesystems can apparently
2161 * result in st_dev/st_ino combinations which are the same but for
2162 * different files.
2163 *
2164 * Mark C. Miller, Fri Feb 12 08:20:03 PST 2010
2165 * Replaced conditional compilation with SIZEOF_OFF64T with
2166 * db_silo_stat_struct.
2167 *
2168 * Mark C. Miller, Wed May 19 17:07:05 PDT 2010
2169 * Added logic for _WIN32 form of the db_silo_stat_struct.
2170 *-------------------------------------------------------------------------*/
2171 PRIVATE int
db_register_file(DBfile * dbfile,const db_silo_stat_t * filestate,int writeable)2172 db_register_file(DBfile *dbfile, const db_silo_stat_t *filestate, int writeable)
2173 {
2174 int i;
2175 for (i = 0; i < DB_NFILES; i++)
2176 {
2177 if (_db_regstatus[i].f == 0)
2178 {
2179 unsigned int hval = 0;
2180 #ifndef _WIN32
2181 hval = bjhash((unsigned char *) &(filestate->s.st_dev), sizeof(filestate->s.st_dev), hval);
2182 hval = bjhash((unsigned char *) &(filestate->s.st_ino), sizeof(filestate->s.st_ino), hval);
2183 #else
2184 hval = bjhash((unsigned char *) &(filestate->fileindexlo), sizeof(filestate->fileindexlo), hval);
2185 hval = bjhash((unsigned char *) &(filestate->fileindexhi), sizeof(filestate->fileindexhi), hval);
2186 #endif
2187 _db_regstatus[i].f = dbfile;
2188 _db_regstatus[i].n = hval;
2189 _db_regstatus[i].w = writeable;
2190 return i;
2191 }
2192 }
2193 return -1;
2194 }
2195
2196 PRIVATE int
db_unregister_file(DBfile * dbfile)2197 db_unregister_file(DBfile *dbfile)
2198 {
2199 int i;
2200 for (i = 0; i < DB_NFILES; i++)
2201 {
2202 if (_db_regstatus[i].f == dbfile)
2203 {
2204 int j;
2205 _db_regstatus[i].f = 0;
2206 for (j = i; (j < DB_NFILES-1) && (_db_regstatus[j+1].f != 0); j++)
2207 {
2208 _db_regstatus[j].f = _db_regstatus[j+1].f;
2209 _db_regstatus[j].n = _db_regstatus[j+1].n;
2210 _db_regstatus[j].w = _db_regstatus[j+1].w;
2211 }
2212 _db_regstatus[j].f = 0;
2213 return i;
2214 }
2215 }
2216 return -1;
2217 }
2218
2219 PRIVATE int
db_isregistered_file(DBfile * dbfile,const db_silo_stat_t * filestate)2220 db_isregistered_file(DBfile *dbfile, const db_silo_stat_t *filestate)
2221 {
2222 int i;
2223 if (dbfile)
2224 {
2225 for (i = 0; i < DB_NFILES; i++)
2226 {
2227 if (_db_regstatus[i].f == dbfile)
2228 return i;
2229 }
2230 }
2231 else if (filestate)
2232 {
2233 unsigned int hval = 0;
2234 #ifndef _WIN32
2235 hval = bjhash((unsigned char *) &(filestate->s.st_dev), sizeof(filestate->s.st_dev), hval);
2236 hval = bjhash((unsigned char *) &(filestate->s.st_ino), sizeof(filestate->s.st_ino), hval);
2237 #else
2238 hval = bjhash((unsigned char *) &(filestate->fileindexlo), sizeof(filestate->fileindexlo), hval);
2239 hval = bjhash((unsigned char *) &(filestate->fileindexhi), sizeof(filestate->fileindexhi), hval);
2240 #endif
2241 for (i = 0; i < DB_NFILES; i++)
2242 {
2243 if (_db_regstatus[i].f != 0 &&
2244 _db_regstatus[i].n == hval)
2245 return i;
2246 }
2247 }
2248 return -1;
2249 }
2250
2251 INTERNAL int
db_num_registered_files()2252 db_num_registered_files()
2253 {
2254 int i;
2255 int cnt = 0;
2256 for (i = 0; i < DB_NFILES; i++)
2257 {
2258 if (_db_regstatus[i].f) cnt++;
2259 }
2260 return cnt;
2261 }
2262
2263 /*-------------------------------------------------------------------------
2264 * Function: db_silo_stat_one_file
2265 *
2266 * Purpose: Better stat method for silo taking into account stat/stat64
2267 * as well as windows-specific notion of an 'inode'.
2268 *
2269 * Programmer: Mark C. Miller
2270 *
2271 * Modifications:
2272 * Adjusted the windows-specific logic to obtain fileindex information so
2273 * that if that work fails, it still returns stat retval and errno of stat.
2274 *-------------------------------------------------------------------------*/
2275 PRIVATE int
db_silo_stat_one_file(const char * name,db_silo_stat_t * statbuf)2276 db_silo_stat_one_file(const char *name, db_silo_stat_t *statbuf)
2277 {
2278 int retval;
2279 errno = 0;
2280 memset(&(statbuf->s), 0, sizeof(statbuf->s));
2281
2282 retval = stat(name, &(statbuf->s));
2283
2284 #ifdef _WIN32
2285 if (retval == 0)
2286 {
2287 /* this logic was copied by and large from HDF5 sec2 VFD */
2288 int errnotmp = errno;
2289 int fd = open(name, O_RDONLY);
2290 if (fd != -1)
2291 {
2292 struct _BY_HANDLE_FILE_INFORMATION fileinfo;
2293 GetFileInformationByHandle((HANDLE)_get_osfhandle(fd), &fileinfo);
2294 statbuf->fileindexhi = fileinfo.nFileIndexHigh;
2295 statbuf->fileindexlo = fileinfo.nFileIndexLow;
2296 close(fd);
2297 }
2298 errno = errnotmp;
2299 }
2300 #endif /* #ifdef _WIN32 */
2301
2302 return retval;
2303 }
2304
2305 /*-------------------------------------------------------------------------
2306 * Function: db_silo_stat
2307 *
2308 * Purpose: Better stat method for silo taking into account stat/stat64
2309 * as well as issues with filenames used for split vfds.
2310 *
2311 * Programmer: Mark C. Miller, Fri Feb 12 08:21:52 PST 2010
2312 *-------------------------------------------------------------------------*/
2313 PRIVATE int
db_silo_stat(const char * name,db_silo_stat_t * statbuf,int opts_set_id)2314 db_silo_stat(const char *name, db_silo_stat_t *statbuf, int opts_set_id)
2315 {
2316 int retval = db_silo_stat_one_file(name, statbuf);
2317
2318 /* check for case where we're opening a buffer as a file */
2319 if (opts_set_id > DB_FILE_OPTS_LAST)
2320 {
2321 const DBoptlist *opts = SILO_Globals.fileOptionsSets[opts_set_id-NUM_DEFAULT_FILE_OPTIONS_SETS];
2322 void *p; int vfd = -1;
2323 if ((p = DBGetOption(opts, DBOPT_H5_VFD)))
2324 vfd = *((int*)p);
2325 if (vfd == DB_H5VFD_FIC)
2326 {
2327 statbuf->s.st_mode = 0x0;
2328 statbuf->s.st_mode |= S_IREAD;
2329 return 0;
2330 }
2331 }
2332
2333 if (opts_set_id == -1 ||
2334 opts_set_id == DB_FILE_OPTS_H5_DEFAULT_SPLIT ||
2335 opts_set_id > DB_FILE_OPTS_LAST)
2336 {
2337 int i;
2338 int imin = opts_set_id == -1 ? 0 : opts_set_id;
2339 int imax = opts_set_id == -1 ? MAX_FILE_OPTIONS_SETS: opts_set_id;
2340 int tmperrno = errno;
2341
2342 for (i = imin; i < imax; i++)
2343 {
2344 db_silo_stat_t tmpstatbuf;
2345 static char tmpname[4096];
2346 char *meta_ext="", *raw_ext="-raw";
2347 void *p; int vfd = -1;
2348 const DBoptlist *opts;
2349
2350 if (opts_set_id == -1)
2351 opts = SILO_Globals.fileOptionsSets[i];
2352 else if (opts_set_id == DB_FILE_OPTS_H5_DEFAULT_SPLIT)
2353 opts = 0;
2354 else
2355 opts = SILO_Globals.fileOptionsSets[i-NUM_DEFAULT_FILE_OPTIONS_SETS];
2356
2357 /* ignore if options set id does not yield a valid options set */
2358 if (opts)
2359 {
2360 /* ignore if options set unrelated to split vfds */
2361 if ((p = DBGetOption(opts, DBOPT_H5_VFD)))
2362 vfd = *((int*)p);
2363
2364 if (vfd != DB_H5VFD_SPLIT)
2365 continue;
2366
2367 /* ok, get meta/raw filenaming extension conventions */
2368 if ((p = DBGetOption(opts, DBOPT_H5_META_EXTENSION)))
2369 meta_ext = (char *) p;
2370 if ((p = DBGetOption(opts, DBOPT_H5_RAW_EXTENSION)))
2371 raw_ext = (char *) p;
2372 }
2373
2374 /* try the raw file name, first */
2375 if (strstr(raw_ext,"%s"))
2376 sprintf(tmpname, raw_ext, name);
2377 else
2378 sprintf(tmpname, "%s%s", name, raw_ext);
2379 errno = 0;
2380 if (db_silo_stat_one_file(tmpname, &tmpstatbuf) != 0 || errno != 0)
2381 continue;
2382
2383 /* try the meta file last and return its statbuf */
2384 if (strstr(meta_ext,"%s"))
2385 sprintf(tmpname, meta_ext, name);
2386 else
2387 sprintf(tmpname, "%s%s", name, meta_ext);
2388 memset(&tmpstatbuf, 0, sizeof(tmpstatbuf));
2389 if (db_silo_stat_one_file(tmpname, &tmpstatbuf) == 0 && errno == 0)
2390 {
2391 memcpy(statbuf, &tmpstatbuf, sizeof(tmpstatbuf));
2392 return 0;
2393 }
2394 }
2395
2396 errno = tmperrno;
2397 }
2398
2399 return retval;
2400 }
2401
2402 /*-------------------------------------------------------------------------
2403 * Function: db_filter_install
2404 *
2405 * Purpose: Install the database-requested filters, calling the filter
2406 * `open' routine for each named filter and reporting errors
2407 * for filters that can't be found. Filters are requested
2408 * through the `_filters' character variable which is
2409 * optional. This variable should contain a list of filter
2410 * names separated by `;' (extra `;' may appear at the beginning
2411 * or end of the string). The first filter in the list is
2412 * the one that will be installed closest to the device
2413 * driver while the last filter is installed closest to the
2414 * API.
2415 *
2416 * Return: Success: 0
2417 *
2418 * Failure: -1
2419 *
2420 * Programmer: robb@cloud
2421 * Tue Feb 28 11:58:01 EST 1995
2422 *
2423 * Modifications:
2424 * Eric Brugger, Fri Mar 7 15:26:29 PST 1997
2425 * I modified the routine to copy the filter name string to a scratch
2426 * so array so that a NULL character could be added without overwriting
2427 * the last character in the string.
2428 *-------------------------------------------------------------------------*/
2429 PRIVATE int
db_filter_install(DBfile * dbfile)2430 db_filter_install ( DBfile *dbfile )
2431 {
2432 char *me = "db_filter_install";
2433 int len, i;
2434 char *var, *var2, *s, *filter_name;
2435 static char not_found[128];
2436
2437 /*
2438 * There should be a miscellaneous variable called `_filters' in
2439 * the current (root) directory. If not, then no filters are
2440 * requested.
2441 */
2442 if (!DBInqVarExists(dbfile,"_filters"))
2443 return(0);
2444
2445 /*
2446 * Read the `_filters' variable and make sure it is a character
2447 * string.
2448 */
2449 if (DB_CHAR != DBGetVarType(dbfile, "_filters")) {
2450 db_perror("`_filters' is not a character variable",
2451 E_NOTFILTER, me);
2452 return -1;
2453 }
2454 len = DBGetVarLength(dbfile, "_filters");
2455 if (len <= 0)
2456 return 0; /*no filters requested */
2457 if (NULL == (var = (char*)DBGetVar(dbfile, "_filters")))
2458 return -1;
2459
2460 /*
2461 * Copy the variable and add a terminating NULL character.
2462 */
2463 var2 = ALLOC_N (char, len+1);
2464 strncpy (var2, var, len);
2465 var2[len] = '\0';
2466
2467 /*
2468 * Process each filter. Names are separated from one another
2469 * by semicolons which may also appear at the beginning and end
2470 * of the string. Be careful for things like `;;'.
2471 */
2472 not_found[0] = '\0';
2473 s = var2;
2474 while ((filter_name = strtok(s, ";\n\r"))) {
2475 s = NULL;
2476 if (!filter_name[0])
2477 continue;
2478
2479 for (i = 0; i < DB_NFILTERS; i++) {
2480 if (_db_filter[i].name &&
2481 !strcmp(_db_filter[i].name, filter_name)) {
2482 break;
2483 }
2484 }
2485
2486 /*
2487 * If the filter isn't found, tack the name onto the end
2488 * of a list of names that weren't found, being careful
2489 * not to overflow that buffer. Each name should be
2490 * separated from the others by a semicolon as in the `_filters'
2491 * database variable.
2492 */
2493 if (i >= DB_NFILTERS) {
2494 int q = 0;
2495 len = strlen(not_found);
2496 if (len && len + 1 < sizeof(not_found)) {
2497 strcat(not_found, ";");
2498 len++;
2499 }
2500 while (len + 1 < sizeof(not_found))
2501 not_found[len++] = filter_name[q++];
2502 not_found[len] = '\0';
2503 continue;
2504 }
2505
2506 /*
2507 * If the filter has an `open' routine, call it now.
2508 */
2509 if (_db_filter[i].open) {
2510 (void)(_db_filter[i].open) (dbfile, _db_filter[i].name);
2511 }
2512 }
2513
2514 FREE (var2);
2515
2516 /*
2517 * If we failed to find some filters, we should notify the user.
2518 * Should we return success or failure??? For now, we return
2519 * success so that failure to find a filter is a warning at
2520 * this level but an error if db_perror calls longjmp(). This
2521 * gives the application a little control.
2522 */
2523 if (not_found[0]) {
2524 db_perror(not_found, E_NOTFILTER, me);
2525 }
2526 return 0;
2527 }
2528
2529 /*-------------------------------------------------------------------------
2530 * Function: DBFilterRegistration
2531 *
2532 * Purpose: Manipulate the global filter table by adding, changing,
2533 * or removing a filter. `Name' specifies the filter that
2534 * will be affected. `Init' and `open' are filter functions
2535 * that will be called when a database is opened. `Init' is
2536 * called for every database that is opend (just after opening;
2537 * filters called in arbitrary order). `Open' is called for
2538 * each file which requests that filter.
2539 *
2540 * Return: Success: 0
2541 *
2542 * Failure: -1, table is full
2543 *
2544 * Programmer: robb@cloud
2545 * Tue Feb 28 11:26:07 EST 1995
2546 *
2547 * Modifications:
2548 *-------------------------------------------------------------------------*/
2549 PUBLIC int
DBFilterRegistration(const char * name,int (* init)(DBfile *,char *),int (* open)(DBfile *,char *))2550 DBFilterRegistration(const char *name, int(*init)(DBfile*, char*),
2551 int(*open)(DBfile*, char*))
2552 {
2553 int i, j = -1;
2554
2555 API_BEGIN("DBFilterRegistration", int, -1) {
2556
2557 /*
2558 * Look for entry already in the table. If found, simply change
2559 * the callbacks.
2560 */
2561 for (i = 0; i < DB_NFILTERS; i++) {
2562 if (_db_filter[i].name && !strcmp(_db_filter[i].name, name)) {
2563 break;
2564 }
2565 if (j < 0 && !_db_filter[i].name)
2566 j = i;
2567 }
2568 if (i < DB_NFILTERS) {
2569 if (!init && !open) {
2570 FREE(_db_filter[i].name);
2571 _db_filter[i].name = NULL;
2572 }
2573 else {
2574 _db_filter[i].init = init;
2575 _db_filter[i].open = open;
2576 }
2577 API_RETURN(0);
2578 }
2579
2580 /*
2581 * This is a new filter definition. Add it to the first free
2582 * slot.
2583 */
2584 if (init || open) {
2585 if (j < 0)
2586 API_ERROR((char *)name, E_MAXFILTERS);
2587 _db_filter[j].name = STRDUP(name);
2588 _db_filter[j].init = init;
2589 _db_filter[j].open = open;
2590 }
2591 API_RETURN(0);
2592 }
2593 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
2594 }
2595
2596 /*-------------------------------------------------------------------------
2597 * Function: DBUninstall
2598 *
2599 * Purpose: Uninstalls the top-most filter if any. This is similar
2600 * to closing the file except the uninstall is not propogated
2601 * down the filter stack.
2602 *
2603 * If the `uninstall' callback is null, this routine
2604 * doesn't do anything and then returns success. This
2605 * allows device drivers to omit the uninstall function.
2606 *
2607 * Return: Success: 0
2608 *
2609 * Failure: -1
2610 *
2611 * Programmer: robb@cloud
2612 * Thu Mar 16 10:29:36 EST 1995
2613 *
2614 * Modifications:
2615 *-------------------------------------------------------------------------*/
2616 int
DBUninstall(DBfile * dbfile)2617 DBUninstall(DBfile *dbfile)
2618 {
2619 int retval;
2620
2621 API_BEGIN("DBUninstall", int, -1) {
2622 if (!dbfile)
2623 API_ERROR(NULL, E_NOFILE);
2624 if (!dbfile->pub.uninstall)
2625 {
2626 API_RETURN(0);
2627 }
2628
2629 retval = (dbfile->pub.uninstall) (dbfile);
2630 API_RETURN(retval);
2631 }
2632 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
2633 }
2634
2635 /*----------------------------------------------------------------------
2636 * Routine: DBSetDataReadMask2
2637 *
2638 * Purpose: Set and return the data read mask
2639 *
2640 * Programmer: Sean Ahern, Fri Jan 26 17:28:06 PST 2001
2641 *
2642 * Description: This routine sets the data read mask. It returns the
2643 * previous data read mask. The data read mask is used to
2644 * tailor how the various driver functions read their data.
2645 * All of them are required to populate the metadata in the
2646 * returned structures. Ordinarily, they also read all of
2647 * the "real" data. If they honor the data read flag (see
2648 * DBDataReadFlagHonored()), the user can set, by way of this
2649 * function, the mask of "real" data to read. This allows
2650 * the user to decide not to read in the zonelist array of a
2651 * UCD mesh, for instance, if he knows that it will not be
2652 * useful to him (i.e. constant connectivity over a
2653 * time-varying dataset.)
2654 *
2655 * Note: Many of these DBSet/Get routines DO NOT include the standard
2656 * API_BEGIN/API_END macros. This is primarily due to the fact that
2657 * these calls CANNOT fail. For others, that can fail, we do indeed
2658 * use the API_BEGIN/API_END macros as per instructions in
2659 * silo_private.h
2660 *
2661 * Modifications:
2662 *--------------------------------------------------------------------*/
2663 PUBLIC unsigned long long
DBSetDataReadMask2(unsigned long long mask)2664 DBSetDataReadMask2(unsigned long long mask)
2665 {
2666 unsigned long long oldmask = SILO_Globals.dataReadMask;
2667 SILO_Globals.dataReadMask = mask;
2668 return oldmask;
2669 }
2670
2671 /*----------------------------------------------------------------------
2672 * Routine: DBGetDataReadMask2
2673 *
2674 * Purpose: Return the current data read mask
2675 *
2676 * Programmer: Sean Ahern, Thu Mar 1 12:02:48 PST 2001
2677 *
2678 * Description: This routine returns the current data read mask.
2679 * The data read mask is used to tailor how the various
2680 * driver functions read their data.
2681 *
2682 * Modifications:
2683 *--------------------------------------------------------------------*/
2684 PUBLIC unsigned long long
DBGetDataReadMask2(void)2685 DBGetDataReadMask2(void)
2686 {
2687 return SILO_Globals.dataReadMask;
2688 }
2689
2690 /*----------------------------------------------------------------------
2691 * Routine: DBSetAllowOverwrites
2692 *
2693 * Purpose: Set and return the allow overwrites flags
2694 *
2695 * Programmer: Mark C. Miller, August 23, 3005
2696 *
2697 * Description: This routine sets the flag that controls whether
2698 * overwrites are allowed.
2699 *--------------------------------------------------------------------*/
2700 PUBLIC int
DBSetAllowOverwrites(int allow)2701 DBSetAllowOverwrites(int allow)
2702 {
2703 int oldAllow = SILO_Globals.allowOverwrites;
2704 SILO_Globals.allowOverwrites = allow;
2705 return oldAllow;
2706 }
2707
2708 PUBLIC int
DBGetAllowOverwrites()2709 DBGetAllowOverwrites()
2710 {
2711 return SILO_Globals.allowOverwrites;
2712 }
2713
2714 /*----------------------------------------------------------------------
2715 * Routine: DBSetAllowEmptyObjects
2716 *
2717 * Purpose: Set and return the allow empty objects flags
2718 *
2719 * Programmer: Mark C. Miller, January 9, 2013
2720 *
2721 * Description: This routine sets the flag that controls whether
2722 * empty objects are allowed. By default, they are not.
2723 *--------------------------------------------------------------------*/
2724 PUBLIC int
DBSetAllowEmptyObjects(int allow)2725 DBSetAllowEmptyObjects(int allow)
2726 {
2727 int oldAllow = SILO_Globals.allowEmptyObjects;
2728 SILO_Globals.allowEmptyObjects = allow;
2729 return oldAllow;
2730 }
2731
2732 PUBLIC int
DBGetAllowEmptyObjects()2733 DBGetAllowEmptyObjects()
2734 {
2735 return SILO_Globals.allowEmptyObjects;
2736 }
2737
2738 /*----------------------------------------------------------------------
2739 * Routine: DBSetEnableChecksums
2740 *
2741 * Purpose: Set and return the enable checksums flags
2742 *
2743 * Programmer: Mark C. Miller, May 1, 2006
2744 *
2745 * Description: This routine sets the flag that controls whether
2746 * checksums are computed on client data.
2747 *--------------------------------------------------------------------*/
2748 PUBLIC int
DBSetEnableChecksums(int enable)2749 DBSetEnableChecksums(int enable)
2750 {
2751 int oldEnable = SILO_Globals.enableChecksums;
2752 SILO_Globals.enableChecksums = enable;
2753 return oldEnable;
2754 }
2755
2756 PUBLIC int
DBGetEnableChecksums()2757 DBGetEnableChecksums()
2758 {
2759 return SILO_Globals.enableChecksums;
2760 }
2761
2762 /*----------------------------------------------------------------------
2763 * Routine: DBSetCompression
2764 *
2765 * Purpose: Set and return the enable Compression flags
2766 *
2767 * Programmer: Thomas R. Treadway, Wed Feb 28 11:36:34 PST 2007
2768 *
2769 * Description: This routine enters the compression method information.
2770 *--------------------------------------------------------------------*/
2771 PUBLIC void
DBSetCompression(const char * s)2772 DBSetCompression(const char *s)
2773 {
2774 if (s && *s == '\0') {
2775 if (SILO_Globals.compressionParams)
2776 FREE(SILO_Globals.compressionParams);
2777 SILO_Globals.compressionParams = ALLOC_N(char, 12);
2778 strcpy(SILO_Globals.compressionParams, "METHOD=GZIP");
2779 }
2780 else if (s) {
2781 if (SILO_Globals.compressionParams)
2782 FREE(SILO_Globals.compressionParams);
2783 SILO_Globals.compressionParams=ALLOC_N(char,strlen(s)+1);
2784 strcpy(SILO_Globals.compressionParams, s);
2785 }
2786 else {
2787 if (SILO_Globals.compressionParams)
2788 FREE(SILO_Globals.compressionParams);
2789 SILO_Globals.compressionParams=0;
2790 }
2791 }
2792
2793 PUBLIC char const *
DBGetCompression()2794 DBGetCompression()
2795 {
2796 return SILO_Globals.compressionParams;
2797 }
2798
2799 PUBLIC int
DBFreeCompressionResources(DBfile * dbfile,const char * meshname)2800 DBFreeCompressionResources(DBfile *dbfile, const char *meshname)
2801 {
2802 int retval = 0;
2803
2804 API_BEGIN2("DBFreeCompressionResources", int, -1, api_dummy) {
2805
2806 if (!dbfile->pub.free_z)
2807 API_ERROR(dbfile->pub.name, E_NOTIMP);
2808 retval = ((dbfile->pub.free_z) (dbfile, meshname));
2809
2810 API_RETURN(retval);
2811 }
2812 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
2813 }
2814
2815
2816 /*----------------------------------------------------------------------
2817 * Routine: DBSetFriendlyHDF5Names
2818 *
2819 * Purpose: Set flag to create friendly HDF5 dataset names
2820 *
2821 * Programmer: Mark C. Miller, Thu Apr 19 15:17:05 PDT 2007
2822 *
2823 * Description: Sets flag for HDF5 driver to control production of
2824 * friendly dataset names. Returns value of old setting.
2825 *--------------------------------------------------------------------*/
2826 PUBLIC int
DBSetFriendlyHDF5Names(int enable)2827 DBSetFriendlyHDF5Names(int enable)
2828 {
2829 int oldEnable = SILO_Globals.enableFriendlyHDF5Names;
2830 SILO_Globals.enableFriendlyHDF5Names = enable;
2831 return oldEnable;
2832 }
2833
2834 PUBLIC int
DBGetFriendlyHDF5Names()2835 DBGetFriendlyHDF5Names()
2836 {
2837 return SILO_Globals.enableFriendlyHDF5Names;
2838 }
2839
2840 #define CHECK_FOR_FRIENDLY(ON,SU) \
2841 ntotal += toc->n ## ON; \
2842 for (i = 0; i < toc->n ## ON; i++) \
2843 { \
2844 char tmp[1024]; \
2845 snprintf(tmp, sizeof(tmp), "%s_%s", toc->ON ## _names[i], SU); \
2846 if (DBInqVarExists(f, tmp)) \
2847 nfriendly++; \
2848 }
2849
2850 /*----------------------------------------------------------------------
2851 * Routine: db_guess_has_friendly_HDF5_names_r
2852 *
2853 * Purpose: Recursive helper func for DBGuessHasFriendlyHDF5Names
2854 * names.
2855 *
2856 * Programmer: Mark C. Miller, Wed Sep 2 15:27:06 PDT 2009
2857 *
2858 *--------------------------------------------------------------------*/
2859 PRIVATE int
db_guess_has_friendly_HDF5_names_r(DBfile * f)2860 db_guess_has_friendly_HDF5_names_r(DBfile *f)
2861 {
2862 int i, ntotal = 0, nfriendly = 0;
2863 int retval;
2864 DBtoc *toc;
2865
2866 toc = DBGetToc(f);
2867
2868 if (!toc) return 0;
2869
2870 CHECK_FOR_FRIENDLY(multimesh, "meshnames");
2871 CHECK_FOR_FRIENDLY(multivar, "varnames");
2872 CHECK_FOR_FRIENDLY(multimat, "matnames");
2873 CHECK_FOR_FRIENDLY(qmesh, "coord0");
2874 CHECK_FOR_FRIENDLY(qvar, "data");
2875 CHECK_FOR_FRIENDLY(ucdmesh, "coord0");
2876 CHECK_FOR_FRIENDLY(ucdvar, "data");
2877 CHECK_FOR_FRIENDLY(ptmesh, "coord0");
2878 CHECK_FOR_FRIENDLY(ptvar, "data");
2879 CHECK_FOR_FRIENDLY(csgmesh, "_coeffs");
2880 CHECK_FOR_FRIENDLY(csgvar, "data");
2881 CHECK_FOR_FRIENDLY(mat, "_matlist");
2882 CHECK_FOR_FRIENDLY(matspecies, "_speclist");
2883 CHECK_FOR_FRIENDLY(curve, "_yvals");
2884 CHECK_FOR_FRIENDLY(obj, "_nodelist");
2885
2886 if (ntotal >= 3) /* arb. min of 3 objects */
2887 {
2888 if (nfriendly >= ntotal/2)
2889 return 1;
2890 else
2891 return 0;
2892 }
2893
2894 retval = -1;
2895 for (i = 0; i < toc->ndir && retval == -1; i++)
2896 {
2897 DBSetDir(f, toc->dir_names[i]);
2898 retval = db_guess_has_friendly_HDF5_names_r(f);
2899 DBSetDir(f, "..");
2900 }
2901
2902 return retval;
2903 }
2904
2905 /*----------------------------------------------------------------------
2906 * Routine: DBGuessHasFriendlyHDF5Names
2907 *
2908 * Purpose: Determine if it looks like a given file has HDF5 friendly
2909 * names.
2910 *
2911 * Programmer: Mark C. Miller, Wed Sep 2 15:27:06 PDT 2009
2912 *
2913 *--------------------------------------------------------------------*/
2914 PUBLIC int
DBGuessHasFriendlyHDF5Names(DBfile * f)2915 DBGuessHasFriendlyHDF5Names(DBfile *f)
2916 {
2917 char cwd[1024];
2918 int retval;
2919
2920 if (DBGetDriverType(f) != 7 /* DB_HDF5X */)
2921 return 0;
2922
2923 DBGetDir(f, cwd);
2924 retval = db_guess_has_friendly_HDF5_names_r(f);
2925 DBSetDir(f, cwd);
2926
2927 return retval;
2928 }
2929
2930 /*----------------------------------------------------------------------
2931 * Routine: DBSetDeprecateWarnings
2932 *
2933 * Purpose: Set number of deprecate warnings Silo should print.
2934 * Default is 3. Setting to zero effectively disables.
2935 *
2936 * Programmer: Mark C. Miller, Thu Oct 11 16:50:12 PDT 2007
2937 *
2938 *--------------------------------------------------------------------*/
2939 PUBLIC int
DBSetDeprecateWarnings(int count)2940 DBSetDeprecateWarnings(int count)
2941 {
2942 int oldCount = SILO_Globals.maxDeprecateWarnings;
2943 SILO_Globals.maxDeprecateWarnings = count;
2944 return oldCount;
2945 }
2946
2947 PUBLIC int
DBGetDeprecateWarnings()2948 DBGetDeprecateWarnings()
2949 {
2950 return SILO_Globals.maxDeprecateWarnings;
2951 }
2952
2953 /*----------------------------------------------------------------------
2954 * Routine: DBSetUnknownDriverPriority
2955 *
2956 * Purpose: Set priority order of drivers used by unknown driver.
2957 *
2958 * Programmer: Mark C. Miller, May 1, 2006
2959 *
2960 * Description: This routine sets the flag that controls whether
2961 * checksums are computed on client data.
2962 *--------------------------------------------------------------------*/
2963 PUBLIC int const *
DBSetUnknownDriverPriorities(const int * priorities)2964 DBSetUnknownDriverPriorities(const int *priorities)
2965 {
2966 int i = 0;
2967 static int oldPriorities[MAX_FILE_OPTIONS_SETS+DB_NFORMATS+1];
2968 memcpy(oldPriorities, SILO_Globals.unknownDriverPriorities, sizeof(oldPriorities));
2969 while (i < (MAX_FILE_OPTIONS_SETS+DB_NFORMATS+1) && priorities[i] >= 0)
2970 {
2971 SILO_Globals.unknownDriverPriorities[i] = priorities[i];
2972 i++;
2973 }
2974 if (i < (MAX_FILE_OPTIONS_SETS+DB_NFORMATS+1))
2975 SILO_Globals.unknownDriverPriorities[i] = -1;
2976 return oldPriorities;
2977 }
2978
2979 PUBLIC int const *
DBGetUnknownDriverPriorities()2980 DBGetUnknownDriverPriorities()
2981 {
2982 static int priorities[MAX_FILE_OPTIONS_SETS+DB_NFORMATS+1];
2983 memcpy(priorities, SILO_Globals.unknownDriverPriorities, sizeof(priorities));
2984 return priorities;
2985 }
2986
2987 PUBLIC int
DBRegisterFileOptionsSet(const DBoptlist * opts)2988 DBRegisterFileOptionsSet(const DBoptlist *opts)
2989 {
2990 int i;
2991
2992 API_BEGIN("DBRegisterFileOptionsSet", int, -1) {
2993 for (i = 0; i < MAX_FILE_OPTIONS_SETS; i++)
2994 {
2995 if (SILO_Globals.fileOptionsSets[i] == 0)
2996 {
2997 SILO_Globals.fileOptionsSets[i] = opts;
2998 API_RETURN(i+NUM_DEFAULT_FILE_OPTIONS_SETS);
2999 }
3000 }
3001 API_ERROR("Silo library", E_MAXFILEOPTSETS);
3002 }
3003 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
3004 }
3005
3006 PUBLIC int
DBUnregisterFileOptionsSet(int opts_set_id)3007 DBUnregisterFileOptionsSet(int opts_set_id)
3008 {
3009 int _opts_set_id = opts_set_id-NUM_DEFAULT_FILE_OPTIONS_SETS;
3010
3011 API_BEGIN("DBUnregisterFileOptionsSet", int, -1) {
3012 if (SILO_Globals.fileOptionsSets[_opts_set_id] == 0)
3013 API_ERROR("opts_set_id", E_BADARGS);
3014 SILO_Globals.fileOptionsSets[_opts_set_id] = 0;
3015 API_RETURN(0);
3016 }
3017 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
3018 }
3019
3020 PUBLIC void
DBUnregisterAllFileOptionsSets()3021 DBUnregisterAllFileOptionsSets()
3022 {
3023 int i;
3024
3025 for (i = 0; i < MAX_FILE_OPTIONS_SETS; i++)
3026 SILO_Globals.fileOptionsSets[i] = 0;
3027 }
3028
db_get_used_file_options_sets_ids()3029 const int* db_get_used_file_options_sets_ids()
3030 {
3031 int i,n;
3032 static int used_slots[MAX_FILE_OPTIONS_SETS+NUM_DEFAULT_FILE_OPTIONS_SETS+1];
3033
3034
3035 /* For the default cases, only return those that 'matter' in that
3036 they could possibly have an impact on Silo's ability to actually
3037 open the file. In addtion, put them in some kind of priority order */
3038 n = 0;
3039 used_slots[n++] = DB_FILE_OPTS_H5_DEFAULT_SILO;
3040 used_slots[n++] = DB_FILE_OPTS_H5_DEFAULT_SPLIT;
3041 used_slots[n++] = DB_FILE_OPTS_H5_DEFAULT_DIRECT;
3042 used_slots[n++] = DB_FILE_OPTS_H5_DEFAULT_FAMILY;
3043 used_slots[n++] = DB_FILE_OPTS_H5_DEFAULT_MPIO;
3044 used_slots[n++] = DB_FILE_OPTS_H5_DEFAULT_MPIP;
3045 for (i = n; i < MAX_FILE_OPTIONS_SETS+NUM_DEFAULT_FILE_OPTIONS_SETS+1; i++)
3046 used_slots[i] = -1;
3047
3048 /* fill in with used options set slots */
3049 for (i = 0; i < MAX_FILE_OPTIONS_SETS; i++)
3050 {
3051 if (SILO_Globals.fileOptionsSets[i]==0)
3052 continue;
3053 used_slots[n++] = i+NUM_DEFAULT_FILE_OPTIONS_SETS;
3054 }
3055
3056 return used_slots;
3057 }
3058
3059 /*----------------------------------------------------------------------
3060 * Routine: DBGrabDriver
3061 *
3062 * Purpose: Set and return the low level driver file handle
3063 *
3064 * Programmer: Thomas R. Treadway, Tue May 29 15:52:19 PDT 2007
3065 *
3066 * Description: This routine returns a ponter to the driver-native
3067 * file handle.
3068 *
3069 * Modifications
3070 * Mark C. Miller, Thu Oct 11 15:36:10 PDT 2007
3071 * Record fact file was grabbed by adding var at top-level
3072 *--------------------------------------------------------------------*/
3073 PUBLIC void *
DBGrabDriver(DBfile * file)3074 DBGrabDriver(DBfile *file)
3075 {
3076 void *rtn = 0;
3077 if (file) {
3078 if (file->pub.GrabId > (void *) 0) {
3079 int grab_val = 1;
3080 DBWrite(file, "/_was_grabbed", &grab_val, &grab_val, 1, DB_INT);
3081 SILO_Globals.enableGrabDriver = TRUE;
3082 rtn = (void *) file->pub.GrabId;
3083 }
3084 }
3085 return rtn;
3086 }
3087 /*----------------------------------------------------------------------
3088 * Routine: DBGetDriverType
3089 *
3090 * Purpose: Return the drive type
3091 *
3092 * Programmer: Thomas R. Treadway, Thu Jun 7 13:19:48 PDT 2007
3093 *
3094 * Description: This routine returns a the driver type
3095 *--------------------------------------------------------------------*/
3096 PUBLIC int
DBGetDriverType(const DBfile * file)3097 DBGetDriverType(const DBfile *file)
3098 {
3099 if (file) {
3100 return file->pub.type;
3101 }
3102 return DB_UNKNOWN;
3103 }
3104
3105 /*----------------------------------------------------------------------
3106 * Routine: DBGetDriverTypeFromPath
3107 *
3108 * Purpose: Return the drive type
3109 *
3110 * Programmer: Thomas R. Treadway, Tue Jul 3 15:24:58 PDT 2007
3111 *
3112 * Description: This routine returns a the driver type
3113 *
3114 * Modifications:
3115 *
3116 * Thomas R. Treadway, Thu Jul 5 11:57:03 PDT 2007
3117 * DB_HDR5 is conditional
3118 *
3119 * Mark C. Miller, Mon Nov 19 10:45:05 PST 2007
3120 * Removed conditional compilation on HDF5 driver
3121 *
3122 * Mark C. Miller, Mon Oct 25 16:12:49 PDT 2010
3123 * Initialize buf to ensure it will be null terminated no matter
3124 * what happens during open/read.
3125 *--------------------------------------------------------------------*/
3126 PUBLIC int
DBGetDriverTypeFromPath(const char * path)3127 DBGetDriverTypeFromPath(const char *path)
3128 {
3129 char buf[9] = {'\0','\0','\0','\0','\0','\0','\0','\0','\0'};
3130 int fd;
3131 int nbytes;
3132 int flags = O_RDONLY;
3133 if ((fd = open(path, flags)) < 0) {
3134 printf("cannot open `%s'\n", path);
3135 return -1;
3136 }
3137 if ((nbytes = read(fd, (char *)buf, 8)) == -1) {
3138 printf("cannot read `%s'\n", path);
3139 close(fd);
3140 return -1;
3141 }
3142 if (nbytes <= 5) {
3143 printf("cannot read `%s' buffer too small\n", path);
3144 close(fd);
3145 return -1;
3146 }
3147 (void) close(fd);
3148 if (strstr(buf, "PDB"))
3149 return 2; /* can't use DB_PDB here */
3150 if (strstr(buf, "HDF"))
3151 return 7; /* can't use DB_HDF5X here. */
3152 return DB_UNKNOWN;
3153 }
3154
3155 /*----------------------------------------------------------------------
3156 * Routine: DBJoinPath
3157 *
3158 * Purpose: Given paths with possible relative naming, combine them
3159 * into a single absolute path.
3160 *
3161 * Programmer: Mark C. Miller, July 20, 2008
3162 *--------------------------------------------------------------------*/
3163 PUBLIC char *
DBJoinPath(const char * first,const char * second)3164 DBJoinPath(const char *first, const char *second)
3165 {
3166 API_BEGIN("DBJoinPath", char *, NULL) {
3167 API_RETURN(db_join_path(first, second));
3168 }
3169 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
3170 }
3171
3172 /*----------------------------------------------------------------------
3173 * Routine: DBUngrabDriver
3174 *
3175 * Purpose: Return control of the low level driver
3176 *
3177 * Programmer: Thomas R. Treadway, Thu Jun 7 13:19:48 PDT 2007
3178 *
3179 * Description: This routine returns a the driver-native type
3180 *--------------------------------------------------------------------*/
3181 PUBLIC int
DBUngrabDriver(DBfile * file,const void * driver_handle)3182 DBUngrabDriver(DBfile *file, const void *driver_handle)
3183 {
3184 if (file) {
3185 SILO_Globals.enableGrabDriver = FALSE;
3186 return file->pub.type;
3187 }
3188 return DB_UNKNOWN;
3189 }
3190
3191 static int
db_IncObjectComponentCount(DBobject * obj)3192 db_IncObjectComponentCount(DBobject *obj)
3193 {
3194 int new_maxcomps = 0;
3195 char **new_comp_names = 0;
3196 char **new_pdb_names = 0;
3197
3198 obj->ncomponents++;
3199 if (obj->ncomponents < obj->maxcomponents)
3200 return 1;
3201
3202 new_maxcomps = obj->maxcomponents * 1.5 + 1; /* golden rule + 1 */
3203 new_comp_names = REALLOC_N(obj->comp_names, char *, new_maxcomps);
3204 if (!new_comp_names)
3205 {
3206 db_perror(0, E_NOMEM, "db_IncObjectComponentCount");
3207 return 0;
3208 }
3209 new_pdb_names = REALLOC_N(obj->pdb_names, char *, new_maxcomps);
3210 if (!new_pdb_names)
3211 {
3212 FREE(new_comp_names);
3213 db_perror(0, E_NOMEM, "db_IncObjectComponentCount");
3214 return 0;
3215 }
3216
3217 obj->maxcomponents = new_maxcomps;
3218 obj->comp_names = new_comp_names;
3219 obj->pdb_names = new_pdb_names;
3220
3221 return 1;
3222 }
3223
3224 /*----------------------------------------------------------------------
3225 * Routine DBMakeObject
3226 *
3227 * Purpose
3228 *
3229 * Allocate an object of the requested length and initialize it.
3230 *
3231 * Programmer
3232 *
3233 * Jeffery W. Long, NSSD-B
3234 *
3235 * Modified
3236 * Robb Matzke, Tue Nov 8 11:41:23 PST 1994
3237 * Added error mechanism
3238 *
3239 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
3240 * Added a check for variable name validity.
3241 *--------------------------------------------------------------------*/
3242 PUBLIC DBobject *
DBMakeObject(const char * name,int type,int maxcomps)3243 DBMakeObject(const char *name, int type, int maxcomps)
3244 {
3245 DBobject *object = NULL;
3246
3247 API_BEGIN("DBMakeObject", DBobject *, NULL) {
3248
3249 if (!name || !*name)
3250 API_ERROR("object name", E_BADARGS);
3251 if (db_VariableNameValid(name) == 0)
3252 API_ERROR("object name", E_INVALIDNAME);
3253 if (NULL == (object = ALLOC(DBobject)))
3254 API_ERROR(NULL, E_NOMEM);
3255
3256 if (maxcomps <= 0) maxcomps = 30;
3257 object->name = STRDUP(name);
3258 object->type = STRDUP(DBGetObjtypeName(type));
3259 object->comp_names = ALLOC_N(char *, maxcomps);
3260 object->pdb_names = ALLOC_N(char *, maxcomps);
3261
3262 if (!object->name || !object->type ||
3263 !object->comp_names || !object->pdb_names)
3264 {
3265 FREE(object->name);
3266 FREE(object->type);
3267 FREE(object->comp_names);
3268 FREE(object->pdb_names);
3269 API_ERROR(NULL, E_NOMEM);
3270 }
3271
3272 object->ncomponents = 0;
3273 object->maxcomponents = maxcomps;
3274
3275 API_RETURN(object);
3276 }
3277 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
3278 }
3279
3280 /*----------------------------------------------------------------------
3281 * Routine DBFreeObject
3282 *
3283 * Purpose
3284 *
3285 * Release the storage associated with the given object list.
3286 *
3287 * Programmer
3288 *
3289 * Jeffery W. Long, NSSD-B
3290 *
3291 * Returns
3292 *
3293 * Returns OKAY on success, OOPS on failure.
3294 *
3295 * Modified
3296 * Robb Matzke, Thu Nov 10 17:28:39 EST 1994
3297 * Added error mechanism.
3298 *
3299 * Robb Matzke, Fri Dec 2 13:14:18 PST 1994
3300 * Removed all references to SCORE memory management.
3301 *
3302 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
3303 * Made the error messages a little better.
3304 *--------------------------------------------------------------------*/
3305 PUBLIC int
DBFreeObject(DBobject * object)3306 DBFreeObject(DBobject *object)
3307 {
3308 int i;
3309
3310 API_BEGIN("DBFreeObject", int, -1) {
3311
3312 if (!object)
3313 API_ERROR("object pointer", E_BADARGS);
3314 if (object->ncomponents < 0) {
3315 API_ERROR("object ncomponents", E_BADARGS);
3316 }
3317
3318 for (i = 0; i < object->ncomponents; i++) {
3319 FREE(object->comp_names[i]);
3320 FREE(object->pdb_names[i]);
3321 }
3322 for (i = 0; i < DB_MAX_H5_OBJ_VALS; i++) {
3323 FREE(object->h5_names[i]);
3324 }
3325
3326 FREE(object->comp_names);
3327 FREE(object->pdb_names);
3328 FREE(object->name);
3329 FREE(object->type);
3330 FREE(object);
3331 }
3332 API_END;
3333
3334 return(0); /* Always succeeds by the time we get here */
3335 }
3336
3337 /*----------------------------------------------------------------------
3338 * Routine DBClearObject
3339 *
3340 * Purpose
3341 *
3342 * Remove all components from the given object and reset counters.
3343 *
3344 * Programmer
3345 *
3346 * Jeffery W. Long, NSSD-B
3347 *
3348 * Returns
3349 *
3350 * Returns OKAY on success, OOPS on failure.
3351 *
3352 * Modified
3353 * Robb Matzke, Tue Nov 8 07:46:29 PST 1994
3354 * Added error mechanism
3355 *
3356 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
3357 * Made the error messages a little better.
3358 *--------------------------------------------------------------------*/
3359 PUBLIC int
DBClearObject(DBobject * object)3360 DBClearObject(DBobject *object)
3361 {
3362 int i;
3363
3364 API_BEGIN("DBClearObject", int, -1) {
3365 if (!object)
3366 API_ERROR("object pointer", E_BADARGS);
3367 if (object->ncomponents < 0) {
3368 API_ERROR("object ncomponents", E_BADARGS);
3369 }
3370
3371 /* Reset values, but do not free */
3372 for (i = 0; i < object->maxcomponents; i++) {
3373 object->comp_names[i] = NULL;
3374 object->pdb_names[i] = NULL;
3375 }
3376
3377 object->name = NULL;
3378 object->type = NULL;
3379 object->ncomponents = 0;
3380 }
3381 API_END;
3382
3383 return(0);
3384 }
3385
3386 /*----------------------------------------------------------------------
3387 * Routine DBAddVarComponent
3388 *
3389 * Purpose
3390 *
3391 * Add a variable component to the given object structure.
3392 *
3393 * Programmer
3394 *
3395 * Jeffery W. Long, NSSD-B
3396 *
3397 * Returns
3398 *
3399 * Returns OKAY on success, OOPS on failure.
3400 *
3401 * Modified
3402 * Robb Matzke, Tue Nov 8 07:43:38 PST 1994
3403 * Added error mechanism
3404 *
3405 * Robb Matzke, Fri Dec 2 13:14:46 PST 1994
3406 * Removed all references to SCORE memory management.
3407 *
3408 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
3409 * Added a check for variable name validity.
3410 *
3411 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
3412 * Made the error messages a little better. Correct spelling.
3413 *--------------------------------------------------------------------*/
3414 PUBLIC int
DBAddVarComponent(DBobject * object,const char * compname,const char * pdbname)3415 DBAddVarComponent(DBobject *object, const char *compname, const char *pdbname)
3416 {
3417 API_BEGIN("DBAddVarComponent", int, -1) {
3418 if (!object)
3419 API_ERROR("object pointer", E_BADARGS);
3420 if (!compname || !*compname)
3421 API_ERROR("component name", E_BADARGS);
3422 if (db_VariableNameValid(compname) == 0)
3423 API_ERROR("component name", E_INVALIDNAME);
3424 if (!pdbname || !*pdbname)
3425 API_ERROR("pdb name", E_BADARGS);
3426 if (object->ncomponents >= object->maxcomponents) {
3427 API_ERROR("object ncomponents", E_BADARGS);
3428 }
3429
3430 if (NULL == (object->comp_names[object->ncomponents] =
3431 STRDUP(compname)) ||
3432 NULL == (object->pdb_names[object->ncomponents] =
3433 STRDUP(pdbname))) {
3434 FREE(object->comp_names[object->ncomponents]);
3435 API_ERROR(NULL, E_NOMEM);
3436 }
3437
3438 if (!db_IncObjectComponentCount(object))
3439 API_ERROR(NULL, E_NOMEM);
3440
3441 }
3442 API_END;
3443
3444 return(0);
3445 }
3446
3447 /*----------------------------------------------------------------------
3448 * Routine DBAddIntComponent
3449 *
3450 * Purpose
3451 *
3452 * Add an integer literal component to the given object structure.
3453 *
3454 * Programmer
3455 *
3456 * Jeffery W. Long, NSSD-B
3457 *
3458 * Returns
3459 *
3460 * Returns OKAY on success, OOPS on failure.
3461 *
3462 * Modifications
3463 * Robb Matzke, Tue Nov 8 07:06:11 PST 1994
3464 * Added error mechanism. Returns 0 on success, -1 on failure.
3465 *
3466 * Robb Matzke, Fri Dec 2 13:15:06 PST 1994
3467 * Removed all references to SCORE memory management.
3468 *
3469 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
3470 * Added a check for variable name validity.
3471 *
3472 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
3473 * Made the error messages a little better.
3474 *--------------------------------------------------------------------*/
3475 PUBLIC int
DBAddIntComponent(DBobject * object,const char * compname,int ii)3476 DBAddIntComponent(DBobject *object, const char *compname, int ii)
3477 {
3478 char tmp[256];
3479
3480 API_BEGIN("DBAddIntComponent", int, -1) {
3481 if (!object)
3482 API_ERROR("object pointer", E_BADARGS);
3483 if (!compname || !*compname)
3484 API_ERROR("component name", E_BADARGS);
3485 if (db_VariableNameValid(compname) == 0)
3486 API_ERROR("component name", E_INVALIDNAME);
3487 if (object->ncomponents >= object->maxcomponents) {
3488 API_ERROR("object ncomponents", E_BADARGS);
3489 }
3490
3491 sprintf(tmp, "'<i>%d'", ii);
3492
3493 if (NULL == (object->comp_names[object->ncomponents] =
3494 STRDUP(compname)) ||
3495 NULL == (object->pdb_names[object->ncomponents] =
3496 STRDUP(tmp))) {
3497 FREE(object->comp_names[object->ncomponents]);
3498 API_ERROR(NULL, E_NOMEM);
3499 }
3500
3501 if (!db_IncObjectComponentCount(object))
3502 API_ERROR(NULL, E_NOMEM);
3503
3504 }
3505 API_END;
3506
3507 return(0);
3508 }
3509
3510 /*----------------------------------------------------------------------
3511 * Routine DBAddFltComponent
3512 *
3513 * Purpose
3514 *
3515 * Add a floating point literal component to the given object
3516 * structure.
3517 *
3518 * Programmer
3519 *
3520 * Jeffery W. Long, NSSD-B
3521 *
3522 * Returns
3523 *
3524 * Returns OKAY on success, OOPS on failure.
3525 *
3526 * Modified:
3527 * Robb Matzke, Tue Nov 8 07:04:15 PST 1994
3528 * Added error mechanism. Return -1 on failure, 0 on success.
3529 *
3530 * Robb Matzke, Fri Dec 2 13:15:28 PST 1994
3531 * Removed all references to SCORE memory management.
3532 *
3533 * Eric Brugger, Tue Feb 7 09:06:58 PST 1995
3534 * I modified the argument declarations to reflect argument promotions.
3535 *
3536 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
3537 * Added a check for variable name validity.
3538 *
3539 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
3540 * Made the error messages a little better.
3541 *--------------------------------------------------------------------*/
3542 PUBLIC int
DBAddFltComponent(DBobject * object,const char * compname,double ff)3543 DBAddFltComponent(DBobject *object, const char *compname, double ff)
3544 {
3545 char tmp[256];
3546
3547 API_BEGIN("DBAddFltComponent", int, -1) {
3548 if (!object)
3549 API_ERROR("object pointer", E_BADARGS);
3550 if (!compname || !*compname)
3551 API_ERROR("component name", E_BADARGS);
3552 if (db_VariableNameValid(compname) == 0)
3553 API_ERROR("component name", E_INVALIDNAME);
3554 if (object->ncomponents >= object->maxcomponents) {
3555 API_ERROR("object ncomponents", E_BADARGS);
3556 }
3557
3558 sprintf(tmp, "'<f>%g'", ff);
3559
3560 if (NULL == (object->comp_names[object->ncomponents] =
3561 STRDUP(compname)) ||
3562 NULL == (object->pdb_names[object->ncomponents] =
3563 STRDUP(tmp))) {
3564 FREE(object->comp_names[object->ncomponents]);
3565 API_ERROR(NULL, E_NOMEM);
3566 }
3567 if (!db_IncObjectComponentCount(object))
3568 API_ERROR(NULL, E_NOMEM);
3569 }
3570 API_END;
3571
3572 return(0);
3573 }
3574
3575 /*----------------------------------------------------------------------
3576 * Routine DBAddDblComponent
3577 *
3578 * Purpose
3579 *
3580 * Add a double precision floating point literal component to
3581 * the given object structure.
3582 *
3583 * Programmer
3584 *
3585 * Brad Whitlock, Thu Jan 20 09:43:13 PDT 2000
3586 *
3587 * Returns
3588 *
3589 * Returns OKAY on success, OOPS on failure.
3590 *
3591 * Modified:
3592 *
3593 *--------------------------------------------------------------------*/
3594 PUBLIC int
DBAddDblComponent(DBobject * object,const char * compname,double ff)3595 DBAddDblComponent(DBobject *object, const char *compname, double ff)
3596 {
3597 char tmp[256];
3598
3599 API_BEGIN("DBAddDblComponent", int, -1) {
3600 if (!object)
3601 API_ERROR("object pointer", E_BADARGS);
3602 if (!compname || !*compname)
3603 API_ERROR("component name", E_BADARGS);
3604 if (db_VariableNameValid(compname) == 0)
3605 API_ERROR("component name", E_INVALIDNAME);
3606 if (object->ncomponents >= object->maxcomponents) {
3607 API_ERROR("object ncomponents", E_BADARGS);
3608 }
3609
3610 sprintf(tmp, "'<d>%.30g'", ff);
3611
3612 if (NULL == (object->comp_names[object->ncomponents] =
3613 STRDUP(compname)) ||
3614 NULL == (object->pdb_names[object->ncomponents] =
3615 STRDUP(tmp))) {
3616 FREE(object->comp_names[object->ncomponents]);
3617 API_ERROR(NULL, E_NOMEM);
3618 }
3619 if (!db_IncObjectComponentCount(object))
3620 API_ERROR(NULL, E_NOMEM);
3621 }
3622 API_END;
3623
3624 return(0);
3625 }
3626
3627 /*----------------------------------------------------------------------
3628 * Routine DBAddStrComponent
3629 *
3630 * Purpose
3631 *
3632 * Add a string literal component to the given object structure.
3633 *
3634 * Programmer
3635 *
3636 * Jeffery W. Long, NSSD-B
3637 *
3638 * Returns
3639 *
3640 * Returns OKAY on success, OOPS on failure.
3641 *
3642 * Modified
3643 * Robb Matzke, Tue Nov 8 07:08:33 PST 1994
3644 * Added error mechanism. Return 0 on success, -1 on failure.
3645 *
3646 * Robb Matzke, Fri Dec 2 13:15:49 PST 1994
3647 * Removed all references to SCORE memory management.
3648 *
3649 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
3650 * Added a check for variable name validity.
3651 *
3652 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
3653 * Made the error messages a little better.
3654 *--------------------------------------------------------------------*/
3655 PUBLIC int
DBAddStrComponent(DBobject * object,const char * compname,const char * ss)3656 DBAddStrComponent(DBobject *object, const char *compname, const char *ss)
3657 {
3658 char tmp[256];
3659
3660 API_BEGIN("DBAddStrComponent", int, -1) {
3661 if (!object)
3662 API_ERROR("object pointer", E_BADARGS);
3663 if (!compname || !*compname)
3664 API_ERROR("component name", E_BADARGS);
3665 if (db_VariableNameValid(compname) == 0)
3666 API_ERROR("component name", E_INVALIDNAME);
3667 if (object->ncomponents >= object->maxcomponents) {
3668 API_ERROR("object ncomponents", E_BADARGS);
3669 }
3670 if (!ss)
3671 {
3672 if (!SILO_Globals.allowEmptyObjects)
3673 API_ERROR("string literal component", E_BADARGS);
3674 sprintf(tmp, "'<s>null'");
3675 }
3676 else
3677 sprintf(tmp, "'<s>%s'", ss);
3678
3679 if (NULL == (object->comp_names[object->ncomponents] =
3680 STRDUP(compname)) ||
3681 NULL == (object->pdb_names[object->ncomponents] =
3682 STRDUP(tmp))) {
3683 FREE(object->comp_names[object->ncomponents]);
3684 API_ERROR(NULL, E_NOMEM);
3685 }
3686 if (!db_IncObjectComponentCount(object))
3687 API_ERROR(NULL, E_NOMEM);
3688 }
3689 API_END;
3690
3691 return(0);
3692 }
3693
3694 /*-------------------------------------------------------------------------
3695 * Function: DBShowErrors
3696 *
3697 * Purpose: Set the method by which errors are displayed. The
3698 * `level' parameter is one of the following:
3699 *
3700 * DB_ALL -- Show all errors, beginning with the
3701 * routine that first detected the error
3702 * and continuing up the call stack to
3703 * the application.
3704 *
3705 * DB_ABORT -- Same as DB_ALL except abort() is called
3706 * after the error message is printed.
3707 *
3708 * DB_TOP -- (default) Only the top-level API functions
3709 * issue error messages.
3710 *
3711 * DB_NONE -- The library does not handle error messages.
3712 * The application is responsible for
3713 * checking the API return values and
3714 * handling the error.
3715 *
3716 * DB_SUSPEND -- This is used internally to temporarily
3717 * suspend the issuance of error messages
3718 * by changing the error level to DB_NONE.
3719 *
3720 * DB_RESTORE -- This is used internally to restore the
3721 * previous error level after a DB_SUSPEND.
3722 *
3723 * The `func' parameter can point to an application-level
3724 * error handling function that will be passed a string that
3725 * is part of the error message (similar to the argument for
3726 * perror()). If the function pointer is null, then
3727 * the library will issue error messages to the standard
3728 * error stream.
3729 *
3730 * The error text and erring function name can
3731 * be obtained by calling DBErrString() or DBErrFunc().
3732 *
3733 * Return: void
3734 *
3735 * Programmer: matzke@viper
3736 * Mon Nov 7 09:58:43 PST 1994
3737 *
3738 * Modifications:
3739 * Robb Matzke, Mon Dec 12 14:25:04 EST 1994
3740 * Added DB_SUSPEND and DB_RESUME in order to get
3741 * db_unk_Open to work properly [the Open callback for
3742 * the SILO-Unknown driver].
3743 *
3744 * Eric Brugger, Tue Feb 7 09:06:58 PST 1995
3745 * I modified the function declaration and changed the default error
3746 * reporting level to DB_NONE.
3747 *
3748 * Eric Brugger, Wed Mar 1 17:07:39 PST 1995
3749 * I shrouded the prototypes for non-ansi compilers.
3750 *
3751 * Hank Childs, Thu Mar 2 13:34:35 PST 2000
3752 * Add check to ensure that nested DBShowErrors to suspend error
3753 * messages would work correctly.
3754 *
3755 *-------------------------------------------------------------------------*/
3756 PUBLIC void
DBShowErrors(int level,void (* func)(char *))3757 DBShowErrors(int level, void(*func)(char*))
3758 {
3759 static int old_level = DB_NONE;
3760 static int old_level_drvr = DB_NONE;
3761 static int nested_suspend = 0;
3762
3763 SILO_Globals._db_err_level_drvr = DB_NONE;
3764 if (level == DB_ALL_AND_DRVR)
3765 {
3766 level = DB_ALL;
3767 SILO_Globals._db_err_level_drvr = DB_ALL;
3768 }
3769
3770 switch (level) {
3771 case DB_SUSPEND:
3772 if (nested_suspend++ == 0)
3773 {
3774 old_level = SILO_Globals._db_err_level;
3775 old_level_drvr = SILO_Globals._db_err_level_drvr;
3776 }
3777 SILO_Globals._db_err_level = DB_NONE;
3778 SILO_Globals._db_err_level_drvr = DB_NONE;
3779 break;
3780 case DB_RESUME:
3781 if (--nested_suspend == 0)
3782 {
3783 SILO_Globals._db_err_level = old_level;
3784 SILO_Globals._db_err_level_drvr = old_level_drvr;
3785 }
3786 break;
3787 default:
3788 SILO_Globals._db_err_level = level;
3789 SILO_Globals._db_err_func = func;
3790 break;
3791 }
3792 }
3793
3794 /*-------------------------------------------------------------------------
3795 * Function: DBErrString
3796 *
3797 * Purpose: Return the error message of the last error.
3798 *
3799 * Return: Success: ptr to static error message
3800 *
3801 * Failure: ptr to static message for db_errno=0
3802 *
3803 * Programmer: robb@cloud
3804 * Tue Feb 21 08:23:48 EST 1995
3805 *
3806 * Modifications:
3807 *-------------------------------------------------------------------------*/
3808 PUBLIC char const *
DBErrString(void)3809 DBErrString(void)
3810 {
3811 static char s[128];
3812
3813 if (db_errno < 0 || db_errno >= NELMTS(_db_err_list)) {
3814 sprintf(s, "Error %d", db_errno);
3815 return s;
3816 }
3817
3818 return _db_err_list[db_errno];
3819 }
3820
3821 PUBLIC int
DBErrno(void)3822 DBErrno(void)
3823 {
3824 return db_errno;
3825 }
3826
3827 PUBLIC char const *
DBErrFuncname(void)3828 DBErrFuncname(void)
3829 {
3830 return db_errfunc;
3831 }
3832
3833 PUBLIC DBErrFunc_t
DBErrfunc(void)3834 DBErrfunc(void)
3835 {
3836 return SILO_Globals._db_err_func;
3837 }
3838
3839 PUBLIC int
DBErrlvl(void)3840 DBErrlvl(void)
3841 {
3842 return SILO_Globals._db_err_level;
3843 }
3844
3845 /*-------------------------------------------------------------------------
3846 * Function: db_parse_version_digits_from_string
3847 *
3848 * str: version string
3849 * sep: separator character (typically '.')
3850 * digits: array of digits to return
3851 * ndigits: size of digits array
3852 *
3853 * returns 0 on successful conversion, non-zero on failure
3854 *-----------------------------------------------------------------------*/
3855 static int
db_parse_version_digits_from_string(char const * str,char sep,int * digits,int ndigits)3856 db_parse_version_digits_from_string(char const *str, char sep, int *digits, int ndigits)
3857 {
3858 int i, nseps, non_digits, retval = 0;
3859 char *p, *ostr;
3860
3861 if (!str || !*str)
3862 return 1;
3863
3864 ostr = strdup(str);
3865 p = ostr;
3866
3867 /* Examine string for seperator chars and non-digits */
3868 nseps = 0;
3869 non_digits = 0;
3870 while (*p)
3871 {
3872 if (*p == sep)
3873 {
3874 *p = '\0';
3875 nseps++;
3876 }
3877 else if (!strncmp(p, "-pre", 4))
3878 {
3879 *(p+0) = '\0';
3880 *(p+1) = '0';
3881 *(p+2) = '0';
3882 *(p+3) = '0';
3883 nseps++;
3884 p += 3;
3885 }
3886 else if (*p < '0' || *p > '9')
3887 {
3888 non_digits = 1;
3889 }
3890 p++;
3891 }
3892 nseps++;
3893
3894 /* Make a second pass over string converting all the digits */
3895 if (!non_digits)
3896 {
3897 p = ostr;
3898 errno = 0;
3899 for (i = 0; i < ndigits; i++)
3900 digits[i] = 0;
3901 for (i = 0; i < nseps && ndigits && errno == 0; i++, ndigits--)
3902 {
3903 digits[i] = strtol(p, 0, 10);
3904 while (*p != '\0') p++;
3905 p++;
3906 }
3907 if (errno)
3908 retval = 1;
3909 }
3910 else
3911 {
3912 retval = 1;
3913 }
3914
3915 free(ostr);
3916
3917 return retval;
3918 }
3919
3920 static int
db_compare_version_digits(int const * a_digits,int const * b_digits,int ndigits)3921 db_compare_version_digits(int const *a_digits, int const *b_digits, int ndigits)
3922 {
3923 int i;
3924 for (i = 0; i < ndigits; i++)
3925 {
3926 if (a_digits[i] < b_digits[i])
3927 return -1;
3928 else if (a_digits[i] > b_digits[i])
3929 return 1;
3930 }
3931 return 0;
3932 }
3933
3934 /*-------------------------------------------------------------------------
3935 * Function: DBVersion
3936 *
3937 * Purpose: Return the version number of the library as a string.
3938 *
3939 * Returns: ptr to version number
3940 *
3941 * Programmer: Hank Childs
3942 * Tue Oct 17 14:08:45 PDT 2000
3943 *
3944 * Modifications:
3945 *
3946 * Mark C. Miller, Tue Oct 24 12:39:31 PDT 2006
3947 * Changed to use SILO_VSTRING
3948 *-------------------------------------------------------------------------*/
3949 PUBLIC char const *
DBVersion(void)3950 DBVersion(void)
3951 {
3952 static char version[256];
3953 strcpy(version, SILO_VSTRING);
3954
3955 return version;
3956 }
3957
3958 PUBLIC int
DBVersionDigits(int * maj,int * min,int * pat,int * pre)3959 DBVersionDigits(int *maj, int *min, int *pat, int *pre)
3960 {
3961 int digits[4] = {0,0,0,0};
3962
3963 if (!db_parse_version_digits_from_string(DBVersion(), '.',
3964 digits, sizeof(digits)/sizeof(digits[0])))
3965 {
3966 if (maj) *maj = digits[0];
3967 if (min) *min = digits[1];
3968 if (pat) *pat = digits[2];
3969 if (pre) *pre = digits[3];
3970 return 0;
3971 }
3972 return -1;
3973 }
3974
3975 /*-------------------------------------------------------------------------
3976 * Function: DBVersionGE
3977 *
3978 * Purpose: Return whether or not the version of the library is greater
3979 * than or equal to the version specified by Maj, Min, Pat.
3980 * This is a run-time equiv. of the SILO_VERSION_GE macro.
3981 *
3982 * Returns: integer indicating if true (1) or false (0)
3983 *
3984 * Programmer: Mark C. Miller, Mon Jan 12 20:59:30 PST 2009
3985 *-------------------------------------------------------------------------*/
3986 PUBLIC int
DBVersionGE(int Maj,int Min,int Pat)3987 DBVersionGE(int Maj, int Min, int Pat)
3988 {
3989 int a_digits[3] = {SILO_VERS_MAJ, SILO_VERS_MIN, SILO_VERS_PAT};
3990 int b_digits[3] = {Maj<0?0:Maj, Min<0?0:Min, Pat<0?0:Pat};
3991 return db_compare_version_digits(a_digits, b_digits, 3) >= 0;
3992 }
3993
3994 PUBLIC int
DBVersionGEFileVersion(const DBfile * dbfile)3995 DBVersionGEFileVersion(const DBfile *dbfile)
3996 {
3997 int a_digits[3];
3998 int b_digits[3] = {4, 5, 0}; /* earliest version we have version info in file */
3999 DBVersionDigits(&a_digits[0], &a_digits[1], &a_digits[2], 0);
4000 DBFileVersionDigits(dbfile, &b_digits[0], &b_digits[1], &b_digits[2], 0);
4001 return db_compare_version_digits(a_digits, b_digits, 3) >= 0;
4002 }
4003
4004 /*-------------------------------------------------------------------------
4005 * Function: DBFileVersion
4006 *
4007 * Purpose: Return the version number of the library that created the
4008 * given file as a string.
4009 *
4010 * Returns: ptr to version number
4011 *
4012 * Programmer: Mark C. Miller, Mon Jan 12 20:59:30 PST 2009
4013 *-------------------------------------------------------------------------*/
4014 PUBLIC char const *
DBFileVersion(const DBfile * dbfile)4015 DBFileVersion(const DBfile *dbfile)
4016 {
4017 static char version[256];
4018 if (dbfile->pub.file_lib_version)
4019 strcpy(version, dbfile->pub.file_lib_version);
4020 else
4021 strcpy(version, "unknown; 4.5 or older");
4022 return version;
4023 }
4024
4025 PUBLIC int
DBFileVersionDigits(const DBfile * dbfile,int * maj,int * min,int * pat,int * pre)4026 DBFileVersionDigits(const DBfile *dbfile, int *maj, int *min, int *pat, int *pre)
4027 {
4028 int digits[4] = {0,0,0,0};
4029 if (!db_parse_version_digits_from_string(DBFileVersion(dbfile), '.',
4030 digits, sizeof(digits)/sizeof(digits[0])))
4031 {
4032 if (maj) *maj = digits[0];
4033 if (min) *min = digits[1];
4034 if (pat) *pat = digits[2];
4035 if (pre) *pre = digits[3];
4036 return 0;
4037 }
4038 return -1;
4039 }
4040
4041 /*-------------------------------------------------------------------------
4042 * Function: DBFileVersionGE
4043 *
4044 * Purpose: Return whether or not the given file was created with a
4045 * version of the library greater than or equal to the
4046 * version specified by Maj, Min, Pat
4047 *
4048 * Returns: 1 if file version is greather than or equal to Maj/Min/Pat
4049 * 0 if file version is less than Maj/Min/Pat
4050 * -1 if unable to determine.
4051 *
4052 * Programmer: Mark C. Miller, Mon Jan 12 20:59:30 PST 2009
4053 *-------------------------------------------------------------------------*/
4054 PUBLIC int
DBFileVersionGE(const DBfile * dbfile,int Maj,int Min,int Pat)4055 DBFileVersionGE(const DBfile *dbfile, int Maj, int Min, int Pat)
4056 {
4057 int retval = -1;
4058 int unknown = 0;
4059 int a_digits[3];
4060 int b_digits[3] = {Maj<0?0:Maj, Min<0?0:Min, Pat<0?0:Pat};
4061 char *version = STRDUP(DBFileVersion(dbfile));
4062
4063 if (strncmp(version, "unknown", 7) == 0)
4064 {
4065 /* We started maintaining library version information in the file
4066 in version 4.5.1. So, if it is 'unknown', we can return something
4067 useful ONLY if the version we're comparing against is 4.5.1 or
4068 greater. */
4069 a_digits[0] = 4;
4070 a_digits[1] = 5;
4071 a_digits[2] = 0;
4072 unknown = 1;
4073 }
4074 else
4075 {
4076 if (db_parse_version_digits_from_string(version, '.',
4077 a_digits, sizeof(a_digits)/sizeof(a_digits[0])))
4078 {
4079 free(version);
4080 return -1;
4081 }
4082 }
4083
4084 free(version);
4085
4086 retval = db_compare_version_digits(a_digits, b_digits, 3) >= 0;
4087
4088 if (unknown)
4089 {
4090 if (retval)
4091 retval = -1;
4092 }
4093
4094 return retval;
4095 }
4096
4097 /*-------------------------------------------------------------------------
4098 * Function: DBOpen
4099 *
4100 * Purpose: Open a data file.
4101 *
4102 * Return: Success: pointer to new file descriptor
4103 *
4104 * Failure: NULL
4105 *
4106 * Programmer: matzke@viper
4107 * Mon Nov 7 10:25:08 PST 1994
4108 *
4109 * Modifications:
4110 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
4111 * I replaced API_END with API_END_NOPOP.
4112 *
4113 * Robb Matzke, Tue Feb 28 10:51:19 EST 1995
4114 * When a file is opened, it is given a unique ID number wrt all other
4115 * open files. The ID is a small integer [0..DB_NFILES-1].
4116 *
4117 * Robb Matzke, Tue Feb 28 11:38:08 EST 1995
4118 * For each registered filter, call the non-null `init' functions for
4119 * every file that is opened.
4120 *
4121 * Sean Ahern, Mon Jan 8 17:38:18 PST 1996
4122 * Added the mode parameter.
4123 *
4124 * Lisa J. Nafziger, Wed Mar 6 10:20:48 PST 1996
4125 * Added code to check for file existence, to check if it is a
4126 * directory and to check for read permission. This allows more
4127 * specific error messages to be returned.
4128 *
4129 * Lisa J. Nafziger, Tue Mar 12 14:15:06 PST 1996
4130 * Modified code to check file attributes so that stat() rather
4131 * than access() is used. The former is POSIX compliant.
4132 *
4133 * Eric Brugger, Tue Jun 17 10:25:57 PDT 1997
4134 * I modified the routine to only check file validity if the type
4135 * is not an SDX connection.
4136 *
4137 * Jeremy Meredith, Fri Jul 23 09:31:14 PDT 1999
4138 * I added error reporting to the result of stat().
4139 *
4140 * Jeremy Meredith, Mon Jul 26 10:39:49 PDT 1999
4141 * Made stat() error reporting POSIX.1 compliant.
4142 *
4143 * Sean Ahern, Wed Jul 5 15:35:48 PDT 2000
4144 * Renamed the function to DBOpenReal. Client code now calls a macro
4145 * called DBOpen.
4146 *
4147 * Mark C. Miller, Wed Feb 2 07:59:53 PST 2005
4148 * Added printing of error message from stat() with strerror
4149 *
4150 * Mark C. Miller, Wed Feb 23 08:51:35 PST 2005
4151 * Added code to reset _db_fstatus slot to 0 if open fails
4152 *
4153 * Thomas R. Treadway, Tue Jun 27 13:59:21 PDT 2006
4154 * Added HAVE_STRERROR wrappers
4155 *
4156 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
4157 * Added code to register the returned file pointer
4158 *
4159 * Mark C. Miller, Mon Jan 12 20:50:41 PST 2009
4160 * Removed DB_SDX conditionally compiled code blocks.
4161 *
4162 * Mark C. Miller, Wed Feb 25 23:50:06 PST 2009
4163 * Moved call to db_isregistered_file to AFTER calls to stat the file
4164 * add changed db_isregistered_file to accept stat struct instead of name.
4165 * Changed call to db_register_file to accpet stat struct.
4166 *
4167 * Mark C. Miller, Fri Feb 12 08:22:41 PST 2010
4168 * Replaced stat/stat64 calls with db_silo_stat. Replaced conditional
4169 * compilation logic for SIZEOF_OFF64_T with db_silo_stat_struct.
4170 *------------------------------------------------------------------------- */
4171 PUBLIC DBfile *
DBOpenReal(const char * name,int type,int mode)4172 DBOpenReal(const char *name, int type, int mode)
4173 {
4174 char ascii[16];
4175 DBfile *dbfile;
4176 int fileid, i;
4177 int origtype = type;
4178 int opts_set_id;
4179 db_silo_stat_t filestate;
4180
4181 API_BEGIN("DBOpen", DBfile *, NULL) {
4182 if (!name)
4183 API_ERROR(NULL, E_NOFILE);
4184
4185 /* deal with extended driver type specifications */
4186 db_DriverTypeAndFileOptionsSetId(origtype, &type, &opts_set_id);
4187
4188 if (type < 0 || type >= DB_NFORMATS) {
4189 sprintf(ascii, "%d", type);
4190 API_ERROR(ascii, E_BADFTYPE);
4191 }
4192 if ((mode != DB_READ) && (mode != DB_APPEND))
4193 {
4194 sprintf(ascii, "%d", mode);
4195 API_ERROR(ascii, E_BADARGS);
4196 }
4197 if (!DBOpenCB[type]) {
4198 sprintf(ascii, "%d", type);
4199 API_ERROR(ascii, E_NOTIMP);
4200 }
4201
4202 /****************************************************/
4203 /* Check to make sure the file exists and has the */
4204 /* correct permissions. */
4205 /****************************************************/
4206 if (db_silo_stat(name, &filestate, type==DB_UNKNOWN?-1:opts_set_id) != 0)
4207 {
4208 if( errno == ENOENT )
4209 {
4210 /********************************/
4211 /* File doesn't exist. */
4212 /********************************/
4213 API_ERROR((char *)name, E_NOFILE);
4214 }
4215 else
4216 {
4217 /********************************/
4218 /* System level error occured. */
4219 /********************************/
4220 printf("stat() failed with error: ");
4221 switch (errno)
4222 {
4223 case EACCES: printf("EACCES\n"); break;
4224 case EBADF: printf("EBADF\n"); break;
4225 case ENAMETOOLONG: printf("ENAMETOOLONG\n"); break;
4226 case ENOTDIR: printf("ENOTDIR\n"); break;
4227 #ifdef EOVERFLOW
4228 case EOVERFLOW:
4229 #ifdef HAVE_STRERROR
4230 printf("EOVERFLOW: \"%s\"\n",
4231 strerror(errno));
4232 #else
4233 printf("EOVERFLOW: errno=%d\n", errno);
4234 #endif
4235 printf("Silo may need to be re-compiled with "
4236 "Large File Support (LFS)\n");
4237 break;
4238 #endif
4239 default:
4240 #ifdef HAVE_STRERROR
4241 printf("\"%s\"\n",
4242 strerror(errno));
4243 #else
4244 printf("errno=%d\n", errno);
4245 #endif
4246 break;
4247 }
4248 API_ERROR((char *)name, E_SYSTEMERR);
4249 }
4250 }
4251
4252 /* Check if file is already opened. If so, none can
4253 have it opened for write, including this new one */
4254 i = db_isregistered_file(0, &filestate);
4255 if (i != -1)
4256 {
4257 if (_db_regstatus[i].w != 0 || mode != DB_READ)
4258 API_ERROR(name, E_CONCURRENT);
4259 }
4260
4261 if( ( filestate.s.st_mode & S_IFDIR ) != 0 )
4262 {
4263 /************************************/
4264 /* File is actually a directory. */
4265 /************************************/
4266 API_ERROR((char *)name, E_FILEISDIR);
4267 }
4268 if( ( filestate.s.st_mode & S_IREAD ) == 0 )
4269 {
4270 /****************************************/
4271 /* File is missing read permissions. */
4272 /****************************************/
4273 API_ERROR((char *)name, E_FILENOREAD);
4274 }
4275 if (DB_READ!=mode && (filestate.s.st_mode & S_IWUSR) == 0)
4276 {
4277 /****************************************/
4278 /* File is open for write and missing write permission. */
4279 /****************************************/
4280 API_ERROR((char *)name, E_FILENOWRITE);
4281 }
4282
4283 if ((fileid = db_get_fileid(DB_ISOPEN)) < 0)
4284 API_ERROR((char *)name, E_MAXOPEN);
4285 if (NULL == (dbfile = (DBOpenCB[type]) (name, mode, opts_set_id)))
4286 {
4287 _db_fstatus[fileid] = 0;
4288 API_RETURN(NULL);
4289 }
4290 dbfile->pub.fileid = fileid;
4291 db_register_file(dbfile, &filestate, mode!=DB_READ);
4292
4293 /*
4294 * Install filters. First, all `init' filters, then the
4295 * specified filters.
4296 */
4297 for (i = 0; i < DB_NFILTERS; i++) {
4298 if (_db_filter[i].name && _db_filter[i].init) {
4299 (void)(_db_filter[i].init) (dbfile, _db_filter[i].name);
4300 }
4301 }
4302 db_filter_install(dbfile);
4303 if (DBInqVarExists(dbfile, SILO_VSTRING_NAME))
4304 dbfile->pub.file_lib_version = (char*)DBGetVar(dbfile, SILO_VSTRING_NAME);
4305
4306 API_RETURN(dbfile);
4307 }
4308 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
4309 }
4310
4311 /*-------------------------------------------------------------------------
4312 * Function: DBCreateReal
4313 *
4314 * Purpose: Create a data file
4315 *
4316 * Return: Success: pointer to file descriptor
4317 *
4318 * Failure: NULL
4319 *
4320 * Programmer: matzke@viper
4321 * Mon Nov 7 10:29:23 PST 1994
4322 *
4323 * Modifications:
4324 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
4325 * I replaced API_END with API_END_NOPOP.
4326 *
4327 * Robb Matzke, Tue Feb 28 10:57:06 EST 1995
4328 * A file ID is assigned to the new file.
4329 *
4330 * Robb Matzke, 15 May 1996
4331 * Removed the unused `statue' auto variable.
4332 *
4333 * Sean Ahern, Wed Jul 5 15:35:48 PDT 2000
4334 * Renamed the function to DBCreateReal. Client code now calls a macro
4335 * called DBCreate.
4336 *
4337 * Mark C. Miller, Wed Feb 23 08:51:35 PST 2005
4338 * Added code to reset _db_fstatus slot to 0 if create fails
4339 *
4340 * Mark C. Miller, Wed Apr 5 10:17:31 PDT 2006
4341 * Added code to output silo library version string to the file
4342 *
4343 * Mark C. Miller, Mon Nov 19 10:45:05 PST 2007
4344 * Added hdf5 driver warning.
4345 *
4346 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
4347 * Added code to register the returned file pointer
4348 *
4349 * Mark C. Miller, Mon Nov 17 19:04:39 PST 2008
4350 * Added code to check to see if name is a directory.
4351 *
4352 * Mark C. Miller, Wed Feb 25 23:52:05 PST 2009
4353 * Moved call to db_isregistered_file to after stat calls. Stat the
4354 * file after its created so we can get information to register it.
4355 *
4356 * Mark C. Miller, Fri Feb 12 08:22:41 PST 2010
4357 * Replaced stat/stat64 calls with db_silo_stat. Replaced conditional
4358 * compilation logic for SIZEOF_OFF64_T with db_silo_stat_struct.
4359 *
4360 * Mark C. Miller, Thu Aug 30 17:41:24 PDT 2012
4361 * Added logic to temporarily disable any compression settings prior
4362 * to writing silo library info and then re-enabling it.
4363 *-------------------------------------------------------------------------*/
4364 PUBLIC DBfile *
DBCreateReal(const char * name,int mode,int target,const char * info,int type)4365 DBCreateReal(const char *name, int mode, int target, const char *info, int type)
4366 {
4367 char ascii[16];
4368 char *tmpcs = 0;
4369 DBfile *dbfile;
4370 int fileid, i, n;
4371 int origtype = type;
4372 int opts_set_id;
4373 db_silo_stat_t filestate;
4374
4375 API_BEGIN("DBCreate", DBfile *, NULL) {
4376 if (!name)
4377 API_ERROR(NULL, E_NOFILE);
4378
4379 /* deal with extended driver type specifications */
4380 db_DriverTypeAndFileOptionsSetId(origtype, &type, &opts_set_id);
4381
4382 if (type < 0 || type >= DB_NFORMATS) {
4383 sprintf(ascii, "%d", type);
4384 API_ERROR(ascii, E_BADFTYPE);
4385 }
4386
4387 if (db_silo_stat(name, &filestate, opts_set_id) == 0) /* Success - File exists */
4388 {
4389 if (mode == DB_NOCLOBBER)
4390 {
4391 API_ERROR((char *)name, E_FEXIST);
4392 }
4393 if ((filestate.s.st_mode & S_IFDIR) != 0)
4394 {
4395 API_ERROR((char *)name, E_FILEISDIR);
4396 }
4397
4398 /* Check if file is already opened. If so, none can
4399 have it opened for write, including this new one */
4400 i = db_isregistered_file(0, &filestate);
4401 if (i != -1)
4402 {
4403 API_ERROR(name, E_CONCURRENT);
4404 }
4405 }
4406
4407 if (!DBCreateCB[type]) {
4408 sprintf(ascii, "%d", type);
4409 if (type == 7)
4410 {
4411 API_ERROR(ascii, E_NOHDF5);
4412 }
4413 else
4414 {
4415 API_ERROR(ascii, E_NOTIMP);
4416 }
4417 }
4418
4419 if ((fileid = db_get_fileid(DB_ISOPEN)) < 0)
4420 API_ERROR((char *)name, E_MAXOPEN);
4421 dbfile = ((DBCreateCB[type]) (name, mode, target, opts_set_id,
4422 info));
4423 if (!dbfile)
4424 {
4425 _db_fstatus[fileid] = 0;
4426 API_RETURN(NULL);
4427 }
4428 dbfile->pub.fileid = fileid;
4429 db_silo_stat(name, &filestate, opts_set_id);
4430 db_register_file(dbfile, &filestate, 1);
4431
4432 /*
4433 * Install filters. First all `init' routines, then the specified
4434 * `open' routines.
4435 */
4436 for (i = 0; i < DB_NFILTERS; i++) {
4437 if (_db_filter[i].name && _db_filter[i].init) {
4438 (void)(_db_filter[i].init) (dbfile, _db_filter[i].name);
4439 }
4440 }
4441 db_filter_install(dbfile);
4442
4443 /* write silo library version information to the file */
4444 /* Temporarily turn off any compression settings and then re-enable */
4445 if (DBGetCompression())
4446 {
4447
4448 n = strlen(DBGetCompression());
4449 tmpcs = ALLOC_N(char,n+1);
4450 strncpy(tmpcs, DBGetCompression(), n);
4451 tmpcs[n] = '\0';
4452 DBSetCompression(0);
4453 }
4454 n = strlen(SILO_VSTRING)+1;
4455 DBWrite(dbfile, SILO_VSTRING_NAME, SILO_VSTRING, &n, 1, DB_CHAR);
4456 dbfile->pub.file_lib_version = STRDUP(SILO_VSTRING);
4457 if (tmpcs)
4458 {
4459 DBSetCompression(tmpcs);
4460 FREE(tmpcs);
4461 }
4462
4463 API_RETURN(dbfile);
4464 }
4465 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
4466 }
4467
4468 /*-------------------------------------------------------------------------
4469 * Function: DBClose
4470 *
4471 * Purpose: Close the specified data file and return NULL.
4472 *
4473 * Return: Success: NULL
4474 *
4475 * Failure: NULL
4476 *
4477 * Programmer: matzke@viper
4478 * Mon Nov 7 10:31:41 PST 1994
4479 *
4480 * Modifications:
4481 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
4482 * I replaced API_END with API_END_NOPOP.
4483 *
4484 * Eric Brugger, Mon Feb 27 15:03:01 PST 1995
4485 * I changed the return value to be an integer instead of a pointer
4486 * to a DBfile.
4487 *
4488 * Robb Matzke, Tue Feb 28 10:57:57 EST 1995
4489 * The file status slot is cleared so it can be reused.
4490 *
4491 * Eric Brugger, Mon Jul 10 07:42:24 PDT 1995
4492 * I moved the reseting of _db_fstatus to before the return statement,
4493 * so that the instruction would get executed.
4494 *
4495 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
4496 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
4497 * Added code to UNregister the given file pointer.
4498 *-------------------------------------------------------------------------*/
4499 PUBLIC int
DBClose(DBfile * dbfile)4500 DBClose(DBfile *dbfile)
4501 {
4502 int id;
4503 int retval;
4504
4505 API_BEGIN2("DBClose", int, -1, api_dummy) {
4506 if (!dbfile)
4507 API_ERROR(NULL, E_NOFILE);
4508 if (NULL == dbfile->pub.close)
4509 API_ERROR(dbfile->pub.name, E_NOTIMP);
4510 id = dbfile->pub.fileid;
4511 if (id >= 0 && id < DB_NFILES)
4512 _db_fstatus[id] = 0;
4513
4514 if (dbfile->pub.file_lib_version)
4515 free(dbfile->pub.file_lib_version);
4516 db_unregister_file(dbfile);
4517 retval = (dbfile->pub.close) (dbfile);
4518 API_RETURN(retval);
4519 }
4520 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
4521 }
4522
4523 /*----------------------------------------------------------------------
4524 * Routine: db_inq_file_has_silo_objects_r
4525 *
4526 * Purpose: Recursive helper func for DBInqFileHasObjects
4527 *
4528 * Programmer: Mark C. Miller, Wed Sep 23 11:34:01 PDT 2009
4529 *
4530 * Modifications:
4531 * Mark C. Miller, Mon Nov 16 10:28:41 PST 2009
4532 * Fixed dir recursion by copying dir-related toc entries. Removed
4533 * misc. vars from count of silo objects.
4534 *--------------------------------------------------------------------*/
4535
4536 PRIVATE int
db_inq_file_has_silo_objects_r(DBfile * f)4537 db_inq_file_has_silo_objects_r(DBfile *f)
4538 {
4539 int i, ndir, retval = 0;
4540 char **dirnames;
4541 DBtoc *toc = DBGetToc(f);
4542
4543 if (!toc)
4544 return -1;
4545
4546 /* save dirnames so we don't loose 'em as we get new tocs */
4547 ndir = toc->ndir;
4548 dirnames = (char **) malloc(ndir * sizeof(char*));
4549 for (i = 0; i < ndir; i++)
4550 dirnames[i] = STRDUP(toc->dir_names[i]);
4551
4552 /* We exclude dirs and misc. vars because a non-Silo file may
4553 * contain them. */
4554 retval = toc->ncurve + toc->ncsgmesh + toc->ncsgvar + toc->ndefvars +
4555 toc->nmultimesh + toc->nmultimeshadj + toc->nmultivar +
4556 toc->nmultimat + toc->nmultimatspecies + toc->nqmesh +
4557 toc->nqvar + toc->nucdmesh + toc->nucdvar + toc->nptmesh +
4558 toc->nptvar + toc->nmat + toc->nmatspecies +
4559 toc->nobj + toc->nmrgtree + toc->ngroupelmap +
4560 toc->nmrgvar + toc->narray;
4561
4562 /* Recurse on directories. */
4563 for (i = 0; i < ndir && retval == 0; i++)
4564 {
4565 DBSetDir(f, dirnames[i]);
4566 retval += db_inq_file_has_silo_objects_r(f);
4567 DBSetDir(f, "..");
4568 }
4569
4570 /* free the dirnames */
4571 for (i = 0; i < ndir; i++)
4572 free(dirnames[i]);
4573 free(dirnames);
4574
4575 return retval;
4576 }
4577
4578 /*-------------------------------------------------------------------------
4579 * Function: DBInqFileHasObjects
4580 *
4581 * Purpose: See if the file contains any silo objects, excluding
4582 * directories in the search.
4583 *
4584 * Return: Success: >0 ==> yes, the file has silo objects.
4585 * ==0 ==> no, the file has no silo objects.
4586 *
4587 * Failure: -1
4588 *
4589 * Programmer: Mark C. Miller, Wed Sep 23 09:42:27 PDT 2009
4590 *
4591 * Modifications:
4592 * Mark C. Miller, Mon Nov 16 10:29:36 PST 2009
4593 * Added logic to test from some well known, tell-tale silo variables.
4594 *-------------------------------------------------------------------------*/
4595
4596 PUBLIC int
DBInqFileHasObjects(DBfile * f)4597 DBInqFileHasObjects(DBfile *f)
4598 {
4599 char cwd[4096];
4600 int retval;
4601
4602 if (f == 0)
4603 return -1;
4604
4605 if (DBInqVarExists(f, "_silolibinfo"))
4606 return 1;
4607 if (DBInqVarExists(f, "_hdf5libinfo"))
4608 return 1;
4609
4610 DBGetDir(f, cwd);
4611 retval = db_inq_file_has_silo_objects_r(f);
4612 DBSetDir(f, cwd);
4613
4614 return retval;
4615 }
4616
4617 /*-------------------------------------------------------------------------
4618 * Function: DBInqFileReal
4619 *
4620 * Purpose: Determines if the filename is a Silo file.
4621 *
4622 * Return: 0 if filename is not a Silo file,
4623 * >0 if filename is a Silo file,
4624 * <0 if an error occurred.
4625 *
4626 * Programmer: Hank Childs
4627 * Tue Feb 29 16:24:01 PST 2000
4628 *
4629 * Modifications:
4630 * Sean Ahern, Wed Jul 5 15:35:48 PDT 2000
4631 * Renamed the function to DBInqFileReal. Client code now calls a macro
4632 * called DBInqFile.
4633 *
4634 * Mark C. Miller, Wed Sep 23 11:48:19 PDT 2009
4635 * Added logic to confirm that indeed the successfully opened file has
4636 * some silo objects in it.
4637 *-------------------------------------------------------------------------*/
4638 PUBLIC int
DBInqFileReal(const char * filename)4639 DBInqFileReal(const char *filename)
4640 {
4641 DBfile *dbfile = NULL;
4642 int hasobjects = -1;
4643
4644 API_BEGIN("DBInqFile", int, -1) {
4645 if (!filename || ! *filename)
4646 API_ERROR("filename", E_BADARGS);
4647
4648 /*
4649 * Turn the error handling off so user won't see errors,
4650 * won't abort, etc.
4651 */
4652 DBShowErrors(DB_SUSPEND, NULL);
4653
4654 /*
4655 * Must protect this code so that the error handling can be
4656 * restored afterwards.
4657 */
4658 PROTECT {
4659 dbfile = DBOpen(filename, DB_UNKNOWN, DB_READ);
4660 if (dbfile)
4661 hasobjects = DBInqFileHasObjects(dbfile);
4662 } CLEANUP {
4663 CANCEL_UNWIND;
4664 } END_PROTECT;
4665
4666 /*
4667 * Turn the error handling back on.
4668 */
4669 DBShowErrors(DB_RESUME, NULL);
4670
4671 if (dbfile != NULL)
4672 {
4673 DBClose(dbfile);
4674 API_RETURN(hasobjects);
4675 }
4676
4677 API_RETURN(0);
4678 }
4679 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
4680 }
4681
4682 /*----------------------------------------------------------------------
4683 * Routine DBInqVarExists
4684 *
4685 * Purpose
4686 *
4687 * Determine if the given variable object exists in the SILO file.
4688 * Return non-zero if it does and 0 if it doesn't.
4689 *
4690 * Programmer
4691 *
4692 * Sean Ahern, Thu Jul 20 11:53:40 PDT 1995
4693 *
4694 * Modifications
4695 * Mon Aug 28 11:15:21 PDT 1995
4696 * (ahern) Changed the API_BEGIN to API_BEGIN2.
4697 *
4698 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
4699 * Added a check for variable name validity.
4700 *--------------------------------------------------------------------*/
4701 PUBLIC int
DBInqVarExists(DBfile * dbfile,const char * varname)4702 DBInqVarExists(DBfile *dbfile, const char *varname)
4703 {
4704 int retval;
4705
4706 API_BEGIN2("DBInqVarExists", int, 0, varname) {
4707 if (!dbfile)
4708 API_ERROR(NULL, E_NOFILE);
4709 if (!varname || !*varname)
4710 API_ERROR("variable name", E_BADARGS);
4711 if (dbfile->pub.exist == NULL)
4712 API_ERROR(dbfile->pub.name, E_NOTIMP);
4713 retval = (dbfile->pub.exist) (dbfile, varname);
4714 API_RETURN(retval);
4715 }
4716 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
4717 }
4718
4719 /*-------------------------------------------------------------------------
4720 * Function: DBForceSingle
4721 *
4722 * Purpose: If 'status' is non-zero, then any 'datatype'd arrays are
4723 * converted on read from whatever their native datatype is to
4724 * float. A 'datatype'd array is an array that is part of some
4725 * Silo object containing a 'datatype' member which indicates
4726 * the type of data in the array. So, for example, a DBucdvar
4727 * has a 'datatype' member to indicate the type of data in the
4728 * var and mixvar arrays. Such arrays will be converted on read
4729 * if 'status' here is non-zero. However, a DBmaterial object
4730 * is ALWAYS integer data. There is no 'datatype' member for
4731 * such an object and so its data will NEVER be converted to
4732 * float on read regardless of force single status set here.
4733 *
4734 * I believe this function's original intention was to convert
4735 * only double precision arrays to single precision. However,
4736 * the PDB driver was apparently never designed that way and
4737 * the PDB driver's behavior sort of established the defacto
4738 * meaning of force single. So, now, as of Silo version 4.8
4739 * the HDF5 driver obeys it as well. Though, in fact the HDF5
4740 * driver was originally written to support the original
4741 * intention of force single status and it worked in this
4742 * ('buggy') fashion for many years before we started
4743 * encountering real problems with it in VisIt.
4744 *
4745 * Return: Success: 0 if all drivers succeeded or did not
4746 * implement this function.
4747 *
4748 * Failure: -1 if any driver returned failure.
4749 *
4750 * Programmer: matzke@viper
4751 * Tue Jan 10 11:01:24 PST 1995
4752 *
4753 * Modifications:
4754 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
4755 * I replaced API_END with API_END_NOPOP.
4756 *
4757 * Mark C. Miller, Fri Jul 16 19:28:23 PDT 2010
4758 * Updated 'Purpose' above to reflect current understanding of the
4759 * meaning of force single.
4760 *-------------------------------------------------------------------------*/
4761 PUBLIC int
DBForceSingle(int status)4762 DBForceSingle(int status)
4763 {
4764 int i;
4765
4766 API_BEGIN("DBForceSingle", int, -1) {
4767 for (i = 0; i < DB_NFORMATS; i++) {
4768 if (DBFSingleCB[i]) {
4769 if (((DBFSingleCB[i]) (status)) < 0) {
4770 char dname[32];
4771
4772 sprintf(dname, "driver-%d", i);
4773 API_ERROR(dname, E_CALLFAIL);
4774 }
4775 }
4776 }
4777 }
4778 API_END;
4779
4780 return(0);
4781 }
4782
4783 /*----------------------------------------------------------------------
4784 * Routine DBMakeOptlist
4785 *
4786 * Purpose
4787 *
4788 * Allocate an option list of the requested length and initialize it.
4789 *
4790 * Programmer
4791 *
4792 * Jeffery W. Long, NSSD-B
4793 *
4794 * Modified
4795 * Robb Matzke, Tue Nov 8 06:58:04 PST 1994
4796 * Added error mechanism
4797 *--------------------------------------------------------------------*/
4798 PUBLIC DBoptlist *
DBMakeOptlist(int maxopts)4799 DBMakeOptlist(int maxopts)
4800 {
4801 DBoptlist *optlist = NULL;
4802
4803 API_BEGIN("DBMakeOptlist", DBoptlist *, NULL) {
4804 if (maxopts <= 0)
4805 API_ERROR("maxopts", E_BADARGS);
4806 optlist = ALLOC(DBoptlist);
4807 if (!optlist) API_ERROR(NULL, E_NOMEM);
4808 optlist->options = ALLOC_N(int, maxopts);
4809 optlist->values = ALLOC_N(void *, maxopts);
4810
4811 if (!optlist->options || !optlist->values)
4812 {
4813 FREE(optlist->values);
4814 FREE(optlist->options);
4815 FREE(optlist);
4816 API_ERROR(NULL, E_NOMEM);
4817 }
4818
4819 optlist->numopts = 0;
4820 optlist->maxopts = maxopts;
4821
4822 API_RETURN(optlist);
4823 }
4824 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
4825 }
4826
4827 /*----------------------------------------------------------------------
4828 * Routine DBFreeOptlist
4829 *
4830 * Purpose
4831 *
4832 * Release the storage associated with the given optlist list.
4833 *
4834 * Programmer
4835 *
4836 * Jeffery W. Long, NSSD-B
4837 *
4838 * Returns
4839 *
4840 * Returns 0 on success, -1 on failure.
4841 *
4842 * Modified
4843 * Robb Matzke, Tue Nov 8 07:56:34 PST 1994
4844 * Added error mechanism.
4845 *
4846 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
4847 * Made the error messages a little better.
4848 *--------------------------------------------------------------------*/
4849 PUBLIC int
DBFreeOptlist(DBoptlist * optlist)4850 DBFreeOptlist(DBoptlist *optlist)
4851 {
4852 API_BEGIN("DBFreeOptlist", int, -1) {
4853 if (!optlist || optlist->numopts < 0) {
4854 API_ERROR("optlist pointer", E_BADARGS);
4855 }
4856 FREE(optlist->options);
4857 FREE(optlist->values);
4858 FREE(optlist);
4859 }
4860 API_END;
4861
4862 return(0);
4863 }
4864
4865 /*----------------------------------------------------------------------
4866 * Routine DBClearOptlist
4867 *
4868 * Purpose
4869 *
4870 * Remove all options from the given optlist and reset counters.
4871 *
4872 * Programmer
4873 *
4874 * Jeffery W. Long, NSSD-B
4875 *
4876 * Returns
4877 *
4878 * Returns OKAY on success, OOPS on failure.
4879 *
4880 * Modified
4881 * Robb Matzke, Tue Nov 8 07:48:52 PST 1994
4882 * Added error mechanism.
4883 *
4884 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
4885 * Made the error messages a little better.
4886 *--------------------------------------------------------------------*/
4887 PUBLIC int
DBClearOptlist(DBoptlist * optlist)4888 DBClearOptlist(DBoptlist *optlist)
4889 {
4890 int i;
4891
4892 API_BEGIN("DBClearOptlist", int, -1) {
4893 if (!optlist || optlist->numopts < 0) {
4894 API_ERROR("optlist pointer", E_BADARGS);
4895 }
4896
4897 /* Reset values, but do not free */
4898 for (i = 0; i < optlist->maxopts; i++) {
4899 optlist->options[i] = 0;
4900 optlist->values[i] = (void *)NULL;
4901 }
4902
4903 optlist->numopts = 0;
4904 }
4905 API_END;
4906
4907 return(0);
4908 }
4909
4910 /*----------------------------------------------------------------------
4911 * Routine DBAddOption
4912 *
4913 * Purpose
4914 *
4915 * Add an option to the given option list structure.
4916 *
4917 * Programmer
4918 *
4919 * Jeffery W. Long, NSSD-B
4920 *
4921 * Returns
4922 *
4923 * Returns OKAY on success, OOPS on failure.
4924 *
4925 * Modified:
4926 * Robb Matzke, Tue Nov 8 07:00:55 PST 1994
4927 * Added error mechanism. Returns -1 on failure, 0 on success.
4928 *
4929 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
4930 * Made the error messages a little better.
4931 *--------------------------------------------------------------------*/
4932 PUBLIC int
DBAddOption(DBoptlist * optlist,int option,void * value)4933 DBAddOption(DBoptlist *optlist, int option, void *value)
4934 {
4935 API_BEGIN("DBAddOption", int, -1) {
4936 if (!optlist)
4937 API_ERROR("optlist pointer", E_BADARGS);
4938 if (optlist->numopts >= optlist->maxopts)
4939 API_ERROR("optlist nopts", E_BADARGS);
4940
4941 optlist->options[optlist->numopts] = option;
4942 optlist->values[optlist->numopts] = value;
4943 optlist->numopts++;
4944
4945 if (optlist->numopts >= optlist->maxopts)
4946 {
4947 int new_maxopts = optlist->maxopts * 1.5 + 1; /* golden rule + 1 */
4948 int *new_options = REALLOC_N(optlist->options, int, new_maxopts);
4949 void **new_values = REALLOC_N(optlist->values, void*, new_maxopts);
4950
4951 if (!new_options || !new_values)
4952 {
4953 FREE(new_options);
4954 FREE(new_values);
4955 API_ERROR(0, E_NOMEM);
4956 }
4957
4958 optlist->maxopts = new_maxopts;
4959 optlist->options = new_options;
4960 optlist->values = new_values;
4961 }
4962
4963 }
4964 API_END;
4965
4966 return(0);
4967 }
4968
4969 /*----------------------------------------------------------------------
4970 * Routine DBClearOption
4971 *
4972 * Purpose
4973 *
4974 * Remove a given option from the given optlist and re-order
4975 * the remaining options.
4976 *
4977 * Programmer
4978 *
4979 * Mark C. Miller, August 18, 2005
4980 *
4981 *--------------------------------------------------------------------*/
4982 PUBLIC int
DBClearOption(DBoptlist * optlist,int option)4983 DBClearOption(DBoptlist *optlist, int option)
4984 {
4985 int i, j, foundit=0;
4986
4987 API_BEGIN("DBClearOption", int, -1) {
4988 if (!optlist || optlist->numopts < 0) {
4989 API_ERROR("optlist pointer", E_BADARGS);
4990 }
4991
4992 /* Shift values down in list by one entry */
4993 for (i = 0; i < optlist->numopts; i++) {
4994 if (optlist->options[i] == option) {
4995 foundit = 1;
4996 for (j = i; j < optlist->numopts-1; j++) {
4997 optlist->options[j] = optlist->options[j+1];
4998 optlist->values[j] = optlist->values[j+1];
4999 }
5000 break;
5001 }
5002 }
5003
5004 if (foundit) {
5005 optlist->numopts--;
5006 optlist->options[optlist->numopts] = 0;
5007 optlist->values[optlist->numopts] = 0;
5008 }
5009 }
5010 API_END;
5011
5012 return(0);
5013 }
5014
5015 /*----------------------------------------------------------------------
5016 * Routine DBGetOption
5017 *
5018 * Purpose
5019 *
5020 * Return value set for a given option from the given optlist.
5021 *
5022 * Programmer
5023 *
5024 * Mark C. Miller, August 18, 2005
5025 *
5026 * Modifications:
5027 *
5028 * Mark C. Miller, Wed Jul 14 20:35:50 PDT 2010
5029 * Replaced 'return' with 'API_RETURN'
5030 *
5031 * Mark C. Miller, Tue Aug 10 23:49:51 PDT 2010
5032 * Removed API_BEGIN/END stuff so that function can be handed
5033 * a null optlist and it will behave well.
5034 *--------------------------------------------------------------------*/
5035 PUBLIC void *
DBGetOption(const DBoptlist * optlist,int option)5036 DBGetOption(const DBoptlist *optlist, int option)
5037 {
5038 int i;
5039
5040 if (!optlist) return 0;
5041
5042 /* find the given option in the optlist and return its value */
5043 for (i = 0; i < optlist->numopts; i++)
5044 if (optlist->options[i] == option)
5045 return optlist->values[i];
5046
5047 return 0;
5048 }
5049
5050 /*-------------------------------------------------------------------------
5051 * Function: DBGetToc
5052 *
5053 * Purpose: Return a pointer to table of contents of the file. Note
5054 * that the pointer is the same as the one in the DBfile
5055 * so it should not be modified and may become invalid after
5056 * calling the next silo routine.
5057 *
5058 * Return: Success: Pointer to the table of contents structure.
5059 *
5060 * Failure: NULL
5061 *
5062 * Programmer: matzke@viper
5063 * Mon Nov 7 10:35:47 PST 1994
5064 *
5065 * Modifications:
5066 * Eric Brugger, Fri Jan 27 08:23:43 PST 1995
5067 * I changed the interface and function of the routine.
5068 *
5069 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5070 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5071 *-------------------------------------------------------------------------*/
5072 PUBLIC DBtoc *
DBGetToc(DBfile * dbfile)5073 DBGetToc(DBfile *dbfile)
5074 {
5075 API_BEGIN2("DBGetToc", DBtoc *, NULL, api_dummy) {
5076 if (SILO_Globals.enableGrabDriver == TRUE)
5077 API_ERROR("", E_GRABBED) ;
5078 if (!dbfile)
5079 API_ERROR(NULL, E_NOFILE);
5080
5081 DBNewToc(dbfile);
5082 API_RETURN(dbfile->pub.toc);
5083 }
5084 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5085 }
5086
5087 /*-------------------------------------------------------------------------
5088 * Function: DBInqVarType
5089 *
5090 * Purpose: Return the DBObjectType for a given object name
5091 *
5092 * Return: Success: the ObjectType for the given object
5093 *
5094 * Failure: DB_INVALID_OBJECT
5095 *
5096 * Programmer: Sean Ahern,
5097 * Wed Oct 28 14:46:53 PST 1998
5098 *
5099 * Modifications:
5100 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
5101 * Added a check for variable name validity.
5102 *
5103 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5104 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5105 *-------------------------------------------------------------------------*/
5106 PUBLIC DBObjectType
DBInqVarType(DBfile * dbfile,char const * varname)5107 DBInqVarType(DBfile *dbfile, char const *varname)
5108 {
5109 DBObjectType retval;
5110
5111 API_BEGIN2("DBInqVarType", DBObjectType, DB_INVALID_OBJECT, api_dummy) {
5112 if (SILO_Globals.enableGrabDriver == TRUE)
5113 API_ERROR("", E_GRABBED) ;
5114 if (!dbfile)
5115 API_ERROR(NULL, E_NOFILE);
5116 if (!varname || !*varname)
5117 API_ERROR("variable name", E_BADARGS);
5118 if (!dbfile->pub.inqvartype)
5119 API_ERROR(dbfile->pub.name, E_NOTIMP);
5120
5121 retval = (dbfile->pub.inqvartype) (dbfile, varname);
5122 API_RETURN(retval);
5123 }
5124 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5125 }
5126
5127 /*-------------------------------------------------------------------------
5128 * Function: DBNewToc
5129 *
5130 * Purpose: Used to be called `DBGetToc', this function installs a
5131 * new table of contents in the specified file from that
5132 * file's current working directory. The old table of contents
5133 * is destroyed.
5134 *
5135 * Return: Success: 0
5136 *
5137 * Failure: -1
5138 *
5139 * Programmer: robb@cloud
5140 * Tue Mar 7 10:26:23 EST 1995
5141 *
5142 * Modifications:
5143 * Robb Matzke, 2000-05-23
5144 * If nothing has changed then this function just returns
5145 * success, leaving the original table of contents in place.
5146 * Any function that potentially changes the table of
5147 * contents should call db_FreeToc() on the file handle.
5148 *-------------------------------------------------------------------------*/
5149 PUBLIC int
DBNewToc(DBfile * dbfile)5150 DBNewToc(DBfile *dbfile)
5151 {
5152 int retval;
5153
5154 API_BEGIN("DBNewToc", int, -1) {
5155 if (!dbfile)
5156 API_ERROR(NULL, E_NOFILE);
5157 if (SILO_Globals.enableGrabDriver == TRUE)
5158 API_ERROR("", E_GRABBED) ;
5159 if (!dbfile->pub.newtoc)
5160 API_ERROR(dbfile->pub.name, E_NOTIMP);
5161 if (dbfile->pub.toc)
5162 API_RETURN(0);
5163 retval = (dbfile->pub.newtoc) (dbfile);
5164 API_RETURN(retval);
5165 }
5166 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5167 }
5168
5169 /*
5170 This logic is necessary to support callers accessing standard (e.g. non-DB_USERDEF)
5171 objects via the generic interface to ensure logic for specially handled component
5172 values is consistent with the standard object's DBGetXXX methods.
5173 To ensure a zero for the component in the file means either not-present or
5174 not-set, certain components, especially those for which a zero value is a valid
5175 value for the data producer to use, special handling is required and that logic
5176 is sprinkled about in the DBPutXXX and DBGetXXX methods of the drivers and so
5177 to is it required here. Its a nasty maintenance issue.
5178 */
5179
5180 static int
db_IsComponentNameStandardWithSpecialHandling(char const * compname)5181 db_IsComponentNameStandardWithSpecialHandling(char const *compname)
5182 {
5183 if (!strcmp(compname, "missing_value")) return 1;
5184 if (!strcmp(compname, "topo_dim")) return 1;
5185 if (!strcmp(compname, "repr_block_idx")) return 1;
5186 return 0;
5187 }
5188
5189 /* For use in the DBGetComponent call */
5190 static void
db_AdjustSpeciallyHandledStandardObjectComponentValue(void * val_ptr,int obj_type,char const * comp_name)5191 db_AdjustSpeciallyHandledStandardObjectComponentValue(
5192 void *val_ptr, int obj_type, char const *comp_name)
5193 {
5194 if (!val_ptr || !comp_name) return;
5195
5196 if (!strcmp(comp_name, "missing_value") &&
5197 (obj_type == DB_UCDVAR || obj_type == DB_QUADVAR || obj_type == DB_CURVE ||
5198 obj_type == DB_POINTVAR || obj_type == DB_MULTIVAR))
5199 {
5200 double val_for_mem, val_from_file = *((double*)val_ptr);
5201 db_SetMissingValueForGet(val_for_mem, val_from_file);
5202 *((double*)val_ptr) = val_for_mem;
5203 }
5204 else if (!strcmp(comp_name, "repr_block_idx") &&
5205 (obj_type == DB_MULTIMESH || obj_type == DB_MULTIVAR ||
5206 obj_type == DB_MULTIMAT || obj_type == DB_MULTIMATSPECIES))
5207 {
5208 int val_for_mem, val_from_file = *((int*)val_ptr);
5209 val_for_mem = val_from_file - 1;
5210 *((int*)val_ptr) = val_for_mem;
5211 }
5212 else if (!strcmp(comp_name, "topo_dim") &&
5213 (obj_type == DB_MULTIMESH || obj_type == DB_UCDMESH))
5214 {
5215 int val_for_mem, val_from_file = *((int*)val_ptr);
5216 val_for_mem = val_from_file - 1;
5217 *((int*)val_ptr) = val_for_mem;
5218 }
5219 }
5220
5221 /* For use in the DBGetObject call */
5222 static void
db_AdjustSpeciallyHandledStandardObjectComponentValues(DBobject * obj)5223 db_AdjustSpeciallyHandledStandardObjectComponentValues(DBobject *obj)
5224 {
5225 int i, obj_type;
5226
5227 if (!obj) return;
5228
5229 obj_type = DBGetObjtypeTag(obj->type);
5230 if (obj_type == DB_USERDEF) return;
5231
5232 for (i = 0; i < obj->ncomponents; i++)
5233 {
5234 char tmp[256];
5235
5236 if (!strcmp(obj->comp_names[i], "missing_value") &&
5237 (obj_type == DB_UCDVAR || obj_type == DB_QUADVAR || obj_type == DB_CURVE ||
5238 obj_type == DB_POINTVAR || obj_type == DB_MULTIVAR))
5239 {
5240 double val_for_mem, val_from_file = strtod(obj->pdb_names[i]+4,0);
5241 db_SetMissingValueForGet(val_for_mem, val_from_file);
5242 sprintf(tmp, "'<d>%.30g'", val_for_mem);
5243 }
5244 else if (!strcmp(obj->comp_names[i], "repr_block_idx") &&
5245 (obj_type == DB_MULTIMESH || obj_type == DB_MULTIVAR ||
5246 obj_type == DB_MULTIMAT || obj_type == DB_MULTIMATSPECIES))
5247 {
5248 int val_for_mem, val_from_file = (int) strtol(obj->pdb_names[i]+4,0,10);
5249 val_for_mem = val_from_file - 1;
5250 sprintf(tmp, "'<i>%d'", val_for_mem);
5251 }
5252 else if (!strcmp(obj->comp_names[i], "topo_dim") &&
5253 (obj_type == DB_MULTIMESH || obj_type == DB_UCDMESH))
5254 {
5255 int val_for_mem, val_from_file = (int) strtol(obj->pdb_names[i]+4,0,10);
5256 val_for_mem = val_from_file - 1;
5257 sprintf(tmp, "'<i>%d'", val_for_mem);
5258 }
5259 else
5260 {
5261 continue;
5262 }
5263
5264 FREE(obj->pdb_names[i]);
5265 obj->pdb_names[i] = STRDUP(tmp);
5266 }
5267 }
5268
5269 /*----------------------------------------------------------------------
5270 * Routine DBGetComponent
5271 *
5272 * Purpose
5273 *
5274 * Return the requested component value for the given object.
5275 *
5276 * Programmer
5277 *
5278 * Jeffery W. Long, NSSD-B
5279 *
5280 * Parameters
5281 *
5282 * dbfile {In} {Pointer to current file}
5283 * objname {In} {Name of object to inquire about}
5284 * compname {In} {Name of component to return}
5285 *
5286 * Notes
5287 *
5288 * Modified
5289 * Robb Matzke, Tue Nov 8 08:22:42 PST 1994
5290 * Added error mechanism
5291 *
5292 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
5293 * I replaced API_END with API_END_NOPOP.
5294 *
5295 * Eric Brugger, Wed Mar 10 16:59:34 PST 1999
5296 * Changed API_BEGIN2 to API_BEGIN so that Silo directory information
5297 * would be processed at the driver level, since the pdb driver
5298 * version of this routine handles silo directory paths as well as
5299 * file system directory paths, which API_BEGIN2 does not.
5300 *
5301 * Eric Brugger, Thu Mar 11 12:33:15 PST 1999
5302 * I forgot to remove the fourth argument when I changed API_BEGIN2
5303 * to API_BEGIN. I did so now.
5304 *
5305 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
5306 * Added a check for variable name validity.
5307 *
5308 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
5309 * Made the error messages a little better.
5310 *
5311 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5312 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5313 *--------------------------------------------------------------------*/
5314 PUBLIC void *
DBGetComponent(DBfile * dbfile,char const * objname,char const * compname)5315 DBGetComponent(DBfile *dbfile, char const *objname, char const *compname)
5316 {
5317 void *retval = NULL;
5318
5319 API_BEGIN2("DBGetComponent", void *, NULL, api_dummy) {
5320 if (!dbfile)
5321 API_ERROR(NULL, E_NOFILE);
5322 if (SILO_Globals.enableGrabDriver == TRUE)
5323 API_ERROR("DBGetComponent", E_GRABBED) ;
5324 if (!objname || !*objname)
5325 API_ERROR("object name", E_BADARGS);
5326 if (!compname || !*compname)
5327 API_ERROR("component name", E_BADARGS);
5328 if (!dbfile->pub.g_comp)
5329 API_ERROR(dbfile->pub.name, E_NOTIMP);
5330
5331 retval = (dbfile->pub.g_comp) (dbfile, objname, compname);
5332
5333 if (db_IsComponentNameStandardWithSpecialHandling(compname))
5334 db_AdjustSpeciallyHandledStandardObjectComponentValue(retval,
5335 DBInqVarType(dbfile, objname), compname);
5336
5337 API_RETURN(retval);
5338 }
5339 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5340 }
5341
5342 /*----------------------------------------------------------------------
5343 * Routine DBGetComponentType
5344 *
5345 * Purpose
5346 *
5347 * Return the type of a component for the given object.
5348 *
5349 * Programmer
5350 *
5351 * Brad Whitlock, Thu Jan 20 11:54:54 PDT 2000
5352 *
5353 * Parameters
5354 *
5355 * dbfile {In} {Pointer to current file}
5356 * objname {In} {Name of object to inquire about}
5357 * compname {In} {Name of component to return}
5358 *
5359 * Modified
5360 *
5361 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5362 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5363 *--------------------------------------------------------------------*/
5364
5365 PUBLIC int
DBGetComponentType(DBfile * dbfile,char const * objname,char const * compname)5366 DBGetComponentType(DBfile *dbfile, char const *objname, char const *compname)
5367 {
5368 int retval = DB_NOTYPE;
5369
5370 API_BEGIN2("DBGetComponentType", int, DB_NOTYPE, api_dummy) {
5371 if (!dbfile)
5372 API_ERROR(NULL, E_NOFILE);
5373 if (SILO_Globals.enableGrabDriver == TRUE)
5374 API_ERROR("", E_GRABBED) ;
5375 if (!objname || !*objname)
5376 API_ERROR("object name", E_BADARGS);
5377 if (!compname || !*compname)
5378 API_ERROR("component name", E_BADARGS);
5379 if (!dbfile->pub.g_comptyp)
5380 API_ERROR(dbfile->pub.name, E_NOTIMP);
5381
5382 retval = (dbfile->pub.g_comptyp) (dbfile, objname, compname);
5383 API_RETURN(retval);
5384 }
5385 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5386 }
5387
5388 /*----------------------------------------------------------------------
5389 * Routine DBGetDir
5390 *
5391 * Purpose
5392 *
5393 * Get the name of the current directory, return in space provided.
5394 *
5395 * Modified
5396 * Robb Matzke, Tue Nov 8 08:48:12 PST 1994
5397 * Added error mechanism
5398 *
5399 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
5400 * I replaced API_END with API_END_NOPOP.
5401 *
5402 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5403 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5404 *--------------------------------------------------------------------*/
5405 PUBLIC int
DBGetDir(DBfile * dbfile,char * path)5406 DBGetDir(DBfile *dbfile, char *path)
5407 {
5408 int retval;
5409
5410 API_BEGIN2("DBGetDir", int, -1, api_dummy) {
5411 if (!dbfile)
5412 API_ERROR(NULL, E_NOFILE);
5413 if (SILO_Globals.enableGrabDriver == TRUE)
5414 API_ERROR("DBGetDir", E_GRABBED) ;
5415 if (!path)
5416 API_ERROR("path", E_BADARGS);
5417 if (!dbfile->pub.g_dir)
5418 API_ERROR(dbfile->pub.name, E_NOTIMP);
5419
5420 retval = (dbfile->pub.g_dir) (dbfile, path);
5421 API_RETURN(retval);
5422 }
5423 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5424 }
5425
5426 /*-------------------------------------------------------------------------
5427 * Function: DBSetDir
5428 *
5429 * Purpose: Sets the current directory within the database.
5430 *
5431 * Return: Success: 0
5432 *
5433 * Failure: -1
5434 *
5435 * Programmer: robb@cloud
5436 * Wed Nov 9 13:09:23 EST 1994
5437 *
5438 * Modifications:
5439 * Robb Matzke, Mon Nov 21 21:31:17 EST 1994
5440 * Added error mechanism.
5441 *
5442 * Robb Matzke, Fri Jan 6 07:34:29 PST 1995
5443 * Checkes for changing to `.' since that is a no-op.
5444 *
5445 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
5446 * I replaced API_END with API_END_NOPOP.
5447 *
5448 * Robb Matzke, 2000-05-23
5449 * The old table of contents is discarded if the directory changes.
5450 *
5451 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5452 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5453 *-------------------------------------------------------------------------*/
5454 PUBLIC int
DBSetDir(DBfile * dbfile,const char * path)5455 DBSetDir(DBfile *dbfile, const char *path)
5456 {
5457 char tmp[256];
5458 int retval;
5459
5460 API_BEGIN2("DBSetDir", int, -1, api_dummy) {
5461 if (!dbfile)
5462 API_ERROR(NULL, E_NOFILE);
5463 if (SILO_Globals.enableGrabDriver == TRUE)
5464 API_ERROR("DBSetDir", E_GRABBED) ;
5465 if (!path || !*path)
5466 API_ERROR("path", E_BADARGS);
5467 if (STR_EQUAL(path, "."))
5468 {
5469 API_RETURN(0);
5470 }
5471 if (DBGetDir(dbfile, tmp) < 0)
5472 API_ERROR("DBGetDir", E_CALLFAIL);
5473 if (STR_EQUAL(tmp, path))
5474 {
5475 API_RETURN(0);
5476 }
5477 if (!dbfile->pub.cd)
5478 API_ERROR(dbfile->pub.name, E_NOTIMP);
5479
5480 retval = (dbfile->pub.cd) (dbfile, path);
5481 db_FreeToc(dbfile);
5482 API_RETURN(retval);
5483 }
5484 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5485 }
5486
5487 /*-------------------------------------------------------------------------
5488 * Function: DBFilters
5489 *
5490 * Purpose: List the names of filters installed for the specified
5491 * file. The list is sent to the specified stream.
5492 *
5493 * Return: Success: 0
5494 *
5495 * Failure: -1
5496 *
5497 * Programmer: robb@cloud
5498 * Tue Mar 7 10:51:58 EST 1995
5499 *
5500 * Modifications:
5501 *
5502 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5503 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5504 *-------------------------------------------------------------------------*/
5505 PUBLIC int
DBFilters(DBfile * dbfile,FILE * stream)5506 DBFilters(DBfile *dbfile, FILE *stream)
5507 {
5508 int retval;
5509
5510 API_BEGIN2("DBFilters", int, -1, api_dummy) {
5511 if (!dbfile)
5512 API_ERROR(NULL, E_NOFILE);
5513 if (SILO_Globals.enableGrabDriver == TRUE)
5514 API_ERROR("DBFilters", E_GRABBED) ;
5515 if (!stream)
5516 stream = stdout;
5517 if (!dbfile->pub.module)
5518 API_ERROR(dbfile->pub.name, E_NOTIMP);
5519
5520 retval = (dbfile->pub.module) (dbfile, stream);
5521 API_RETURN(retval);
5522 }
5523 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5524 }
5525
5526 /*-------------------------------------------------------------------------
5527 * Function: DBMkDir
5528 *
5529 * Purpose: Creates a new directory in the database.
5530 *
5531 * Return: Success: directory ID
5532 *
5533 * Failure: -1
5534 *
5535 * Programmer: matzke@viper
5536 * Tue Nov 8 11:46:21 PST 1994
5537 *
5538 * Modifications:
5539 * Robb Matzke, Mon Nov 21 21:36:44 EST 1994
5540 * Added error mechanism.
5541 *
5542 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
5543 * I replaced API_END with API_END_NOPOP.
5544 *
5545 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
5546 * Added a check for variable name validity.
5547 *
5548 * Robb Matzke, 2000-05-23
5549 * The old table of contents is discarded if the directory changes.
5550 *
5551 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5552 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5553 *-------------------------------------------------------------------------*/
5554 PUBLIC int
DBMkDir(DBfile * dbfile,const char * name)5555 DBMkDir(DBfile *dbfile, const char *name)
5556 {
5557 int retval;
5558
5559 API_BEGIN2("DBMkDir", int, -1, api_dummy) {
5560 if (!dbfile)
5561 API_ERROR(NULL, E_NOFILE);
5562 if (SILO_Globals.enableGrabDriver == TRUE)
5563 API_ERROR("DBMkDir", E_GRABBED) ;
5564 if (!name || !*name)
5565 API_ERROR("directory name", E_BADARGS);
5566 if (db_VariableNameValid(name) == 0)
5567 API_ERROR("directory name", E_INVALIDNAME);
5568 if (!dbfile->pub.mkdir)
5569 API_ERROR(dbfile->pub.name, E_NOTIMP);
5570
5571 retval = (dbfile->pub.mkdir) (dbfile, name);
5572 db_FreeToc(dbfile);
5573 API_RETURN(retval);
5574 }
5575 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5576 }
5577
5578
5579 /*-------------------------------------------------------------------------
5580 * Function: DBCpDir
5581 *
5582 * Purpose: Copies a directory tree from one file to another
5583 *
5584 * Return: Success: directory ID
5585 *
5586 * Failure: -1
5587 *
5588 * Programmer: Mark C. Miller, Wed Aug 6 15:14:33 PDT 2008
5589 *
5590 *-------------------------------------------------------------------------*/
5591 PUBLIC int
DBCpDir(DBfile * dbfile,const char * srcDir,DBfile * dstFile,const char * dstDir)5592 DBCpDir(DBfile *dbfile, const char *srcDir,
5593 DBfile *dstFile, const char *dstDir)
5594 {
5595 int retval;
5596
5597 API_BEGIN2("DBCpDir", int, -1, api_dummy) {
5598 if (!dbfile)
5599 API_ERROR(NULL, E_NOFILE);
5600 if (!dstFile)
5601 API_ERROR(NULL, E_NOFILE);
5602 if (db_isregistered_file(dstFile,0)==-1)
5603 API_ERROR(NULL, E_NOTREG);
5604 if (SILO_Globals.enableGrabDriver == TRUE)
5605 API_ERROR(NULL, E_GRABBED) ;
5606 if (!srcDir || !*srcDir)
5607 API_ERROR("source directory name", E_BADARGS);
5608 if (!dstDir || !*dstDir)
5609 API_ERROR("destination directory name", E_BADARGS);
5610 if (db_VariableNameValid(dstDir) == 0)
5611 API_ERROR("destination directory name", E_INVALIDNAME);
5612 if (!dbfile->pub.cpdir)
5613 API_ERROR(dbfile->pub.name, E_NOTIMP);
5614
5615 retval = (dbfile->pub.cpdir) (dbfile, srcDir, dstFile, dstDir);
5616 db_FreeToc(dbfile);
5617 API_RETURN(retval);
5618 }
5619 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5620 }
5621
5622 /*-------------------------------------------------------------------------
5623 * Function: DBChangeObject
5624 *
5625 * Purpose: Overwrites an object with a new object. This is usually
5626 * the same function as called by DBWriteObject but with
5627 * OVER_WRITE as the flag. However, we keep it as a separate
5628 * callback so existing drivers that don't support overwriting
5629 * don't need to be changed and so that the silo API doesn't
5630 * change by changing the meaning of the `freemem' argument
5631 * to DBWriteObject.
5632 *
5633 * Return: Success: 0
5634 *
5635 * Failure: -1
5636 *
5637 * Programmer: Robb Matzke
5638 * robb@maya.nuance.mdn.com
5639 * Mar 7 1997
5640 *
5641 * Modifications:
5642 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
5643 * Completely reformatted the code so a human can read it. Made the error
5644 * messages a little better.
5645 *
5646 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5647 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5648 *-------------------------------------------------------------------------*/
5649 PUBLIC int
DBChangeObject(DBfile * dbfile,DBobject const * obj)5650 DBChangeObject (DBfile *dbfile, DBobject const *obj)
5651 {
5652 int retval;
5653
5654 API_BEGIN2("DBChangeObject", int, -1, api_dummy)
5655 {
5656 if (!dbfile)
5657 API_ERROR(NULL, E_NOFILE);
5658 if (SILO_Globals.enableGrabDriver == TRUE)
5659 API_ERROR("DBChangeObject", E_GRABBED) ;
5660 if (!obj)
5661 API_ERROR("object pointer", E_BADARGS);
5662 if (!dbfile->pub.c_obj)
5663 API_ERROR(dbfile->pub.name, E_NOTIMP);
5664 retval = (dbfile->pub.c_obj) (dbfile, obj, OVER_WRITE);
5665 API_RETURN(retval);
5666 }
5667 API_END_NOPOP; /* BEWARE: If API_RETURN is removed
5668 * use API_END */
5669 }
5670
5671 /*-------------------------------------------------------------------------
5672 * Function: DBWriteObject
5673 *
5674 * Purpose: Write an object into the data file.
5675 *
5676 * Return: Success: 0
5677 *
5678 * Failure: -1
5679 *
5680 * Programmer: matzke@viper
5681 * Mon Nov 7 10:45:14 PST 1994
5682 *
5683 * Modifications:
5684 * Robb Matzke, Mon Nov 21 21:37:54 EST 1994
5685 * Added error mechanism.
5686 *
5687 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
5688 * I replaced API_END with API_END_NOPOP.
5689 *
5690 * Robb Matzke, 7 Mar 1997
5691 * The freemem value passed to the driver is either FREE_MEM or zero
5692 * so that drivers that overload this function with DBChangeObject
5693 * are guaranteed to be able to tell the difference.
5694 *
5695 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
5696 * Made the error messages a little better.
5697 *
5698 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5699 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5700 *-------------------------------------------------------------------------*/
5701 PUBLIC int
DBWriteObject(DBfile * dbfile,DBobject const * obj,int freemem)5702 DBWriteObject(DBfile *dbfile, DBobject const *obj, int freemem)
5703 {
5704 int retval;
5705
5706 API_BEGIN2("DBWriteObject", int, -1, api_dummy)
5707 {
5708 if (!dbfile)
5709 API_ERROR(NULL, E_NOFILE);
5710 if (SILO_Globals.enableGrabDriver == TRUE)
5711 API_ERROR("DBWriteObject", E_GRABBED) ;
5712 if (!obj)
5713 API_ERROR("object pointer", E_BADARGS);
5714 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, obj->name))
5715 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
5716 if (!dbfile->pub.w_obj)
5717 API_ERROR(dbfile->pub.name, E_NOTIMP);
5718
5719 retval = (dbfile->pub.w_obj) (dbfile, obj, freemem?FREE_MEM:0);
5720 API_RETURN(retval);
5721 }
5722 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5723 }
5724
5725 /*-------------------------------------------------------------------------
5726 * Function: DBGetObject
5727 *
5728 * Purpose: Reads an object from a file.
5729 *
5730 * Return: Success: Ptr to the new object.
5731 *
5732 * Failure: NULL
5733 *
5734 * Programmer: Robb Matzke
5735 * matzke@viper.llnl.gov
5736 * Dec 2 1996
5737 *
5738 * Modifications:
5739 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
5740 * Added a check for variable name validity.
5741 *
5742 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
5743 * Made the error messages a little better.
5744 *
5745 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5746 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5747 *-------------------------------------------------------------------------*/
5748 PUBLIC DBobject *
DBGetObject(DBfile * dbfile,char const * objname)5749 DBGetObject (DBfile *dbfile, char const *objname)
5750 {
5751 DBobject *retval = NULL;
5752
5753 API_BEGIN2("DBGetObject", DBobject *, NULL, api_dummy)
5754 {
5755 if (!dbfile)
5756 API_ERROR(NULL, E_NOFILE);
5757 if (SILO_Globals.enableGrabDriver == TRUE)
5758 API_ERROR("DBGetObject", E_GRABBED) ;
5759 if (!objname)
5760 API_ERROR("object name", E_BADARGS);
5761 if (!dbfile->pub.g_obj)
5762 API_ERROR(dbfile->pub.name, E_NOTIMP);
5763 retval = (dbfile->pub.g_obj) (dbfile, (char const *)objname);
5764 db_AdjustSpeciallyHandledStandardObjectComponentValues(retval);
5765 API_RETURN(retval);
5766 }
5767 API_END_NOPOP; /* BEWARE: If API_RETURN above is
5768 * removed use API_END */
5769 }
5770
5771 /*-------------------------------------------------------------------------
5772 * Function: DBWriteComponent
5773 *
5774 * Purpose: Add a variable component to the given object structure, AND
5775 * write out the associated data.
5776 *
5777 * Return: Success: 0
5778 *
5779 * Failure: -1
5780 *
5781 * Programmer: matzke@viper
5782 * Mon Nov 7 10:47:29 PST 1994
5783 *
5784 * Modifications:
5785 * Robb Matzke, Mon Nov 21 21:39:06 EST 1994
5786 * Added error mechanism.
5787 *
5788 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
5789 * I replaced API_END with API_END_NOPOP.
5790 *
5791 * Sean Ahern, Tue Mar 31 17:16:24 PST 1998
5792 * I added a check for zero-length data arrays.
5793 *
5794 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
5795 * Added a check for variable name validity.
5796 *
5797 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
5798 * Made the error messages a little better.
5799 *
5800 * Robb Matzke, 2000-05-23
5801 * The old table of contents is discarded if the directory changes.
5802 *
5803 * Mark C. Miller, Wed Jul 23 00:15:15 PDT 2008
5804 * Changed to API_BEGIN2 to help detect attempted ops on closed files.
5805 *-------------------------------------------------------------------------*/
5806 PUBLIC int
DBWriteComponent(DBfile * dbfile,DBobject * obj,char const * comp_name,char const * prefix,char const * datatype,void const * var,int nd,long const * count)5807 DBWriteComponent(DBfile *dbfile, DBobject *obj, char const *comp_name,
5808 char const *prefix, char const *datatype, void const *var, int nd,
5809 long const *count)
5810 {
5811 int retval;
5812 int nvals, i;
5813
5814 API_BEGIN2("DBWriteComponent", int, -1, api_dummy) {
5815 if (!dbfile)
5816 API_ERROR(NULL, E_NOFILE);
5817 if (SILO_Globals.enableGrabDriver == TRUE)
5818 API_ERROR("DBWriteComponent", E_GRABBED) ;
5819 if (!obj)
5820 API_ERROR("object pointer", E_BADARGS);
5821 if (SILO_Globals.allowEmptyObjects)
5822 {
5823 if (nd<=0) API_RETURN(0);
5824 if (!count) API_RETURN(0);
5825 if (!var) API_RETURN(0);
5826 for(nvals=1,i=0;i<nd;i++)
5827 nvals *= count[i];
5828 if (nvals<=0) API_RETURN(0);
5829 }
5830 if (!comp_name || !*comp_name)
5831 API_ERROR("component name", E_BADARGS);
5832 if (db_VariableNameValid((char *)comp_name) == 0)
5833 API_ERROR("component name", E_INVALIDNAME);
5834 #if 0
5835 /* We don't know what name to pass to DBInqVarExists here because it
5836 is the driver that knows how to construct component names */
5837 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, obj->name))
5838 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
5839 #endif
5840 if (!prefix || !*prefix)
5841 API_ERROR("prefix", E_BADARGS);
5842 if (db_VariableNameValid((char *)prefix) == 0)
5843 API_ERROR("prefix", E_INVALIDNAME);
5844 if (!datatype || !*datatype)
5845 API_ERROR("data type", E_BADARGS);
5846 if (!var)
5847 API_ERROR("var pointer", E_BADARGS);
5848 if (nd <= 0)
5849 API_ERROR("nd", E_BADARGS);
5850 if (!count && nd)
5851 API_ERROR("count", E_BADARGS);
5852 for(nvals=1,i=0;i<nd;i++)
5853 {
5854 nvals *= count[i];
5855 }
5856 if (nvals == 0) {
5857 API_ERROR("Zero-length write attempted", E_BADARGS);
5858 }
5859 if (!dbfile->pub.w_comp)
5860 API_ERROR(dbfile->pub.name, E_NOTIMP);
5861
5862 /* Note that the work to add the variable component to the object is
5863 handled down in the drivers due to the fact that the drivers may
5864 use different rules to construct the object component names */
5865
5866 retval = (dbfile->pub.w_comp) (dbfile, obj, comp_name, prefix,
5867 datatype, var, nd, count);
5868 db_FreeToc(dbfile);
5869 API_RETURN(retval);
5870 }
5871 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5872 }
5873
5874 /*-------------------------------------------------------------------------
5875 * Function: DBWrite
5876 *
5877 * Purpose: Writes a single variable into the database.
5878 *
5879 * Return: Success: 0
5880 *
5881 * Failure: -1
5882 *
5883 * Programmer: robb@cloud
5884 * Wed Nov 9 13:19:49 EST 1994
5885 *
5886 * Modifications:
5887 * Robb Matzke, Mon Nov 21 21:42:27 EST 1994
5888 * Added error mecanism.
5889 *
5890 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
5891 * I replaced API_END with API_END_NOPOP.
5892 *
5893 * Sean Ahern, Tue Mar 31 17:17:44 PST 1998
5894 * I added a check for zero-length arrays.
5895 *
5896 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
5897 * Added a check for variable name validity.
5898 *
5899 * Robb Matzke, 2000-05-23
5900 * The old table of contents is discarded if the directory changes.
5901 *
5902 * Mark C. Miller, Mon Jan 11 17:42:51 PST 2010
5903 * Allow special variable names in the magic /.silo dir for HDF5 files.
5904 *-------------------------------------------------------------------------*/
5905 PUBLIC int
DBWrite(DBfile * dbfile,char const * vname,void const * var,int const * dims,int ndims,int datatype)5906 DBWrite(DBfile *dbfile, char const *vname, void const *var, int const *dims,
5907 int ndims, int datatype)
5908 {
5909 int retval;
5910 int nvals, i;
5911
5912 API_BEGIN2("DBWrite", int, -1, vname) {
5913 if (!dbfile)
5914 API_ERROR(NULL, E_NOFILE);
5915 if (SILO_Globals.enableGrabDriver == TRUE)
5916 API_ERROR("DBWrite", E_GRABBED) ;
5917 if (!vname || !*vname)
5918 API_ERROR("variable name", E_BADARGS);
5919 if (strncmp("/.silo/#", vname, 8) != 0 &&
5920 db_VariableNameValid(vname) == 0)
5921 API_ERROR("variable name", E_INVALIDNAME);
5922 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, vname))
5923 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
5924 if (ndims <= 0)
5925 API_ERROR("ndims", E_BADARGS);
5926 if (!dims && ndims)
5927 API_ERROR("dims", E_BADARGS);
5928 for(nvals=1,i=0;i<ndims;i++)
5929 {
5930 nvals *= dims[i];
5931 }
5932 if (nvals == 0)
5933 API_ERROR("Zero length write attempted", E_BADARGS);
5934 if (db_FullyDeprecatedConvention(vname))
5935 API_ERROR(dbfile->pub.name, E_NOTIMP);
5936 if (!dbfile->pub.write)
5937 API_ERROR(dbfile->pub.name, E_NOTIMP);
5938
5939 retval = (dbfile->pub.write) (dbfile, vname, var, dims,
5940 ndims, datatype);
5941 db_FreeToc(dbfile);
5942 API_RETURN(retval);
5943 }
5944 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
5945 }
5946
5947 /*-------------------------------------------------------------------------
5948 * Function: DBWriteSlice
5949 *
5950 * Purpose: Similar to DBWrite except only part of the data is
5951 * written. If VNAME doesn't exist, space is reserved for
5952 * the entire variable based on DIMS; otherwise we check
5953 * that DIMS has the same value as originally. Then we
5954 * write the specified slice to the file.
5955 *
5956 * Return: Success: 0
5957 *
5958 * Failure: -1
5959 *
5960 * Programmer: Robb Matzke
5961 * robb@callisto.nuance.com
5962 * May 9, 1996
5963 *
5964 * Modifications:
5965 * Sean Ahern, Tue Mar 31 17:19:38 PST 1998
5966 * I added a check for zero-length writes.
5967 *
5968 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
5969 * Added a check for variable name validity.
5970 *
5971 * Robb Matzke, 2000-05-23
5972 * The old table of contents is discarded if the directory changes.
5973 *-------------------------------------------------------------------------*/
5974 PUBLIC int
DBWriteSlice(DBfile * dbfile,const char * vname,void const * values,int dtype,int const * offset,int const * length,int const * stride,int const * dims,int ndims)5975 DBWriteSlice (DBfile *dbfile, const char *vname, void const *values, int dtype,
5976 int const *offset, int const *length, int const *stride, int const *dims,
5977 int ndims)
5978 {
5979 int retval;
5980 int nvals,i;
5981
5982 API_BEGIN2("DBWriteSlice", int, -1, vname)
5983 {
5984 if (!dbfile)
5985 API_ERROR(NULL, E_NOFILE);
5986 if (SILO_Globals.enableGrabDriver == TRUE)
5987 API_ERROR("DBWriteSlice", E_GRABBED) ;
5988 if (!vname || !*vname)
5989 API_ERROR("variable name", E_BADARGS);
5990 if (db_VariableNameValid(vname) == 0)
5991 API_ERROR("variable name", E_INVALIDNAME);
5992 if (!values)
5993 API_ERROR("values", E_BADARGS);
5994 if (!offset)
5995 API_ERROR("offset", E_BADARGS);
5996 if (!length)
5997 API_ERROR("length", E_BADARGS);
5998 if (!stride)
5999 API_ERROR("stride", E_BADARGS);
6000 if (!dims)
6001 API_ERROR("dims", E_BADARGS);
6002 if (ndims <= 0 || ndims > 3)
6003 API_ERROR("ndims", E_BADARGS);
6004 for(nvals=1,i=0;i<ndims;i++)
6005 {
6006 nvals *= length[i];
6007 }
6008 if (nvals == 0)
6009 API_ERROR("Zero-length write attempted", E_BADARGS);
6010 if (!dbfile->pub.writeslice)
6011 API_ERROR(dbfile->pub.name, E_NOTIMP);
6012
6013 retval = (dbfile->pub.writeslice) (dbfile, vname, values,
6014 dtype, offset, length, stride,
6015 dims, ndims);
6016 db_FreeToc(dbfile);
6017 API_RETURN(retval);
6018 }
6019 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
6020 }
6021
6022 /*-------------------------------------------------------------------------
6023 * Function: DBGetCompoundarray
6024 *
6025 * Purpose: Read a compound array object from the file.
6026 *
6027 * Return: Success: pointer to fresh compound array obj.
6028 *
6029 * Failure: NULL
6030 *
6031 * Programmer: matzke@viper
6032 * Mon Nov 7 10:50:29 PST 1994
6033 *
6034 * Modifications:
6035 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6036 * I replaced API_END with API_END_NOPOP.
6037 *
6038 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6039 * Added a check for variable name validity.
6040 *-------------------------------------------------------------------------*/
6041 PUBLIC DBcompoundarray *
DBGetCompoundarray(DBfile * dbfile,char const * name)6042 DBGetCompoundarray(DBfile *dbfile, char const *name)
6043 {
6044 DBcompoundarray *retval = NULL;
6045
6046 API_BEGIN2("DBGetCompoundarray", DBcompoundarray *, NULL, name) {
6047 if (!dbfile)
6048 API_ERROR(NULL, E_NOFILE);
6049 if (SILO_Globals.enableGrabDriver == TRUE)
6050 API_ERROR("DBGetCompoundarray", E_GRABBED) ;
6051 if (!name || !*name)
6052 API_ERROR("array name", E_BADARGS);
6053 if (NULL == dbfile->pub.g_ca)
6054 API_ERROR(dbfile->pub.name, E_NOTIMP);
6055
6056 retval = (dbfile->pub.g_ca) (dbfile, name);
6057 API_RETURN(retval);
6058 }
6059 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6060 }
6061
6062 /*-------------------------------------------------------------------------
6063 * Function: DBGetCurve
6064 *
6065 * Purpose: Read a curve object from the file.
6066 *
6067 * Return: Success: pointer to fresh curve obj
6068 *
6069 * Failure: NULL
6070 *
6071 * Programmer: Robb Matzke
6072 * robb@callisto.nuance.com
6073 * May 16, 1996
6074 *
6075 * Modifications:
6076 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6077 * Added a check for variable name validity.
6078 *-------------------------------------------------------------------------*/
6079 PUBLIC DBcurve *
DBGetCurve(DBfile * dbfile,char const * name)6080 DBGetCurve (DBfile *dbfile, char const *name)
6081 {
6082 DBcurve *retval = NULL;
6083
6084 API_BEGIN2("DBGetCurve", DBcurve *, NULL, name)
6085 {
6086 if (!dbfile)
6087 API_ERROR(NULL, E_NOFILE);
6088 if (SILO_Globals.enableGrabDriver == TRUE)
6089 API_ERROR("DBGetCurve", E_GRABBED) ;
6090 if (!name || !*name)
6091 API_ERROR("curve name", E_BADARGS);
6092 if (NULL == dbfile->pub.g_cu)
6093 API_ERROR(dbfile->pub.name, E_NOTIMP);
6094
6095 retval = (dbfile->pub.g_cu) (dbfile, name);
6096 API_RETURN(retval);
6097 }
6098 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
6099 }
6100
6101 /*-------------------------------------------------------------------------
6102 * Function: DBGetDefvars
6103 *
6104 * Purpose: Read a defvars object from the file.
6105 *
6106 * Return: Success: pointer to fresh defvars obj
6107 *
6108 * Failure: NULL
6109 *
6110 * Programmer: Mark C. Miller
6111 * August 8, 2005
6112 *
6113 *-------------------------------------------------------------------------*/
6114 PUBLIC DBdefvars *
DBGetDefvars(DBfile * dbfile,const char * name)6115 DBGetDefvars (DBfile *dbfile, const char *name)
6116 {
6117 DBdefvars *retval = NULL;
6118
6119 API_BEGIN2("DBGetDefvars", DBdefvars *, NULL, name)
6120 {
6121 if (!dbfile)
6122 API_ERROR(NULL, E_NOFILE);
6123 if (SILO_Globals.enableGrabDriver == TRUE)
6124 API_ERROR("DBGetDefvars", E_GRABBED) ;
6125 if (!name || !*name)
6126 API_ERROR("defvars name", E_BADARGS);
6127 if (NULL == dbfile->pub.g_defv)
6128 API_ERROR(dbfile->pub.name, E_NOTIMP);
6129
6130 retval = (dbfile->pub.g_defv) (dbfile, name);
6131 API_RETURN(retval);
6132 }
6133 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
6134 }
6135
6136 /*-------------------------------------------------------------------------
6137 * Function: DBGetMaterial
6138 *
6139 * Purpose: Allocates a DBmaterial data structure, reads material data
6140 * from the database, and returns a pointer to that struct.
6141 *
6142 * Return: Success: pointer to a new DBmaterial structure
6143 *
6144 * Failure: NULL
6145 *
6146 * Programmer: matzke@viper
6147 * Tue Nov 8 09:32:17 PST 1994
6148 *
6149 * Modifications:
6150 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6151 * I replaced API_END with API_END_NOPOP.
6152 *
6153 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6154 * Added a check for variable name validity.
6155 *-------------------------------------------------------------------------*/
6156 PUBLIC DBmaterial *
DBGetMaterial(DBfile * dbfile,const char * name)6157 DBGetMaterial(DBfile *dbfile, const char *name)
6158 {
6159 DBmaterial *retval = NULL;
6160
6161 API_BEGIN2("DBGetMaterial", DBmaterial *, NULL, name) {
6162 if (!dbfile)
6163 API_ERROR(NULL, E_NOFILE);
6164 if (SILO_Globals.enableGrabDriver == TRUE)
6165 API_ERROR("DBGetMaterial", E_GRABBED) ;
6166 if (!name || !*name)
6167 API_ERROR("material name", E_BADARGS);
6168 if (!dbfile->pub.g_ma)
6169 API_ERROR(dbfile->pub.name, E_NOTIMP);
6170
6171 retval = (dbfile->pub.g_ma) (dbfile, name);
6172 API_RETURN(retval);
6173 }
6174 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6175 }
6176
6177 /*----------------------------------------------------------------------
6178 * Routine DBGetMatspecies
6179 *
6180 * Purpose
6181 *
6182 * Read a matspecies-data structure from the given database.
6183 *
6184 * Programmer
6185 *
6186 * Jeffery W. Long, NSSD-B
6187 *
6188 * Parameters
6189 *
6190 * DBGetMatspecies {Out} {Pointer to matspecies structure}
6191 * dbfile {In} {Pointer to current file}
6192 * name {In} {Name of matspecies-data to read}
6193 *
6194 * Notes
6195 *
6196 * Modifications
6197 * Al Leibee, Tue Jul 26 08:44:01 PDT 1994
6198 * Replaced composition by species.
6199 *
6200 * Robb Matzke, Tue Nov 29 13:21:27 PST 1994
6201 * Modified for device independence. Added error mechanism.
6202 *
6203 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6204 * I replaced API_END with API_END_NOPOP.
6205 *
6206 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6207 * Added a check for variable name validity.
6208 *
6209 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6210 * Made the error messages a little better.
6211 *--------------------------------------------------------------------*/
6212 PUBLIC DBmatspecies *
DBGetMatspecies(DBfile * dbfile,const char * name)6213 DBGetMatspecies(DBfile *dbfile, const char *name)
6214 {
6215 DBmatspecies *retval = NULL;
6216
6217 API_BEGIN2("DBGetMatspecies", DBmatspecies *, NULL, name) {
6218 if (!dbfile)
6219 API_ERROR(NULL, E_NOFILE);
6220 if (SILO_Globals.enableGrabDriver == TRUE)
6221 API_ERROR("DBGetMatspecies", E_GRABBED) ;
6222 if (!name || !*name)
6223 API_ERROR("material species name", E_BADARGS);
6224 if (!dbfile->pub.g_ms)
6225 API_ERROR(dbfile->pub.name, E_NOTIMP);
6226
6227 retval = (dbfile->pub.g_ms) (dbfile, name);
6228 API_RETURN(retval);
6229 }
6230 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6231 }
6232
6233 /*-------------------------------------------------------------------------
6234 * Function: DBGetMultimesh
6235 *
6236 * Purpose: Allocates a DBmultimesh data structure, reads a multi-block
6237 * mesh from the database, and returns a pointer to the
6238 * new structure.
6239 *
6240 * Return: Success: pointer to the new DBmultimesh
6241 *
6242 * Failure: NULL
6243 *
6244 * Programmer: matzke@viper
6245 * Tue Nov 8 09:35:38 PST 1994
6246 *
6247 * Modifications:
6248 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6249 * I replaced API_END with API_END_NOPOP.
6250 *
6251 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6252 * Added a check for variable name validity.
6253 *
6254 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6255 * Made the error messages a little better.
6256 *-------------------------------------------------------------------------*/
6257 PUBLIC DBmultimesh *
DBGetMultimesh(DBfile * dbfile,const char * name)6258 DBGetMultimesh(DBfile *dbfile, const char *name)
6259 {
6260 DBmultimesh * retval = NULL;
6261
6262 API_BEGIN2("DBGetMultimesh", DBmultimesh *, NULL, name) {
6263 if (!dbfile)
6264 API_ERROR(NULL, E_NOFILE);
6265 if (SILO_Globals.enableGrabDriver == TRUE)
6266 API_ERROR("DBGetMultimesh", E_GRABBED) ;
6267 if (!name || !*name)
6268 API_ERROR("multimesh name", E_BADARGS);
6269 if (!dbfile->pub.g_mm)
6270 API_ERROR(dbfile->pub.name, E_NOTIMP);
6271
6272 retval = (dbfile->pub.g_mm) (dbfile, name);
6273 API_RETURN(retval);
6274 }
6275 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6276 }
6277
6278 /*-------------------------------------------------------------------------
6279 * Function: DBGetMultimeshadj
6280 *
6281 * Purpose: Allocates a DBmultimeshdj data structure, reads a
6282 * multi-block mesh adjacency object from the database, and
6283 * returns a pointer to the new structure.
6284 *
6285 * Return: Success: pointer to the new DBmultimeshadj
6286 *
6287 * Failure: NULL
6288 *
6289 * Programmer: Mark C. Miller
6290 * August 24, 2005
6291 *
6292 *-------------------------------------------------------------------------*/
6293 PUBLIC DBmultimeshadj *
DBGetMultimeshadj(DBfile * dbfile,const char * name,int nmesh,const int * block_map)6294 DBGetMultimeshadj(DBfile *dbfile, const char *name, int nmesh,
6295 const int *block_map)
6296 {
6297 DBmultimeshadj * retval = NULL;
6298
6299 API_BEGIN2("DBGetMultimeshadj", DBmultimeshadj *, NULL, name) {
6300 if (!dbfile)
6301 API_ERROR(NULL, E_NOFILE);
6302 if (SILO_Globals.enableGrabDriver == TRUE)
6303 API_ERROR("DBGetMultimeshadj", E_GRABBED) ;
6304 if (!name || !*name)
6305 API_ERROR("multimesh name", E_BADARGS);
6306 if (!dbfile->pub.g_mmadj)
6307 API_ERROR(dbfile->pub.name, E_NOTIMP);
6308
6309 retval = (dbfile->pub.g_mmadj) (dbfile, name, nmesh,
6310 block_map);
6311 API_RETURN(retval);
6312 }
6313 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6314 }
6315
6316
6317
6318
6319
6320 /*-------------------------------------------------------------------------
6321 * Function: DBGetMultivar
6322 *
6323 * Purpose: Allocates a DBmultivar data structure, reads a multi-block
6324 * variable from the database, and returns a pointer to the
6325 * new structure.
6326 *
6327 * Return: Success: pointer to the new DBmultivar
6328 *
6329 * Failure: NULL
6330 *
6331 * Programmer: matzke@cloud
6332 * Tue Feb 21 11:27:46 EST 1995
6333 *
6334 * Modifications:
6335 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6336 * Added a check for variable name validity.
6337 *
6338 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6339 * Made the error messages a little better.
6340 *-------------------------------------------------------------------------*/
6341 PUBLIC DBmultivar *
DBGetMultivar(DBfile * dbfile,const char * name)6342 DBGetMultivar(DBfile *dbfile, const char *name)
6343 {
6344 DBmultivar * retval = NULL;
6345
6346 API_BEGIN2("DBGetMultivar", DBmultivar *, NULL, name) {
6347 if (!dbfile)
6348 API_ERROR(NULL, E_NOFILE);
6349 if (SILO_Globals.enableGrabDriver == TRUE)
6350 API_ERROR("DBGetMultivar", E_GRABBED) ;
6351 if (!name || !*name)
6352 API_ERROR("multivar name", E_BADARGS);
6353 if (!dbfile->pub.g_mv)
6354 API_ERROR(dbfile->pub.name, E_NOTIMP);
6355
6356 retval = (dbfile->pub.g_mv) (dbfile, name);
6357 API_RETURN(retval);
6358 }
6359 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6360 }
6361
6362 /*-------------------------------------------------------------------------
6363 * Function: DBGetMultimat
6364 *
6365 * Purpose: Allocates a DBmultimat data structure, reads a multi-
6366 * material from the database, and returns a pointer to the
6367 * new structure.
6368 *
6369 * Return: Success: pointer to the new DBmultimat
6370 *
6371 * Failure: NULL
6372 *
6373 * Programmer: matzke@cloud
6374 * Tue Feb 21 11:27:46 EST 1995
6375 *
6376 * Modifications:
6377 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6378 * Added a check for variable name validity.
6379 *
6380 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6381 * Made the error messages a little better.
6382 *-------------------------------------------------------------------------*/
6383 PUBLIC DBmultimat *
DBGetMultimat(DBfile * dbfile,const char * name)6384 DBGetMultimat(DBfile *dbfile, const char *name)
6385 {
6386 DBmultimat * retval = NULL;
6387
6388 API_BEGIN2("DBGetMultimat", DBmultimat *, NULL, name) {
6389 if (!dbfile)
6390 API_ERROR(NULL, E_NOFILE);
6391 if (SILO_Globals.enableGrabDriver == TRUE)
6392 API_ERROR("DBGetMultimat", E_GRABBED) ;
6393 if (!name || !*name)
6394 API_ERROR("multimat name", E_BADARGS);
6395 if (!dbfile->pub.g_mt)
6396 API_ERROR(dbfile->pub.name, E_NOTIMP);
6397
6398 retval = (dbfile->pub.g_mt) (dbfile, name);
6399 API_RETURN(retval);
6400 }
6401 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6402 }
6403
6404 /*-------------------------------------------------------------------------
6405 * Function: DBGetMultimatspecies
6406 *
6407 * Purpose: Allocates a DBmultimatspecies data structure, reads a
6408 * multi-material-species from the database, and returns
6409 * a pointer to the new structure.
6410 *
6411 * Return: Success: pointer to the new DBmultimatspecies
6412 *
6413 * Failure: NULL
6414 *
6415 * Programmer: Jeremy S. Meredith
6416 * Sept 17 1998
6417 *
6418 * Modifications:
6419 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6420 * Added a check for variable name validity.
6421 *
6422 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6423 * Made the error messages a little better.
6424 *-------------------------------------------------------------------------*/
6425 PUBLIC DBmultimatspecies *
DBGetMultimatspecies(DBfile * dbfile,const char * name)6426 DBGetMultimatspecies(DBfile *dbfile, const char *name)
6427 {
6428 DBmultimatspecies * retval = NULL;
6429
6430 API_BEGIN2("DBGetMultimatspecies", DBmultimatspecies *, NULL, name) {
6431 if (!dbfile)
6432 API_ERROR(NULL, E_NOFILE);
6433 if (SILO_Globals.enableGrabDriver == TRUE)
6434 API_ERROR("DBGetMultimatspecies", E_GRABBED) ;
6435 if (!name || !*name)
6436 API_ERROR("multimatspecies name", E_BADARGS);
6437 if (!dbfile->pub.g_mms)
6438 API_ERROR(dbfile->pub.name, E_NOTIMP);
6439
6440 retval = (dbfile->pub.g_mms) (dbfile, name);
6441 API_RETURN(retval);
6442 }
6443 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6444 }
6445
6446 /*-------------------------------------------------------------------------
6447 * Function: DBGetPointmesh
6448 *
6449 * Purpose: Allocates a DBpointmesh data structure and reads a point
6450 * mesh from the database.
6451 *
6452 * Return: Success: pointer to the new DBpointmesh struct.
6453 *
6454 * Failure: NULL
6455 *
6456 * Programmer: matzke@viper
6457 * Tue Nov 8 09:37:55 PST 1994
6458 *
6459 * Modifications:
6460 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6461 * I replaced API_END with API_END_NOPOP.
6462 *
6463 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6464 * Added a check for variable name validity.
6465 *
6466 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6467 * Made the error messages a little better.
6468 *-------------------------------------------------------------------------*/
6469 PUBLIC DBpointmesh *
DBGetPointmesh(DBfile * dbfile,const char * name)6470 DBGetPointmesh(DBfile *dbfile, const char *name)
6471 {
6472 DBpointmesh * retval = NULL;
6473
6474 API_BEGIN2("DBGetPointmesh", DBpointmesh *, NULL, name) {
6475 if (!dbfile)
6476 API_ERROR(NULL, E_NOFILE);
6477 if (SILO_Globals.enableGrabDriver == TRUE)
6478 API_ERROR("DBGetPointmesh", E_GRABBED) ;
6479 if (!name || !*name)
6480 API_ERROR("pointmesh name", E_BADARGS);
6481 if (!dbfile->pub.g_pm)
6482 API_ERROR(dbfile->pub.name, E_NOTIMP);
6483
6484 retval = (dbfile->pub.g_pm) (dbfile, name);
6485 API_RETURN(retval);
6486 }
6487 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6488 }
6489
6490 /*-------------------------------------------------------------------------
6491 * Function: DBGetPointvar
6492 *
6493 * Purpose: Allocates a DBmeshvar data structure and reads a variable
6494 * associated with a point mesh from the database.
6495 *
6496 * Return: Success: pointer to the new DBmeshvar struct
6497 *
6498 * Failure: NULL
6499 *
6500 * Programmer: matzke@viper
6501 * Tue Nov 8 09:41:21 PST 1994
6502 *
6503 * Modifications:
6504 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6505 * I replaced API_END with API_END_NOPOP.
6506 *
6507 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6508 * Added a check for variable name validity.
6509 *
6510 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6511 * Made the error messages a little better.
6512 *-------------------------------------------------------------------------*/
6513 PUBLIC DBmeshvar *
DBGetPointvar(DBfile * dbfile,const char * name)6514 DBGetPointvar(DBfile *dbfile, const char *name)
6515 {
6516 DBmeshvar * retval = NULL;
6517
6518 API_BEGIN2("DBGetPointvar", DBmeshvar *, NULL, name) {
6519 if (!dbfile)
6520 API_ERROR(NULL, E_NOFILE);
6521 if (SILO_Globals.enableGrabDriver == TRUE)
6522 API_ERROR("DBGetPointvar", E_GRABBED) ;
6523 if (!name || !*name)
6524 API_ERROR("pointvar name", E_BADARGS);
6525 if (!dbfile->pub.g_pv)
6526 API_ERROR(dbfile->pub.name, E_NOTIMP);
6527
6528 retval = (dbfile->pub.g_pv) (dbfile, name);
6529 API_RETURN(retval);
6530 }
6531 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6532 }
6533
6534 /*-------------------------------------------------------------------------
6535 * Function: DBGetQuadmesh
6536 *
6537 * Purpose: Allocates a DBquadmesh data structure and reads
6538 * a quadrilateral mesh from the databas.
6539 *
6540 * Return: Success: pointer to the new DBquadmesh struct.
6541 *
6542 * Failure: NULL
6543 *
6544 * Programmer: matzke@viper
6545 * Tue Nov 8 09:44:26 PST 1994
6546 *
6547 * Modifications:
6548 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6549 * I replaced API_END with API_END_NOPOP.
6550 *
6551 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6552 * Added a check for variable name validity.
6553 *
6554 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6555 * Made the error messages a little better.
6556 *
6557 * Hank Childs, Fri Feb 25 09:48:40 PST 2000
6558 * Initialized start_index and size_index.
6559 *
6560 *-------------------------------------------------------------------------*/
6561 PUBLIC DBquadmesh *
DBGetQuadmesh(DBfile * dbfile,const char * name)6562 DBGetQuadmesh(DBfile *dbfile, const char *name)
6563 {
6564 DBquadmesh *qm = NULL;
6565 int i;
6566
6567 API_BEGIN2("DBGetQuadmesh", DBquadmesh *, NULL, name) {
6568 if (!dbfile)
6569 API_ERROR(NULL, E_NOFILE);
6570 if (SILO_Globals.enableGrabDriver == TRUE)
6571 API_ERROR("DBGetQuadmesh", E_GRABBED) ;
6572 if (!name || !*name)
6573 API_ERROR("quadmesh name", E_BADARGS);
6574 if (!dbfile->pub.g_qm)
6575 API_ERROR(dbfile->pub.name, E_NOTIMP);
6576 qm = (dbfile->pub.g_qm) (dbfile, name);
6577 if (!qm)
6578 {
6579 API_RETURN(NULL);
6580 }
6581
6582 /*
6583 * Put in default axis labels if none supplied.
6584 */
6585 switch (qm->ndims) {
6586 case 3:
6587 if (qm->labels[2] == NULL) {
6588 qm->labels[2] = ALLOC_N(char, 7);
6589
6590 strcpy(qm->labels[2], "Z Axis");
6591 }
6592 /* Fall through */
6593 case 2:
6594 if (qm->labels[1] == NULL) {
6595 qm->labels[1] = ALLOC_N(char, 7);
6596
6597 strcpy(qm->labels[1], "Y Axis");
6598 }
6599 /* Fall through */
6600 case 1:
6601 if (qm->labels[0] == NULL) {
6602 qm->labels[0] = ALLOC_N(char, 7);
6603
6604 strcpy(qm->labels[0], "X Axis");
6605 }
6606 break;
6607 }
6608
6609 for (i = 0 ; i < 3 ; i++)
6610 {
6611 qm->start_index[i] = 0;
6612 qm->size_index[i] = qm->dims[i];
6613 }
6614
6615 API_RETURN(qm);
6616 }
6617 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6618 }
6619
6620 /*-------------------------------------------------------------------------
6621 * Function: DBGetQuadvar
6622 *
6623 * Purpose: Allocates a DBquadvar data structure and reads a variable
6624 * associated with a quadrilateral mesh from the database.
6625 *
6626 * Return: Success: Pointer to the new DBquadvar struct
6627 *
6628 * Failure: NULL
6629 *
6630 * Programmer: matzke@viper
6631 * Tue Nov 8 09:46:57 PST 1994
6632 *
6633 * Modifications:
6634 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6635 * I replaced API_END with API_END_NOPOP.
6636 *
6637 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6638 * Added a check for variable name validity.
6639 *
6640 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6641 * Made the error messages a little better.
6642 *-------------------------------------------------------------------------*/
6643 PUBLIC DBquadvar *
DBGetQuadvar(DBfile * dbfile,const char * name)6644 DBGetQuadvar(DBfile *dbfile, const char *name)
6645 {
6646 DBquadvar * retval = NULL;
6647
6648 API_BEGIN2("DBGetQuadvar", DBquadvar *, NULL, name) {
6649 if (!dbfile)
6650 API_ERROR(NULL, E_NOFILE);
6651 if (SILO_Globals.enableGrabDriver == TRUE)
6652 API_ERROR("DBGetQuadvar", E_GRABBED) ;
6653 if (!name || !*name)
6654 API_ERROR("quadvar name", E_BADARGS);
6655 if (!dbfile->pub.g_qv)
6656 API_ERROR(dbfile->pub.name, E_NOTIMP);
6657
6658 retval = (dbfile->pub.g_qv) (dbfile, name);
6659 API_RETURN(retval);
6660 }
6661 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6662 }
6663
6664 /*-------------------------------------------------------------------------
6665 * Function: DBAnnotateUcdmesh
6666 *
6667 * Purpose: Walks a DBucdmesh data structure and adds shapetype
6668 * info based on ndims and shapesize (spatial dimensions
6669 * and node count).
6670 *
6671 * Return: 1: One or more zones/shapes were annotated.
6672 *
6673 * 0: No annotation was performed.
6674 *
6675 * -1: Annotation could not be performed (an
6676 * error condition such as exhaustion of
6677 * dynamic memory occurred).
6678 *
6679 * Programmer: reus@viper
6680 * Tue Oct 8 09:40:36 PDT 1996
6681 *
6682 * Modifications:
6683 *-------------------------------------------------------------------------*/
6684 PUBLIC int
DBAnnotateUcdmesh(DBucdmesh * m)6685 DBAnnotateUcdmesh(DBucdmesh *m)
6686 {
6687 if (m != NULL)
6688 {
6689 DBzonelist *z;
6690
6691 if ((z=m->zones) != NULL)
6692 if (z->shapetype == NULL)
6693 {
6694 int N, dims;
6695
6696 if (m->topo_dim == 0 || m->topo_dim == 1 || m->topo_dim == 2)
6697 dims = m->topo_dim;
6698 else
6699 dims = z->ndims;
6700
6701 N = z->nshapes;
6702 if ((z->shapetype=(int *)malloc(N*sizeof(int))) != NULL)
6703 {
6704 int *numberOfNodes;
6705
6706 if ((numberOfNodes=z->shapesize) != NULL)
6707 {
6708 int i;
6709
6710 switch (dims)
6711 {
6712 case 1: for (i=0; i<N; ++i)
6713 z->shapetype[i] = DB_ZONETYPE_BEAM;
6714 break;
6715 case 2: for (i=0; i<N; ++i)
6716 switch (numberOfNodes[i])
6717 {
6718 case 3: z->shapetype[i] = DB_ZONETYPE_TRIANGLE;
6719 break;
6720 case 4: z->shapetype[i] = DB_ZONETYPE_QUAD;
6721 break;
6722 default: z->shapetype[i] = DB_ZONETYPE_POLYGON;
6723 break;
6724 }
6725 break;
6726 case 3: for (i=0; i<N; ++i)
6727 switch (numberOfNodes[i])
6728 {
6729 case 4: z->shapetype[i] = DB_ZONETYPE_TET;
6730 break;
6731 case 5: z->shapetype[i] = DB_ZONETYPE_PYRAMID;
6732 break;
6733 case 6: z->shapetype[i] = DB_ZONETYPE_PRISM;
6734 break;
6735 case 8: z->shapetype[i] = DB_ZONETYPE_HEX;
6736 break;
6737 default: z->shapetype[i] = DB_ZONETYPE_POLYHEDRON;
6738 break;
6739 }
6740 break;
6741 }
6742 return 1;
6743 }
6744 else
6745 return 0;
6746 }
6747 else
6748 return -1;
6749 }
6750 else
6751 return 0;
6752 else
6753 return 0;
6754 }
6755 else
6756 return 0;
6757 }
6758
6759 /*-------------------------------------------------------------------------
6760 * Function: DBGetUcdmesh
6761 *
6762 * Purpose: Allocates a DBucdmesh data structure and reads a UCD mesh
6763 * from the data file.
6764 *
6765 * Return: Success: Pointer to the new DBucdmesh struct
6766 *
6767 * Failure: NULL
6768 *
6769 * Programmer: matzke@viper
6770 * Tue Nov 8 09:57:59 PST 1994
6771 *
6772 * Modifications:
6773 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6774 * Added a check for variable name validity.
6775 *
6776 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6777 * Made the error messages a little better.
6778 *-------------------------------------------------------------------------*/
6779 PUBLIC DBucdmesh *
DBGetUcdmesh(DBfile * dbfile,const char * name)6780 DBGetUcdmesh(DBfile *dbfile, const char *name)
6781 {
6782 DBucdmesh *um = NULL;
6783
6784 API_BEGIN2("DBGetUcdmesh", DBucdmesh *, NULL, name) {
6785 if (!dbfile)
6786 API_ERROR(NULL, E_NOFILE);
6787 if (SILO_Globals.enableGrabDriver == TRUE)
6788 API_ERROR("DBGetUcdmesh", E_GRABBED) ;
6789 if (!name || !*name)
6790 API_ERROR("UCDmesh name", E_BADARGS);
6791 if (!dbfile->pub.g_um)
6792 API_ERROR(dbfile->pub.name, E_NOTIMP);
6793 um = ((dbfile->pub.g_um) (dbfile, name));
6794 if (!um)
6795 {
6796 API_RETURN(NULL);
6797 }
6798
6799 /*
6800 * Put in default axis labels if none supplied.
6801 */
6802 switch (um->ndims) {
6803 case 3:
6804 if (um->labels[2] == NULL) {
6805 um->labels[2] = ALLOC_N(char, 7);
6806
6807 if (!um->labels[2])
6808 API_ERROR(NULL, E_NOMEM);
6809 strcpy(um->labels[2], "Z Axis");
6810 }
6811 /*fall through */
6812 case 2:
6813 if (um->labels[1] == NULL) {
6814 um->labels[1] = ALLOC_N(char, 7);
6815
6816 if (!um->labels[1])
6817 API_ERROR(NULL, E_NOMEM);
6818 strcpy(um->labels[1], "Y Axis");
6819 }
6820 /*fall through */
6821 case 1:
6822 if (um->labels[0] == NULL) {
6823 um->labels[0] = ALLOC_N(char, 7);
6824
6825 if (!um->labels[0])
6826 API_ERROR(NULL, E_NOMEM);
6827 strcpy(um->labels[0], "X Axis");
6828 }
6829 }
6830 if (DBAnnotateUcdmesh(um) < 0)
6831 API_ERROR(NULL, E_NOMEM);
6832
6833 API_RETURN(um);
6834 }
6835 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6836 }
6837
6838 /*-------------------------------------------------------------------------
6839 * Function: DBGetUcdvar
6840 *
6841 * Purpose: Allocates a DBucdvar structure and reads a variable associated
6842 * with a UCD mesh from the database.
6843 *
6844 * Return: Success: Pointer to the new DBucdvar struct
6845 *
6846 * Failure: NULL
6847 *
6848 * Programmer: matzke@viper
6849 * Tue Nov 8 11:04:35 PST 1994
6850 *
6851 * Modifications:
6852 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6853 * Added a check for variable name validity.
6854 *
6855 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6856 * Made the error messages a little better.
6857 *-------------------------------------------------------------------------*/
6858 PUBLIC DBucdvar *
DBGetUcdvar(DBfile * dbfile,const char * name)6859 DBGetUcdvar(DBfile *dbfile, const char *name)
6860 {
6861 DBucdvar * retval = NULL;
6862
6863 API_BEGIN2("DBGetUcdvar", DBucdvar *, NULL, name) {
6864 if (!dbfile)
6865 API_ERROR(NULL, E_NOFILE);
6866 if (SILO_Globals.enableGrabDriver == TRUE)
6867 API_ERROR("DBGetUcdvar", E_GRABBED) ;
6868 if (!name || !*name)
6869 API_ERROR("UCDvar name", E_BADARGS);
6870 if (!dbfile->pub.g_uv)
6871 API_ERROR(dbfile->pub.name, E_NOTIMP);
6872
6873 retval = (dbfile->pub.g_uv) (dbfile, name);
6874 API_RETURN(retval);
6875 }
6876 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6877 }
6878
6879 /*-------------------------------------------------------------------------
6880 * Function: DBGetFacelist
6881 *
6882 * Purpose: Allocate and read a DBfacelist structure.
6883 *
6884 * Return: Success: ptr to new DBfacelist
6885 *
6886 * Failure: NULL
6887 *
6888 * Programmer: robb@cloud
6889 * Wed Dec 14 13:50:44 EST 1994
6890 *
6891 * Modifications:
6892 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6893 * I replaced API_END with API_END_NOPOP.
6894 *
6895 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6896 * Added a check for variable name validity.
6897 *
6898 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6899 * Made the error messages a little better.
6900 *-------------------------------------------------------------------------*/
6901 PUBLIC DBfacelist *
DBGetFacelist(DBfile * dbfile,const char * name)6902 DBGetFacelist(DBfile *dbfile, const char *name)
6903 {
6904 DBfacelist * retval = NULL;
6905
6906 API_BEGIN2("DBGetFacelist", DBfacelist *, NULL, name) {
6907 if (!dbfile)
6908 API_ERROR(NULL, E_NOFILE);
6909 if (SILO_Globals.enableGrabDriver == TRUE)
6910 API_ERROR("DBGetFacelist", E_GRABBED) ;
6911 if (!name || !*name)
6912 API_ERROR("facelist name", E_BADARGS);
6913 if (!dbfile->pub.g_fl)
6914 API_ERROR(dbfile->pub.name, E_NOTIMP);
6915
6916 retval = (dbfile->pub.g_fl) (dbfile, name);
6917 API_RETURN(retval);
6918 }
6919 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6920 }
6921
6922 /*-------------------------------------------------------------------------
6923 * Function: DBGetZonelist
6924 *
6925 * Purpose: Allocate and read a DBzonelist structure.
6926 *
6927 * Return: Success: ptr to new DBzonelist.
6928 *
6929 * Failure: NULL
6930 *
6931 * Programmer: robb@cloud
6932 * Wed Dec 14 13:59:51 EST 1994
6933 *
6934 * Modifications:
6935 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
6936 * I replaced API_END with API_END_NOPOP.
6937 *
6938 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
6939 * Added a check for variable name validity.
6940 *
6941 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
6942 * Made the error messages a little better.
6943 *-------------------------------------------------------------------------*/
6944 PUBLIC DBzonelist *
DBGetZonelist(DBfile * dbfile,const char * name)6945 DBGetZonelist(DBfile *dbfile, const char *name)
6946 {
6947 DBzonelist * retval = NULL;
6948
6949 API_BEGIN2("DBGetZonelist", DBzonelist *, NULL, name) {
6950 if (!dbfile)
6951 API_ERROR(NULL, E_NOFILE);
6952 if (SILO_Globals.enableGrabDriver == TRUE)
6953 API_ERROR("DBGetZonelist", E_GRABBED) ;
6954 if (!name || !*name)
6955 API_ERROR("zonelist name", E_BADARGS);
6956 if (!dbfile->pub.g_zl)
6957 API_ERROR(dbfile->pub.name, E_NOTIMP);
6958
6959 retval = (dbfile->pub.g_zl) (dbfile, name);
6960 API_RETURN(retval);
6961 }
6962 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6963 }
6964
6965 /*-------------------------------------------------------------------------
6966 * Function: DBGetPHZonelist
6967 *
6968 * Purpose: Allocate and read a DBphzonelist structure.
6969 *
6970 * Return: Success: ptr to new DBphzonelist.
6971 *
6972 * Failure: NULL
6973 *
6974 * Programmer: Mark C. Miller
6975 * July 28, 2004
6976 *
6977 *-------------------------------------------------------------------------*/
6978 PUBLIC DBphzonelist *
DBGetPHZonelist(DBfile * dbfile,const char * name)6979 DBGetPHZonelist(DBfile *dbfile, const char *name)
6980 {
6981 DBphzonelist * retval = NULL;
6982
6983 API_BEGIN2("DBGetPHZonelist", DBphzonelist *, NULL, name) {
6984 if (!dbfile)
6985 API_ERROR(NULL, E_NOFILE);
6986 if (SILO_Globals.enableGrabDriver == TRUE)
6987 API_ERROR("DBGetPHZonelist", E_GRABBED) ;
6988 if (!name || !*name)
6989 API_ERROR("zonelist name", E_BADARGS);
6990 if (!dbfile->pub.g_phzl)
6991 API_ERROR(dbfile->pub.name, E_NOTIMP);
6992
6993 retval = (dbfile->pub.g_phzl) (dbfile, name);
6994 API_RETURN(retval);
6995 }
6996 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
6997 }
6998
6999 /*-------------------------------------------------------------------------
7000 * Function: DBGetVar
7001 *
7002 * Purpose: Allocate space for a variable and read the variable from the
7003 * database.
7004 *
7005 * Return: Success: Pointer to the variable value.
7006 *
7007 * Failure: NULL
7008 *
7009 * Programmer: matzke@viper
7010 * Tue Nov 8 11:11:29 PST 1994
7011 *
7012 * Modifications:
7013 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7014 * I replaced API_END with API_END_NOPOP.
7015 *
7016 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7017 * Added a check for variable name validity.
7018 *-------------------------------------------------------------------------*/
7019 PUBLIC void *
DBGetVar(DBfile * dbfile,const char * name)7020 DBGetVar(DBfile *dbfile, const char *name)
7021 {
7022 void * retval = NULL;
7023
7024 API_BEGIN2("DBGetVar", void *, NULL, name) {
7025 if (!dbfile)
7026 API_ERROR(NULL, E_NOFILE);
7027 if (SILO_Globals.enableGrabDriver == TRUE)
7028 API_ERROR("DBGetVar", E_GRABBED) ;
7029 if (!name || !*name)
7030 API_ERROR("variable name", E_BADARGS);
7031 if (!dbfile->pub.g_var)
7032 API_ERROR(dbfile->pub.name, E_NOTIMP);
7033
7034 retval = (dbfile->pub.g_var) (dbfile, name);
7035 API_RETURN(retval);
7036 }
7037 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7038 }
7039
7040 /*-------------------------------------------------------------------------
7041 * Function: DBReadVar
7042 *
7043 * Purpose: Same as DBGetVar() except the user supplies the result
7044 * memory instead of the function allocating it on the heap.
7045 *
7046 * Return: Success: 0
7047 *
7048 * Failure: -1
7049 *
7050 * Programmer: robb@cloud
7051 * Wed Nov 9 13:00:07 EST 1994
7052 *
7053 * Modifications:
7054 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7055 * I replaced API_END with API_END_NOPOP.
7056 *
7057 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7058 * Added a check for variable name validity.
7059 *
7060 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7061 * Made the error messages a little better.
7062 *-------------------------------------------------------------------------*/
7063 PUBLIC int
DBReadVar(DBfile * dbfile,const char * name,void * result)7064 DBReadVar(DBfile *dbfile, const char *name, void *result)
7065 {
7066 int retval;
7067
7068 API_BEGIN2("DBReadVar", int, -1, name) {
7069 if (!dbfile)
7070 API_ERROR(NULL, E_NOFILE);
7071 if (SILO_Globals.enableGrabDriver == TRUE)
7072 API_ERROR("DBReadVar", E_GRABBED) ;
7073 if (!name || !*name)
7074 API_ERROR("variable name", E_BADARGS);
7075 if (!result)
7076 API_ERROR("result pointer", E_BADARGS);
7077 if (!dbfile->pub.r_var)
7078 API_ERROR(dbfile->pub.name, E_NOTIMP);
7079
7080 retval = (dbfile->pub.r_var) (dbfile, name, result);
7081 API_RETURN(retval);
7082 }
7083 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7084 }
7085
7086 /*-------------------------------------------------------------------------
7087 * Function: DBReadVarSlice
7088 *
7089 * Purpose: Same as DBReadVarSlice() except the user can read a only
7090 * a slice of the variable.
7091 *
7092 * Return: Success: 0
7093 *
7094 * Failure: -1
7095 *
7096 * Programmer: brugger@sgibird
7097 * Thu Feb 16 08:25:47 PST 1995
7098 *
7099 * Modifications:
7100 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7101 * Added a check for variable name validity.
7102 *
7103 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7104 * Made the error messages a little better.
7105 *-------------------------------------------------------------------------*/
7106 PUBLIC int
DBReadVarSlice(DBfile * dbfile,const char * name,int const * offset,int const * length,int const * stride,int ndims,void * result)7107 DBReadVarSlice(DBfile *dbfile, const char *name, int const *offset, int const *length,
7108 int const *stride, int ndims, void *result)
7109 {
7110 int retval;
7111
7112 API_BEGIN2("DBReadVarSlice", int, -1, name) {
7113 if (!dbfile)
7114 API_ERROR(NULL, E_NOFILE);
7115 if (SILO_Globals.enableGrabDriver == TRUE)
7116 API_ERROR("DBReadVarSlice", E_GRABBED) ;
7117 if (!name || !*name)
7118 API_ERROR("variable name", E_BADARGS);
7119 if (!offset)
7120 API_ERROR("offset", E_BADARGS);
7121 if (!length)
7122 API_ERROR("length", E_BADARGS);
7123 if (!stride)
7124 API_ERROR("stride", E_BADARGS);
7125 if (ndims <= 0)
7126 API_ERROR("ndims", E_BADARGS);
7127 if (!result)
7128 API_ERROR("result pointer", E_BADARGS);
7129 if (!dbfile->pub.r_varslice)
7130 API_ERROR(dbfile->pub.name, E_NOTIMP);
7131
7132 retval = (dbfile->pub.r_varslice) (dbfile, name, offset,
7133 length, stride, ndims, result);
7134 API_RETURN(retval);
7135 }
7136 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7137 }
7138
7139 /*-------------------------------------------------------------------------
7140 * Function: DBGetVarByteLength
7141 *
7142 * Purpose: Returns the length of the requested variable, in bytes.
7143 *
7144 * Return: Success: length of variable in bytes.
7145 *
7146 * Failure: -1
7147 *
7148 * Programmer: matzke@viper
7149 * Tue Nov 8 11:18:35 PST 1994
7150 *
7151 * Modifications:
7152 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7153 * I replaced API_END with API_END_NOPOP.
7154 *
7155 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7156 * Added a check for variable name validity.
7157 *-------------------------------------------------------------------------*/
7158 PUBLIC int
DBGetVarByteLength(DBfile * dbfile,const char * name)7159 DBGetVarByteLength(DBfile *dbfile, const char *name)
7160 {
7161 int retval;
7162
7163 API_BEGIN2("DBGetVarByteLength", int, -1, name) {
7164 if (!dbfile)
7165 API_ERROR(NULL, E_NOFILE);
7166 if (SILO_Globals.enableGrabDriver == TRUE)
7167 API_ERROR("DBGetVarByteLength", E_GRABBED) ;
7168 if (!name || !*name)
7169 API_ERROR("variable name", E_BADARGS);
7170 if (!dbfile->pub.g_varbl)
7171 API_ERROR(dbfile->pub.name, E_NOTIMP);
7172
7173 retval = (dbfile->pub.g_varbl) (dbfile, name);
7174 API_RETURN(retval);
7175 }
7176 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7177 }
7178
7179 /*-------------------------------------------------------------------------
7180 * Function: DBGetVarLength
7181 *
7182 * Purpose: Returns the number of elements in the given variable.
7183 *
7184 * Return: Success: number of elements
7185 *
7186 * Failure: -1
7187 *
7188 * Programmer: matzke@viper
7189 * Tue Nov 8 11:23:20 PST 1994
7190 *
7191 * Modifications:
7192 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7193 * I replaced API_END with API_END_NOPOP.
7194 *
7195 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7196 * Added a check for variable name validity.
7197 *-------------------------------------------------------------------------*/
7198 PUBLIC int
DBGetVarLength(DBfile * dbfile,const char * name)7199 DBGetVarLength(DBfile *dbfile, const char *name)
7200 {
7201 int retval;
7202
7203 API_BEGIN2("DBGetVarLength", int, -1, name) {
7204 if (!dbfile)
7205 API_ERROR(NULL, E_NOFILE);
7206 if (SILO_Globals.enableGrabDriver == TRUE)
7207 API_ERROR("DBGetVarLength", E_GRABBED) ;
7208 if (!name || !*name)
7209 API_ERROR("variable name", E_BADARGS);
7210 if (!dbfile->pub.g_varlen)
7211 API_ERROR(dbfile->pub.name, E_NOTIMP);
7212
7213 retval = (dbfile->pub.g_varlen) (dbfile, name);
7214 API_RETURN(retval);
7215 }
7216 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7217 }
7218
7219 /*-------------------------------------------------------------------------
7220 * Function: DBGetVarDims
7221 *
7222 * Purpose: Returns information about the dimensions of a variable.
7223 * The user passes a buffer to hold the dimension sizes
7224 * and indicates the size of that buffer.
7225 *
7226 * Return: Success: The number of dimensions not exceeding
7227 * MAXDIMS. The dimension sizes are returned
7228 * through DIMS.
7229 *
7230 * Failure: -1
7231 *
7232 * Programmer: Robb Matzke
7233 * robb@maya.nuance.mdn.com
7234 * Mar 6 1997
7235 *
7236 * Modifications:
7237 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7238 * Reformatted the code so that a human can read it.
7239 *-------------------------------------------------------------------------*/
7240 PUBLIC int
DBGetVarDims(DBfile * dbfile,const char * name,int maxdims,int * dims)7241 DBGetVarDims(DBfile *dbfile, const char *name, int maxdims, int *dims)
7242 {
7243 int retval = -1;
7244
7245 API_BEGIN2("DBGetVarDims", int, -1, name)
7246 {
7247 if (!dbfile)
7248 API_ERROR(NULL, E_NOFILE);
7249 if (SILO_Globals.enableGrabDriver == TRUE)
7250 API_ERROR("DBGetVarDims", E_GRABBED) ;
7251 if (!name || !*name)
7252 API_ERROR("variable name", E_BADARGS);
7253 if (maxdims <= 0)
7254 API_ERROR("max dims", E_BADARGS);
7255 if (!dims)
7256 API_ERROR("dimension buffer pointer", E_BADARGS);
7257 if (!dbfile->pub.g_vardims)
7258 API_ERROR(dbfile->pub.name, E_NOTIMP);
7259
7260 retval = (dbfile->pub.g_vardims) (dbfile, name, maxdims, dims);
7261 API_RETURN(retval);
7262 }
7263 API_END_NOPOP; /* BEWARE: If API_RETURN above is
7264 * removed use API_END */
7265 }
7266
7267 /*-------------------------------------------------------------------------
7268 * Function: DBGetVarType
7269 *
7270 * Purpose: Returns the data type of a variable.
7271 *
7272 * Return: Success: type, such as DB_INT, DB_FLOAT, etc.
7273 *
7274 * Failure: -1
7275 *
7276 * Programmer: matzke@viper
7277 * Thu Dec 22 08:54:20 PST 1994
7278 *
7279 * Modifications:
7280 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7281 * I replaced API_END with API_END_NOPOP.
7282 *
7283 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7284 * Added a check for variable name validity.
7285 *-------------------------------------------------------------------------*/
7286 PUBLIC int
DBGetVarType(DBfile * dbfile,const char * name)7287 DBGetVarType(DBfile *dbfile, const char *name)
7288 {
7289 int retval;
7290
7291 API_BEGIN2("DBGetVarType", int, -1, name) {
7292 if (!dbfile)
7293 API_ERROR(NULL, E_NOFILE);
7294 if (SILO_Globals.enableGrabDriver == TRUE)
7295 API_ERROR("DBGetVarType", E_GRABBED) ;
7296 if (!name || !*name)
7297 API_ERROR("variable name", E_BADARGS);
7298 if (!dbfile->pub.g_vartype)
7299 API_ERROR(dbfile->pub.name, E_NOTIMP);
7300
7301 retval = (dbfile->pub.g_vartype) (dbfile, name);
7302 API_RETURN(retval);
7303 }
7304 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7305 }
7306
7307 /*-------------------------------------------------------------------------
7308 * Function: DBInqMeshname
7309 *
7310 * Purpose: Returns the name of a mesh associated with a mesh
7311 * variable.
7312 *
7313 * Return: Success: 0, name returned via `mname'
7314 *
7315 * Failure: -1
7316 *
7317 * Programmer: matzke@viper
7318 * Tue Nov 8 11:27:15 PST 1994
7319 *
7320 * Modifications:
7321 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7322 * I replaced API_END with API_END_NOPOP.
7323 *
7324 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7325 * Added a check for variable name validity.
7326 *
7327 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7328 * Made the error messages a little better.
7329 *-------------------------------------------------------------------------*/
7330 PUBLIC int
DBInqMeshname(DBfile * dbfile,const char * vname,char * mname)7331 DBInqMeshname(DBfile *dbfile, const char *vname, char *mname)
7332 {
7333 int retval;
7334
7335 API_BEGIN2("DBInqMeshname", int, -1, vname) {
7336 if (!dbfile)
7337 API_ERROR(NULL, E_NOFILE);
7338 if (SILO_Globals.enableGrabDriver == TRUE)
7339 API_ERROR("DBInqMeshname", E_GRABBED) ;
7340 if (!vname || !*vname)
7341 API_ERROR("variable name", E_BADARGS);
7342 if (!mname)
7343 API_ERROR("mesh name pointer", E_BADARGS);
7344 if (!dbfile->pub.i_meshname)
7345 API_ERROR(dbfile->pub.name, E_NOTIMP);
7346
7347 retval = (dbfile->pub.i_meshname) (dbfile, vname, mname);
7348 API_RETURN(retval);
7349 }
7350 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7351 }
7352
7353 /*-------------------------------------------------------------------------
7354 * Function: DBInqMeshtype
7355 *
7356 * Purpose: Returns the mesh type for the specified mesh.
7357 *
7358 * Return: Success: mesh type constant
7359 *
7360 * Failure: -1
7361 *
7362 * Programmer: matzke@viper
7363 * Tue Nov 8 11:31:56 PST 1994
7364 *
7365 * Modifications:
7366 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7367 * I replaced API_END with API_END_NOPOP.
7368 *
7369 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7370 * Added a check for variable name validity.
7371 *-------------------------------------------------------------------------*/
7372 PUBLIC int
DBInqMeshtype(DBfile * dbfile,const char * name)7373 DBInqMeshtype(DBfile *dbfile, const char *name)
7374 {
7375 int retval;
7376
7377 API_BEGIN2("DBInqMeshtype", int, -1, name) {
7378 if (!dbfile)
7379 API_ERROR(NULL, E_NOFILE);
7380 if (SILO_Globals.enableGrabDriver == TRUE)
7381 API_ERROR("DBInqMeshtype", E_GRABBED) ;
7382 if (!name || !*name)
7383 API_ERROR("mesh name", E_BADARGS);
7384 if (!dbfile->pub.i_meshtype)
7385 API_ERROR(dbfile->pub.name, E_NOTIMP);
7386
7387 retval = (dbfile->pub.i_meshtype) (dbfile, name);
7388 API_RETURN(retval);
7389 }
7390 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7391 }
7392
7393 /*-------------------------------------------------------------------------
7394 * Function: DBPutCompoundarray
7395 *
7396 * Purpose: Write compoundarray information to a file.
7397 *
7398 * Return: Success: 0
7399 *
7400 * Failure: -1
7401 *
7402 * Programmer: matzke@viper
7403 * Mon Nov 7 10:54:46 PST 1994
7404 *
7405 * Modifications:
7406 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7407 * I replaced API_END with API_END_NOPOP.
7408 *
7409 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7410 * Added a check for variable name validity.
7411 *
7412 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7413 * Made the error messages a little better.
7414 *
7415 * Robb Matzke, 2000-05-23
7416 * The old table of contents is discarded if the directory changes.
7417 *-------------------------------------------------------------------------*/
7418 PUBLIC int
DBPutCompoundarray(DBfile * dbfile,char const * name,char const * const * elemnames,int const * elemlengths,int nelems,void const * values,int nvalues,int datatype,DBoptlist const * opts)7419 DBPutCompoundarray(
7420 DBfile *dbfile,
7421 char const *name,
7422 char const * const *elemnames,
7423 int const *elemlengths,
7424 int nelems,
7425 void const *values,
7426 int nvalues,
7427 int datatype,
7428 DBoptlist const *opts
7429 )
7430 {
7431 int retval;
7432
7433 API_BEGIN2("DBPutCompoundarray", int, -1, name) {
7434 if (!dbfile)
7435 API_ERROR(NULL, E_NOFILE);
7436 if (SILO_Globals.enableGrabDriver == TRUE)
7437 API_ERROR("DBPutCompoundarray", E_GRABBED) ;
7438 if (!name || !*name)
7439 API_ERROR("array name", E_BADARGS);
7440 if (db_VariableNameValid(name) == 0)
7441 API_ERROR("array name", E_INVALIDNAME);
7442 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
7443 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
7444 if (nelems < 0)
7445 API_ERROR("nelems<0", E_BADARGS);
7446 if (nelems)
7447 {
7448 if (!nelems)
7449 API_ERROR("nelems=0", E_BADARGS);
7450 if (!elemnames)
7451 API_ERROR("elemnames=0", E_BADARGS);
7452 if (nvalues <= 0)
7453 API_ERROR("nvalues=0", E_BADARGS);
7454 if (!values)
7455 API_ERROR("values=0", E_BADARGS);
7456 }
7457 else if (!SILO_Globals.allowEmptyObjects)
7458 {
7459 /* this is an empty object but we don't know if it was intentional */
7460 API_ERROR("nelems=0", E_EMPTYOBJECT);
7461 }
7462 else
7463 {
7464 nvalues = 0;
7465 }
7466
7467 if (NULL == dbfile->pub.p_ca)
7468 API_ERROR(dbfile->pub.name, E_NOTIMP);
7469
7470 retval = (dbfile->pub.p_ca) (dbfile, name, elemnames,
7471 elemlengths, nelems, values, nvalues,
7472 datatype, opts);
7473 db_FreeToc(dbfile);
7474 API_RETURN(retval);
7475 }
7476 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7477 }
7478
7479 /*-------------------------------------------------------------------------
7480 * Function: DBPutCurve
7481 *
7482 * Purpose: Writes curve information to a file.
7483 *
7484 * Return: Success: 0
7485 *
7486 * Failure: -1
7487 *
7488 * Programmer: Robb Matzke
7489 * robb@callisto.nuance.com
7490 * May 15, 1996
7491 *
7492 * Modifications:
7493 * Robb Matzke, 16 May 1996
7494 * Don't check for existence of XVALS and YVALS since the OPTS can
7495 * specify a PDB variable name which has already been added to the
7496 * file and which contains the necessary x or y values. However,
7497 * the driver should check.
7498 *
7499 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7500 * Added a check for variable name validity.
7501 *
7502 * Robb Matzke, 2000-05-23
7503 * The old table of contents is discarded if the directory changes.
7504 *-------------------------------------------------------------------------*/
7505 PUBLIC int
DBPutCurve(DBfile * dbfile,char const * name,void const * xvals,void const * yvals,int datatype,int npts,DBoptlist const * opts)7506 DBPutCurve(
7507 DBfile *dbfile,
7508 char const *name,
7509 void const *xvals,
7510 void const *yvals,
7511 int datatype,
7512 int npts,
7513 DBoptlist const *opts
7514 )
7515 {
7516 int retval;
7517
7518 API_BEGIN2("DBPutCurve", int, -1, name)
7519 {
7520 if (!dbfile)
7521 API_ERROR(NULL, E_NOFILE);
7522 if (SILO_Globals.enableGrabDriver == TRUE)
7523 API_ERROR("DBPutCurve", E_GRABBED) ;
7524 if (!name || !*name)
7525 API_ERROR("curve name", E_BADARGS);
7526 if (db_VariableNameValid(name) == 0)
7527 API_ERROR("curve name", E_INVALIDNAME);
7528 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
7529 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
7530 if (npts < 0)
7531 API_ERROR("npts<0", E_BADARGS);
7532 if (npts)
7533 {
7534 if (DBGetOption(opts, DBOPT_REFERENCE))
7535 {
7536 if (yvals || xvals)
7537 API_ERROR("xvals & yvals must be null when using DBOPT_REFERENCE", E_BADARGS);
7538 }
7539 else
7540 {
7541 if (!xvals && !DBGetOption(opts, DBOPT_XVARNAME))
7542 API_ERROR("xvals=0 || DBOPT_XVARNAME", E_BADARGS);
7543 if (xvals && DBGetOption(opts, DBOPT_XVARNAME))
7544 API_ERROR("xvals!=0 && DBOPT_XVARNAME", E_BADARGS);
7545 if (!yvals && !DBGetOption(opts, DBOPT_YVARNAME))
7546 API_ERROR("yvals=0 || DBOPT_YVARNAME", E_BADARGS);
7547 if (yvals && DBGetOption(opts, DBOPT_YVARNAME))
7548 API_ERROR("yvals!=0 && DBOPT_YVARNAME", E_BADARGS);
7549 }
7550 }
7551 else if (!SILO_Globals.allowEmptyObjects &&
7552 !DBGetOption(opts, DBOPT_REFERENCE))
7553 {
7554 /* this is an empty object but we don't know if it was intentional */
7555 API_ERROR("npts=0", E_EMPTYOBJECT);
7556 }
7557
7558 if (NULL == dbfile->pub.p_cu)
7559 API_ERROR(dbfile->pub.name, E_NOTIMP);
7560
7561 retval = (dbfile->pub.p_cu) (dbfile, name, (void*)xvals, (void*)yvals,
7562 datatype, npts, opts);
7563
7564 db_FreeToc(dbfile);
7565 API_RETURN(retval);
7566 }
7567 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
7568 }
7569
7570 /*-------------------------------------------------------------------------
7571 * Function: DBPutDefvars
7572 *
7573 * Purpose: Writes a Defvars object to a file.
7574 *
7575 * Return: Success: 0
7576 *
7577 * Failure: -1
7578 *
7579 * Programmer: Mark C. Miller
7580 * August 8, 2005
7581 *
7582 *-------------------------------------------------------------------------*/
7583 PUBLIC int
DBPutDefvars(DBfile * dbfile,const char * name,int ndefs,char const * const * names,int const * types,char const * const * defns,DBoptlist const * const * opts)7584 DBPutDefvars(
7585 DBfile *dbfile,
7586 const char *name,
7587 int ndefs,
7588 char const * const *names,
7589 int const *types,
7590 char const * const *defns,
7591 DBoptlist const * const *opts
7592 )
7593 {
7594 int retval;
7595
7596 API_BEGIN2("DBPutDefvars", int, -1, name)
7597 {
7598 if (!dbfile)
7599 API_ERROR(NULL, E_NOFILE);
7600 if (SILO_Globals.enableGrabDriver == TRUE)
7601 API_ERROR("DBPutDefvars", E_GRABBED) ;
7602 if (!name || !*name)
7603 API_ERROR("defvars name", E_BADARGS);
7604 if (db_VariableNameValid(name) == 0)
7605 API_ERROR("defvars name", E_INVALIDNAME);
7606 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
7607 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
7608 if (ndefs < 0)
7609 API_ERROR("ndefs", E_BADARGS);
7610 if (ndefs)
7611 {
7612 if (!names)
7613 API_ERROR("names=0", E_BADARGS);
7614 if (!types)
7615 API_ERROR("types=0", E_BADARGS);
7616 if (!defns)
7617 API_ERROR("defns=0", E_BADARGS);
7618 }
7619 else if (!SILO_Globals.allowEmptyObjects)
7620 {
7621 /* this is an empty object but we don't know if it was intentional */
7622 API_ERROR("ndefs=0", E_EMPTYOBJECT);
7623 }
7624
7625 if (NULL == dbfile->pub.p_defv)
7626 API_ERROR(dbfile->pub.name, E_NOTIMP);
7627
7628 retval = (dbfile->pub.p_defv) (dbfile, name, ndefs, names,
7629 types, defns, opts);
7630 db_FreeToc(dbfile);
7631 API_RETURN(retval);
7632 }
7633 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
7634 }
7635
7636 /*-------------------------------------------------------------------------
7637 * Function: DBPutFacelist
7638 *
7639 * Purpose: Writes a facelist object into the open database file.
7640 *
7641 * Return: Success: 0
7642 *
7643 * Failure: -1
7644 *
7645 * Programmer: matzke@viper
7646 * Tue Nov 8 11:52:25 PST 1994
7647 *
7648 * Modifications:
7649 * Robb Matzke, Thu Dec 1 10:34:09 PST 1994
7650 * The `zoneno' parameter is optional even if
7651 * the number of faces is zero.
7652 *
7653 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7654 * I replaced API_END with API_END_NOPOP.
7655 *
7656 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7657 * Added a check for variable name validity.
7658 *
7659 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7660 * Made the error messages a little better.
7661 *
7662 * Robb Matzke, 2000-05-23
7663 * The old table of contents is discarded if the directory changes.
7664 *-------------------------------------------------------------------------*/
7665 PUBLIC int
DBPutFacelist(DBfile * dbfile,const char * name,int nfaces,int ndims,int const * nodelist,int lnodelist,int origin,int const * zoneno,int const * shapesize,int const * shapecnt,int nshapes,int const * types,int const * typelist,int ntypes)7666 DBPutFacelist(DBfile *dbfile, const char *name, int nfaces, int ndims,
7667 int const *nodelist, int lnodelist, int origin, int const *zoneno,
7668 int const *shapesize, int const *shapecnt, int nshapes, int const *types,
7669 int const *typelist, int ntypes)
7670 {
7671 int retval;
7672
7673 API_BEGIN2("DBPutFacelist", int, -1, name) {
7674 if (!dbfile)
7675 API_ERROR(NULL, E_NOFILE);
7676 if (SILO_Globals.enableGrabDriver == TRUE)
7677 API_ERROR("DBPutFacelist", E_GRABBED) ;
7678 if (!name || !*name)
7679 API_ERROR("facelist name", E_BADARGS);
7680 if (db_VariableNameValid(name) == 0)
7681 API_ERROR("facelist name", E_INVALIDNAME);
7682 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
7683 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
7684 if (nfaces < 0)
7685 API_ERROR("nfaces<0", E_BADARGS);
7686 if (nfaces)
7687 {
7688 if (nfaces <= 0)
7689 API_ERROR("nfaces<=0", E_BADARGS);
7690 if (ndims <= 0)
7691 API_ERROR("ndims<=0", E_BADARGS);
7692 if (lnodelist <= 0)
7693 API_ERROR("lnodelist<0", E_BADARGS);
7694 if (nshapes <= 0)
7695 API_ERROR("nshapes<0", E_BADARGS);
7696 if (!nodelist)
7697 API_ERROR("nodelist==0", E_BADARGS);
7698 if (!shapesize)
7699 API_ERROR("shapesize==0", E_BADARGS);
7700 if (!shapecnt)
7701 API_ERROR("shapecnt==0", E_BADARGS);
7702 if (ntypes < 0)
7703 API_ERROR("ntypes<0", E_BADARGS);
7704 if (origin != 0 && origin != 1)
7705 API_ERROR("origin", E_BADARGS);
7706 }
7707 else if (!SILO_Globals.allowEmptyObjects)
7708 {
7709 /* this is an empty object but we don't know if it was intentional */
7710 API_ERROR("nfaces=0", E_EMPTYOBJECT);
7711 }
7712 else
7713 {
7714 nfaces = 0;
7715 lnodelist = 0;
7716 nshapes = 0;
7717 ntypes = 0;
7718 }
7719
7720 if (!dbfile->pub.p_fl)
7721 API_ERROR(dbfile->pub.name, E_NOTIMP);
7722
7723 retval = (dbfile->pub.p_fl) (dbfile, name, nfaces, ndims,
7724 nodelist, lnodelist, origin, zoneno,
7725 shapesize, shapecnt, nshapes, types,
7726 typelist, ntypes);
7727 db_FreeToc(dbfile);
7728 API_RETURN(retval);
7729 }
7730 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7731 }
7732
7733 /*-------------------------------------------------------------------------
7734 * Function: DBPutMaterial
7735 *
7736 * Purpose: Writes a material data object into the current open
7737 * database. The minimum required information for a material
7738 * data object is supplied via the standard arguments to the
7739 * function. The `optlist' argument must be used for
7740 * supplying any information not requested through the
7741 * standard arguments.
7742 *
7743 * Return: Success: object ID
7744 *
7745 * Failure: -1
7746 *
7747 * Programmer: matzke@viper
7748 * Tue Nov 8 12:05:23 PST 1994
7749 *
7750 * Modifications:
7751 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7752 * I replaced API_END with API_END_NOPOP.
7753 *
7754 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7755 * Added a check for variable name validity.
7756 *
7757 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7758 * Made the error messages a little better.
7759 *
7760 * Robb Matzke, 2000-05-23
7761 * The old table of contents is discarded if the directory changes.
7762 *
7763 * Sean Ahern, Thu Jun 8 12:08:05 PDT 2000
7764 * Removed an unnecessary check on mix_zone.
7765 *-------------------------------------------------------------------------*/
7766 PUBLIC int
DBPutMaterial(DBfile * dbfile,char const * name,char const * meshname,int nmat,int const * matnos,int const * matlist,int const * dims,int ndims,int const * mix_next,int const * mix_mat,int const * mix_zone,DBVCP1_t mix_vf,int mixlen,int datatype,DBoptlist const * optlist)7767 DBPutMaterial(
7768 DBfile *dbfile,
7769 char const *name,
7770 char const *meshname,
7771 int nmat,
7772 int const *matnos,
7773 int const *matlist,
7774 int const *dims,
7775 int ndims,
7776 int const *mix_next,
7777 int const *mix_mat,
7778 int const *mix_zone,
7779 DBVCP1_t mix_vf,
7780 int mixlen,
7781 int datatype,
7782 DBoptlist const *optlist
7783 )
7784 {
7785 int i, retval, is_empty = 1;
7786
7787 API_BEGIN2("DBPutMaterial", int, -1, name) {
7788 if (!dbfile)
7789 API_ERROR(NULL, E_NOFILE);
7790 if (SILO_Globals.enableGrabDriver == TRUE)
7791 API_ERROR("DBPutMaterial", E_GRABBED) ;
7792 if (!name || !*name)
7793 API_ERROR("material name", E_BADARGS);
7794 if (db_VariableNameValid(name) == 0)
7795 API_ERROR("material name", E_INVALIDNAME);
7796 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
7797 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
7798 if (nmat < 0)
7799 API_ERROR("nmat<0", E_BADARGS);
7800 if (ndims < 0)
7801 API_ERROR("ndims<0", E_BADARGS);
7802 if (!dims)
7803 API_ERROR("dims=0", E_BADARGS);
7804 for (i = 0; i < ndims; i++)
7805 {
7806 if (dims[i] != 0)
7807 {
7808 is_empty = 0;
7809 break;
7810 }
7811 }
7812 if (!is_empty)
7813 {
7814 for (i = 0; i < ndims && dims; i++)
7815 if (dims[i] == 0) dims = 0;
7816 if (!matnos) API_ERROR("matnos=0", E_BADARGS);
7817 if (!matlist) API_ERROR("matlist=0", E_BADARGS);
7818 if (!meshname || !*meshname) API_ERROR("mesh name", E_BADARGS);
7819 if (!db_VariableNameValid(meshname)) API_ERROR("meshname", E_INVALIDNAME);
7820 if (mixlen < 0)
7821 API_ERROR("mixlen<0", E_BADARGS);
7822 if (mixlen)
7823 {
7824 if (!mix_next)
7825 API_ERROR("mix_next=0", E_BADARGS);
7826 if (!mix_mat)
7827 API_ERROR("mix_mat=0", E_BADARGS);
7828 if (!mix_vf)
7829 API_ERROR("mix_vf=0", E_BADARGS);
7830 }
7831 }
7832 else if (!SILO_Globals.allowEmptyObjects)
7833 {
7834 API_ERROR("nmat=0", E_EMPTYOBJECT);
7835 }
7836 if (!dbfile->pub.p_ma)
7837 API_ERROR(dbfile->pub.name, E_NOTIMP);
7838
7839 retval = (dbfile->pub.p_ma) (dbfile, name, meshname,
7840 nmat, matnos, matlist, dims, ndims,
7841 mix_next, mix_mat, mix_zone, mix_vf,
7842 mixlen, datatype, optlist);
7843
7844 /* Zero out the _ma._matnames pointer so we can't accidentially use it
7845 * again. Likewise for matcolors. */
7846 _ma._matnames = NULL;
7847 _ma._matcolors = NULL;
7848
7849 db_FreeToc(dbfile);
7850 API_RETURN(retval);
7851 }
7852 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7853 }
7854
7855 /*----------------------------------------------------------------------
7856 * Routine DBPutMatspecies
7857 *
7858 * Purpose
7859 *
7860 * Write a material species object into the open file.
7861 *
7862 * Programmer
7863 *
7864 * Al Leibee, B-DSAD
7865 *
7866 * Notes
7867 *
7868 * One zonal array ('speclist') is used which contains either:
7869 * 1) an index into the 'species_mf' array of the species mass fractions
7870 * of a clean zone's material.
7871 *
7872 * OR
7873 * 2) an index into the 'mix_speclist' array which contains an index
7874 * into the 'species_mf' of the species mass fractions of a mixed
7875 * zone's materials.
7876 *
7877 * Modified
7878 * Robb Matzke, Mon Nov 28 15:19:50 EST 1994
7879 * Added device independence stuff.
7880 *
7881 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7882 * I replaced API_END with API_END_NOPOP.
7883 *
7884 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7885 * Added a check for variable name validity.
7886 *
7887 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7888 * Made the error messages a little better.
7889 *
7890 * Robb Matzke, 2000-05-23
7891 * The old table of contents is discarded if the directory changes.
7892 *--------------------------------------------------------------------*/
7893 PUBLIC int
DBPutMatspecies(DBfile * dbfile,const char * name,const char * matname,int nmat,int const * nmatspec,int const * speclist,int const * dims,int ndims,int nspecies_mf,DBVCP1_t species_mf,int const * mix_speclist,int mixlen,int datatype,DBoptlist const * optlist)7894 DBPutMatspecies(DBfile *dbfile, const char *name, const char *matname,
7895 int nmat, int const *nmatspec, int const *speclist, int const *dims,
7896 int ndims, int nspecies_mf, DBVCP1_t species_mf,
7897 int const *mix_speclist, int mixlen, int datatype,
7898 DBoptlist const *optlist)
7899 {
7900 int i, retval, is_empty=1;
7901
7902 API_BEGIN2("DBPutMatspecies", int, -1, name) {
7903 if (!dbfile)
7904 API_ERROR(NULL, E_NOFILE);
7905 if (SILO_Globals.enableGrabDriver == TRUE)
7906 API_ERROR("DBPutMatspecies", E_GRABBED) ;
7907 if (!name || !*name)
7908 API_ERROR("matspecies name", E_BADARGS);
7909 if (db_VariableNameValid(name) == 0)
7910 API_ERROR("matspecies name", E_INVALIDNAME);
7911 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
7912 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
7913 if (nmat < 0)
7914 API_ERROR("nmat<0", E_BADARGS);
7915 if (ndims < 0)
7916 API_ERROR("ndims<0", E_BADARGS);
7917 if (!dims)
7918 API_ERROR("dims=0", E_BADARGS);
7919 if (nspecies_mf < 0)
7920 API_ERROR("nspecies_mf<0", E_BADARGS);
7921 for (i = 0; i < ndims; i++)
7922 {
7923 if (dims[i] != 0)
7924 {
7925 is_empty = 0;
7926 break;
7927 }
7928 }
7929 if (!is_empty && nspecies_mf > 0)
7930 {
7931 if (!matname || !*matname)
7932 API_ERROR("material name", E_BADARGS);
7933 if (db_VariableNameValid(matname) == 0)
7934 API_ERROR("material name", E_INVALIDNAME);
7935 if (ndims == 1 && dims[0] <= 0) API_ERROR("dims[0]<=0", E_BADARGS);
7936 if (ndims == 2 && dims[1] <= 0) API_ERROR("dims[1]<=0", E_BADARGS);
7937 if (ndims == 3 && dims[2] <= 0) API_ERROR("dims[2]<=0", E_BADARGS);
7938 if (!nmatspec) API_ERROR("nmatspec=0", E_BADARGS);
7939 if (!speclist) API_ERROR("speclist=0", E_BADARGS);
7940 if (!species_mf) API_ERROR("species_mf=0", E_BADARGS);
7941 if (mixlen < 0)
7942 API_ERROR("mixlen", E_BADARGS);
7943 if (!mix_speclist && mixlen)
7944 API_ERROR("mix_speclist", E_BADARGS);
7945 }
7946 else if (!SILO_Globals.allowEmptyObjects)
7947 {
7948 API_ERROR("dims[i]==0 for all i || nspecies_mf==0", E_EMPTYOBJECT);
7949 }
7950 if (!dbfile->pub.p_ms)
7951 API_ERROR(dbfile->pub.name, E_NOTIMP);
7952 retval = (dbfile->pub.p_ms) (dbfile, name, matname,
7953 nmat, nmatspec, speclist, dims, ndims,
7954 nspecies_mf, species_mf, mix_speclist,
7955 mixlen, datatype, optlist);
7956
7957 /* Zero out the _ma._matnames pointer so we can't accidentially use it
7958 * again. Likewise for matcolors. */
7959 _ms._specnames = NULL;
7960 _ms._speccolors = NULL;
7961
7962 db_FreeToc(dbfile);
7963 API_RETURN(retval);
7964 }
7965 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
7966 }
7967
7968 /*-------------------------------------------------------------------------
7969 * Function: DBPutMultimesh
7970 *
7971 * Purpose: Writes a multi-bloc kmesh object into the open database.
7972 * It accepts as input descriptions of the various sub-meshes
7973 * (blocks) which are part of this mesh.
7974 *
7975 * Return: Success: object ID
7976 *
7977 * Failure: -1
7978 *
7979 * Programmer: matzke@viper
7980 * Tue Nov 8 12:17:57 PST 1994
7981 *
7982 * Modifications:
7983 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
7984 * I replaced API_END with API_END_NOPOP.
7985 *
7986 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
7987 * Added a check for variable name validity.
7988 *
7989 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
7990 * Made the error messages a little better.
7991 *
7992 * Robb Matzke, 2000-05-23
7993 * The old table of contents is discarded if the directory changes.
7994 *
7995 * Mark C. Miller, Wed Jul 14 20:36:23 PDT 2010
7996 * Added support for nameschemes on multi-block objects. This meant
7997 * adjusting sanity checks for args as some can be null now.
7998 *-------------------------------------------------------------------------*/
7999 PUBLIC int
DBPutMultimesh(DBfile * dbfile,char const * name,int nmesh,char const * const * meshnames,int const * meshtypes,DBoptlist const * optlist)8000 DBPutMultimesh(DBfile *dbfile, char const *name, int nmesh,
8001 char const * const *meshnames, int const *meshtypes,
8002 DBoptlist const *optlist)
8003 {
8004 int retval;
8005
8006 API_BEGIN2("DBPutMultimesh", int, -1, name) {
8007 if (!dbfile)
8008 API_ERROR(NULL, E_NOFILE);
8009 if (SILO_Globals.enableGrabDriver == TRUE)
8010 API_ERROR("DBPutMultimesh", E_GRABBED) ;
8011 if (!name || !*name)
8012 API_ERROR("multimesh name", E_BADARGS);
8013 if (db_VariableNameValid(name) == 0)
8014 API_ERROR("multimesh name", E_INVALIDNAME);
8015 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8016 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8017 if (nmesh < 0)
8018 API_ERROR("nmesh", E_BADARGS);
8019 if (!meshnames && nmesh && (!optlist ||
8020 (!DBGetOption(optlist, DBOPT_MB_FILE_NS) &&
8021 !DBGetOption(optlist, DBOPT_MB_BLOCK_NS))))
8022 API_ERROR("mesh names", E_BADARGS);
8023 if (!meshtypes && nmesh && (!optlist ||
8024 !DBGetOption(optlist, DBOPT_MB_BLOCK_TYPE)))
8025 API_ERROR("mesh types", E_BADARGS);
8026 if (!dbfile->pub.p_mm)
8027 API_ERROR(dbfile->pub.name, E_NOTIMP);
8028
8029 retval = (dbfile->pub.p_mm) (dbfile, name, nmesh, meshnames,
8030 meshtypes, optlist);
8031 db_FreeToc(dbfile);
8032 API_RETURN(retval);
8033 }
8034 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8035 }
8036
8037 /*-------------------------------------------------------------------------
8038 * Function: DBPutMultimeshadj
8039 *
8040 * Purpose: Writes a multi-mesh adjacency object into the
8041 * open database.
8042 *
8043 * Return: Success: object ID
8044 *
8045 * Failure: -1
8046 *
8047 * Programmer: Mark C. Miller, August 23, 2005
8048 *
8049 * Notes: This function is designed to support repeated calls where
8050 * Different parts of the same object are written at different
8051 * times.
8052 *
8053 *-------------------------------------------------------------------------*/
8054 PUBLIC int
DBPutMultimeshadj(DBfile * dbfile,char const * name,int nmesh,int const * meshtypes,int const * nneighbors,int const * neighbors,int const * back,int const * lnodelists,int const * const * nodelists,int const * lzonelists,int const * const * zonelists,DBoptlist const * optlist)8055 DBPutMultimeshadj(DBfile *dbfile, char const *name, int nmesh,
8056 int const *meshtypes, int const *nneighbors,
8057 int const *neighbors, int const *back,
8058 int const *lnodelists, int const * const *nodelists,
8059 int const *lzonelists, int const * const *zonelists,
8060 DBoptlist const *optlist)
8061 {
8062 int retval;
8063
8064 API_BEGIN2("DBPutMultimeshadj", int, -1, name) {
8065 if (!dbfile)
8066 API_ERROR(NULL, E_NOFILE);
8067 if (SILO_Globals.enableGrabDriver == TRUE)
8068 API_ERROR("DBPutMultimeshadj", E_GRABBED) ;
8069 if (!name || !*name)
8070 API_ERROR("multimeshadj name", E_BADARGS);
8071 if (db_VariableNameValid(name) == 0)
8072 API_ERROR("multimeshadj name", E_INVALIDNAME);
8073 if (nmesh < 0)
8074 API_ERROR("nmesh", E_BADARGS);
8075 if (!meshtypes && nmesh)
8076 API_ERROR("mesh types", E_BADARGS);
8077 if (!nneighbors && nmesh)
8078 API_ERROR("nneighbors", E_BADARGS);
8079 if (!neighbors && nmesh)
8080 API_ERROR("neighbors", E_BADARGS);
8081 if (lnodelists == NULL && nodelists != NULL)
8082 API_ERROR("non-NULL nodelists", E_BADARGS);
8083 if (lzonelists == NULL && zonelists != NULL)
8084 API_ERROR("non-NULL zonelists", E_BADARGS);
8085 if (!dbfile->pub.p_mmadj)
8086 API_ERROR(dbfile->pub.name, E_NOTIMP);
8087
8088 retval = (dbfile->pub.p_mmadj) (dbfile, name, nmesh, meshtypes,
8089 nneighbors, neighbors, back,
8090 lnodelists, nodelists, lzonelists, zonelists,
8091 optlist);
8092 db_FreeToc(dbfile);
8093 API_RETURN(retval);
8094 }
8095 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8096 }
8097
8098 /*-------------------------------------------------------------------------
8099 * Function: DBPutMultivar
8100 *
8101 * Purpose: Writes a multi-block variable object to the database.
8102 *
8103 * Return: Success: object ID
8104 *
8105 * Failure: -1
8106 *
8107 * Programmer: matzke@viper
8108 * Tue Nov 8 12:26:30 PST 1994
8109 *
8110 * Modifications:
8111 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8112 * I replaced API_END with API_END_NOPOP.
8113 *
8114 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8115 * Added a check for variable name validity.
8116 *
8117 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8118 * Made the error messages a little better.
8119 *
8120 * Robb Matzke, 2000-05-23
8121 * The old table of contents is discarded if the directory changes.
8122 *
8123 * Mark C. Miller, Wed Jul 14 20:36:23 PDT 2010
8124 * Added support for nameschemes on multi-block objects. This meant
8125 * adjusting sanity checks for args as some can be null now.
8126 *-------------------------------------------------------------------------*/
8127 PUBLIC int
DBPutMultivar(DBfile * dbfile,const char * name,int nvar,char const * const * varnames,int const * vartypes,DBoptlist const * optlist)8128 DBPutMultivar(DBfile *dbfile, const char *name, int nvar,
8129 char const * const *varnames, int const *vartypes, DBoptlist const *optlist)
8130 {
8131 int retval;
8132
8133 API_BEGIN2("DBPutMultivar", int, -1, name) {
8134 if (!dbfile)
8135 API_ERROR(NULL, E_NOFILE);
8136 if (SILO_Globals.enableGrabDriver == TRUE)
8137 API_ERROR("DBPutMultivar", E_GRABBED) ;
8138 if (!name || !*name)
8139 API_ERROR("multivar name", E_BADARGS);
8140 if (db_VariableNameValid(name) == 0)
8141 API_ERROR("multivar name", E_INVALIDNAME);
8142 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8143 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8144 if (nvar < 0)
8145 API_ERROR("nvar", E_BADARGS);
8146 if (!varnames && nvar && (!optlist ||
8147 (!DBGetOption(optlist, DBOPT_MB_FILE_NS) &&
8148 !DBGetOption(optlist, DBOPT_MB_BLOCK_NS))))
8149 API_ERROR("varnames", E_BADARGS);
8150 if (!vartypes && nvar && (!optlist ||
8151 !DBGetOption(optlist, DBOPT_MB_BLOCK_TYPE)))
8152 API_ERROR("vartypes", E_BADARGS);
8153 if (!dbfile->pub.p_mv)
8154 API_ERROR(dbfile->pub.name, E_NOTIMP);
8155
8156 retval = (dbfile->pub.p_mv) (dbfile, name, nvar, varnames,
8157 vartypes, optlist);
8158 db_FreeToc(dbfile);
8159 API_RETURN(retval);
8160 }
8161 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8162 }
8163
8164 /*-------------------------------------------------------------------------
8165 * Function: DBPutMultimat
8166 *
8167 * Purpose: Writes a multi-material object to the database.
8168 *
8169 * Return: Success: object ID
8170 *
8171 * Failure: -1
8172 *
8173 * Programmer: matzke@viper
8174 * Tue Feb 21 12:35:10 EST 1995
8175 *
8176 * Modifications:
8177 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8178 * Added a check for variable name validity.
8179 *
8180 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8181 * Made the error messages a little better.
8182 *
8183 * Robb Matzke, 2000-05-23
8184 * The old table of contents is discarded if the directory changes.
8185 *
8186 * Mark C. Miller, Wed Jul 14 20:36:23 PDT 2010
8187 * Added support for nameschemes on multi-block objects. This meant
8188 * adjusting sanity checks for args as some can be null now.
8189 *-------------------------------------------------------------------------*/
8190 PUBLIC int
DBPutMultimat(DBfile * dbfile,const char * name,int nmats,char const * const * matnames,DBoptlist const * optlist)8191 DBPutMultimat(DBfile *dbfile, const char *name, int nmats,
8192 char const * const *matnames, DBoptlist const *optlist)
8193 {
8194 int retval;
8195
8196 API_BEGIN2("DBPutMultimat", int, -1, name) {
8197 if (!dbfile)
8198 API_ERROR(NULL, E_NOFILE);
8199 if (SILO_Globals.enableGrabDriver == TRUE)
8200 API_ERROR("DBPutMultimat", E_GRABBED) ;
8201 if (!name || !*name)
8202 API_ERROR("multimat name", E_BADARGS);
8203 if (db_VariableNameValid(name) == 0)
8204 API_ERROR("multimat name", E_INVALIDNAME);
8205 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8206 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8207 if (nmats < 0)
8208 API_ERROR("nmats", E_BADARGS);
8209 if (!matnames && nmats && (!optlist ||
8210 (!DBGetOption(optlist, DBOPT_MB_FILE_NS) &&
8211 !DBGetOption(optlist, DBOPT_MB_BLOCK_NS))))
8212 API_ERROR("material-names", E_BADARGS);
8213 if (!dbfile->pub.p_mt)
8214 API_ERROR(dbfile->pub.name, E_NOTIMP);
8215
8216 retval = (dbfile->pub.p_mt) (dbfile, name, nmats, matnames,
8217 optlist);
8218
8219 /* Zero out the _mm._matnames pointer so we can't accidentially use it
8220 * again. Likewise for matcolors. */
8221 _mm._matnames = NULL;
8222 _mm._matcolors = NULL;
8223
8224 db_FreeToc(dbfile);
8225 API_RETURN(retval);
8226 }
8227 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8228 }
8229
8230 /*-------------------------------------------------------------------------
8231 * Function: DBPutMultimatspecies
8232 *
8233 * Purpose: Writes a multi-material object to the database.
8234 *
8235 * Return: Success: object ID
8236 *
8237 * Failure: -1
8238 *
8239 * Programmer: Jeremy S. Meredith
8240 * Sept 17 1998
8241 *
8242 * Modifications:
8243 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8244 * Added a check for variable name validity.
8245 *
8246 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8247 * Made the error messages a little better.
8248 *
8249 * Robb Matzke, 2000-05-23
8250 * The old table of contents is discarded if the directory changes.
8251 *
8252 * Mark C. Miller, Wed Jul 14 20:36:23 PDT 2010
8253 * Added support for nameschemes on multi-block objects. This meant
8254 * adjusting sanity checks for args as some can be null now.
8255 *-------------------------------------------------------------------------*/
8256 PUBLIC int
DBPutMultimatspecies(DBfile * dbfile,const char * name,int nspec,char const * const * specnames,DBoptlist const * optlist)8257 DBPutMultimatspecies(DBfile *dbfile, const char *name, int nspec,
8258 char const * const *specnames, DBoptlist const *optlist)
8259 {
8260 int retval;
8261
8262 API_BEGIN2("DBPutMultimatspecies", int, -1, name) {
8263 if (!dbfile)
8264 API_ERROR(NULL, E_NOFILE);
8265 if (SILO_Globals.enableGrabDriver == TRUE)
8266 API_ERROR("DBPutMultimatspecies", E_GRABBED) ;
8267 if (!name || !*name)
8268 API_ERROR("multimatspecies name", E_BADARGS);
8269 if (db_VariableNameValid(name) == 0)
8270 API_ERROR("multimatspecies name", E_INVALIDNAME);
8271 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8272 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8273 if (nspec < 0)
8274 API_ERROR("nspec", E_BADARGS);
8275 if (!specnames && nspec && (!optlist ||
8276 (!DBGetOption(optlist, DBOPT_MB_FILE_NS) &&
8277 !DBGetOption(optlist, DBOPT_MB_BLOCK_NS))))
8278 API_ERROR("species-names", E_BADARGS);
8279 if (!dbfile->pub.p_mms)
8280 API_ERROR(dbfile->pub.name, E_NOTIMP);
8281
8282 retval = (dbfile->pub.p_mms) (dbfile, name, nspec, specnames, optlist);
8283
8284 /* Zero out the _ma._matnames pointer so we can't accidentially use it
8285 * again. Likewise for matcolors. */
8286 _mm._specnames = NULL;
8287 _mm._speccolors = NULL;
8288
8289 db_FreeToc(dbfile);
8290 API_RETURN(retval);
8291 }
8292 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8293 }
8294
8295 /*-------------------------------------------------------------------------
8296 * Function: DBPutPoinmesh
8297 *
8298 * Purpose: Accepts pointers to the coordinate arrays and writes the
8299 * mesh into the database.
8300 *
8301 * Return: Success: object ID
8302 *
8303 * Failure: -1
8304 *
8305 * Programmer: matzke@viper
8306 * Tue Nov 8 12:32:43 PST 1994
8307 *
8308 * Modifications:
8309 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8310 * I replaced API_END with API_END_NOPOP.
8311 *
8312 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8313 * Added a check for variable name validity.
8314 *
8315 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8316 * Made the error messages a little better.
8317 *
8318 * Robb Matzke, 2000-05-23
8319 * The old table of contents is discarded if the directory changes.
8320 *-------------------------------------------------------------------------*/
8321 PUBLIC int
DBPutPointmesh(DBfile * dbfile,const char * name,int ndims,DBVCP2_t coords,int nels,int datatype,DBoptlist const * optlist)8322 DBPutPointmesh(DBfile *dbfile, const char *name, int ndims, DBVCP2_t coords,
8323 int nels, int datatype, DBoptlist const *optlist)
8324 {
8325 int retval;
8326
8327 API_BEGIN2("DBPutPointmesh", int, -1, name) {
8328 if (!dbfile)
8329 API_ERROR(NULL, E_NOFILE);
8330 if (SILO_Globals.enableGrabDriver == TRUE)
8331 API_ERROR("DBPutPointmesh", E_GRABBED) ;
8332 if (!name || !*name)
8333 API_ERROR("pointmesh name", E_BADARGS);
8334 if (db_VariableNameValid(name) == 0)
8335 API_ERROR("pointmesh name", E_INVALIDNAME);
8336 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8337 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8338 if (nels < 0)
8339 API_ERROR("nels<0", E_BADARGS);
8340 if (nels > 0)
8341 {
8342 int i;
8343 void **coords2 = (void**) coords;
8344 if (ndims < 1 || ndims > 3)
8345 API_ERROR("ndims < 1 || ndims > 3", E_BADARGS);
8346 for (i = 0; i < ndims && coords; i++)
8347 if (coords2[i] == 0) coords = 0;
8348 if (!coords)
8349 API_ERROR("coords=0 || coords[i]=0 for some i", E_BADARGS);
8350 }
8351 else if (!SILO_Globals.allowEmptyObjects)
8352 {
8353 API_ERROR("nels==0", E_EMPTYOBJECT);
8354 }
8355
8356 if (!dbfile->pub.p_pm)
8357 API_ERROR(dbfile->pub.name, E_NOTIMP);
8358
8359 retval = (dbfile->pub.p_pm) (dbfile, name, ndims, coords, nels,
8360 datatype, optlist);
8361 db_FreeToc(dbfile);
8362 API_RETURN(retval);
8363 }
8364 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8365 }
8366
8367 /*-------------------------------------------------------------------------
8368 * Function: DBPutPointvar
8369 *
8370 * Purpose: Accepts pointers to the value arrays and writes the
8371 * variables into a point-variable object in the database.
8372 *
8373 * Return: Success: object ID
8374 *
8375 * Failure: -1
8376 *
8377 * Programmer: matzke@viper
8378 * Tue Nov 8 12:38:22 PST 1994
8379 *
8380 * Modifications:
8381 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8382 * I replaced API_END with API_END_NOPOP.
8383 *
8384 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8385 * Added a check for variable name validity.
8386 *
8387 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8388 * Made the error messages a little better.
8389 *
8390 * Robb Matzke, 2000-05-23
8391 * The old table of contents is discarded if the directory changes.
8392 *-------------------------------------------------------------------------*/
8393 PUBLIC int
DBPutPointvar(DBfile * dbfile,const char * vname,const char * mname,int nvars,DBVCP2_t vars,int nels,int datatype,DBoptlist const * optlist)8394 DBPutPointvar(DBfile *dbfile, const char *vname, const char *mname, int nvars,
8395 DBVCP2_t vars, int nels, int datatype, DBoptlist const *optlist)
8396 {
8397 int retval;
8398
8399 API_BEGIN2("DBPutPointvar", int, -1, vname) {
8400 if (!dbfile)
8401 API_ERROR(NULL, E_NOFILE);
8402 if (SILO_Globals.enableGrabDriver == TRUE)
8403 API_ERROR("DBPutPointvar", E_GRABBED) ;
8404 if (!vname || !*vname)
8405 API_ERROR("pointvar name", E_BADARGS);
8406 if (db_VariableNameValid(vname) == 0)
8407 API_ERROR("pointvar name", E_INVALIDNAME);
8408 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, vname))
8409 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8410 if (nels < 0)
8411 API_ERROR("nels<0", E_BADARGS);
8412 if (nels)
8413 {
8414 int i;
8415 void **vars2 = (void**) vars;
8416 if (nvars <= 0)
8417 API_ERROR("nvars<=0", E_BADARGS);
8418 for (i = 0; i < nvars && vars; i++)
8419 if (!vars2[i]) vars = 0;
8420 if (!vars) API_ERROR("vars==0 || vars[i]==0", E_BADARGS);
8421 if (!mname || !*mname)
8422 API_ERROR("pointmesh name", E_BADARGS);
8423 if (db_VariableNameValid(mname) == 0)
8424 API_ERROR("pointmesh name", E_INVALIDNAME);
8425 }
8426 else if (!SILO_Globals.allowEmptyObjects)
8427 {
8428 API_ERROR("nels=0", E_EMPTYOBJECT);
8429 }
8430
8431 if (!dbfile->pub.p_pv)
8432 API_ERROR(dbfile->pub.name, E_NOTIMP);
8433
8434 retval = (dbfile->pub.p_pv) (dbfile, vname, mname,
8435 nvars, vars, nels, datatype, optlist);
8436 db_FreeToc(dbfile);
8437 API_RETURN(retval);
8438 }
8439 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8440 }
8441
8442 /*-------------------------------------------------------------------------
8443 * Function: DBPutPointvar1
8444 *
8445 * Purpose: Same as DBPutPointvar except only one variable at a time.
8446 *
8447 * Return: Success: Object ID
8448 *
8449 * Failure: -1
8450 *
8451 * Programmer: matzke@viper
8452 * Tue Nov 8 12:46:01 PST 1994
8453 *
8454 * Modifications:
8455 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8456 * I replaced API_END with API_END_NOPOP.
8457 *
8458 * Robb Matzke, 2000-05-23
8459 * The old table of contents is discarded if the directory changes.
8460 *-------------------------------------------------------------------------*/
8461 PUBLIC int
DBPutPointvar1(DBfile * dbfile,const char * vname,const char * mname,DBVCP1_t var,int nels,int datatype,DBoptlist const * optlist)8462 DBPutPointvar1(DBfile *dbfile, const char *vname, const char *mname,
8463 DBVCP1_t var, int nels, int datatype, DBoptlist const *optlist)
8464 {
8465 DBVCP1_t vars[1] = {var};
8466 int retval;
8467
8468 API_BEGIN2("DBPutPointvar1", int, -1, vname)
8469 {
8470 retval = DBPutPointvar(dbfile, vname, mname, 1, vars,
8471 nels, datatype, optlist);
8472 db_FreeToc(dbfile);
8473 API_RETURN(retval);
8474 }
8475 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8476 }
8477
8478 /*-------------------------------------------------------------------------
8479 * Function: DBPutQuadmesh
8480 *
8481 * Purpose: Accepts pointers to the coordinate arrays and writes the
8482 * mesh into a quad-mesh object in the database.
8483 *
8484 * Return: Success: Object ID
8485 *
8486 * Failure: -1
8487 *
8488 * Programmer: matzke@viper
8489 * Tue Nov 8 12:50:40 PST 1994
8490 *
8491 * Modifications:
8492 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8493 * I replaced API_END with API_END_NOPOP.
8494 *
8495 * Sean Ahern, Mon Nov 2 17:51:55 PST 1998
8496 * Removed the requirement for a non-NULL coordnames parameter.
8497 *
8498 * Sean Ahern, Wed Mar 17 10:12:39 PST 1999
8499 * Added a check for the coordtype. It must be DB_COLLINEAR or
8500 * DB_NONCOLLINEAR.
8501 *
8502 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8503 * Added a check for variable name validity.
8504 *
8505 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8506 * Made the error messages a little better.
8507 *
8508 * Robb Matzke, 2000-05-23
8509 * The old table of contents is discarded if the directory changes.
8510 *-------------------------------------------------------------------------*/
8511 PUBLIC int
DBPutQuadmesh(DBfile * dbfile,const char * name,char const * const * coordnames,DBVCP2_t coords,int const * dims,int ndims,int datatype,int coordtype,DBoptlist const * optlist)8512 DBPutQuadmesh(DBfile *dbfile, const char *name, char const * const *coordnames,
8513 DBVCP2_t coords, int const *dims, int ndims, int datatype,
8514 int coordtype, DBoptlist const *optlist)
8515 {
8516 int i, retval, is_empty=1;
8517
8518 API_BEGIN2("DBPutQuadmesh", int, -1, name) {
8519 if (!dbfile)
8520 API_ERROR(NULL, E_NOFILE);
8521 if (SILO_Globals.enableGrabDriver == TRUE)
8522 API_ERROR("DBPutQuadmesh", E_GRABBED) ;
8523 if (!name || !*name)
8524 API_ERROR("quadmesh name", E_BADARGS);
8525 if (db_VariableNameValid(name) == 0)
8526 API_ERROR("quadmesh name", E_INVALIDNAME);
8527 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8528 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8529 if ((coordtype != DB_COLLINEAR) && (coordtype != DB_NONCOLLINEAR))
8530 API_ERROR("coordtype must be DB_COLLINEAR or DB_NONCOLLINEAR", E_BADARGS);
8531 if (ndims < 0)
8532 API_ERROR("ndims", E_BADARGS);
8533 if (!dims)
8534 API_ERROR("dims==0", E_BADARGS);
8535 for (i = 0; i < ndims; i++)
8536 {
8537 if (dims[i] != 0)
8538 {
8539 is_empty = 0;
8540 break;
8541 }
8542 }
8543 if (!is_empty)
8544 {
8545 void **coords2 = (void**) coords;
8546 for (i = 0; i < ndims && coords; i++)
8547 if (!coords2[i]) coords = 0;
8548 if (!coords)
8549 API_ERROR("coords==0 || coords[i]==0", E_BADARGS);
8550 }
8551 else if (!SILO_Globals.allowEmptyObjects)
8552 {
8553 /* this is an empty object but we don't think it was intentional */
8554 API_ERROR("dims[i]==0 for all i", E_EMPTYOBJECT);
8555 }
8556 if (!dbfile->pub.p_qm)
8557 API_ERROR(dbfile->pub.name, E_NOTIMP);
8558
8559 retval = (dbfile->pub.p_qm) (dbfile, name, coordnames, coords,
8560 dims, ndims, datatype, coordtype,
8561 optlist);
8562 db_FreeToc(dbfile);
8563 API_RETURN(retval);
8564 }
8565 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8566 }
8567
8568 /*-------------------------------------------------------------------------
8569 * Function: DBPutQuadvar
8570 *
8571 * Purpose: Writes a variable associated with a quad mesh into a
8572 * database. Variables will be either node-centered or zone-
8573 * centered.
8574 *
8575 * Return: Success: Object ID
8576 *
8577 * Failure: -1
8578 *
8579 * Programmer: matzke@viper
8580 * Tue Nov 8 12:57:08 PST 1994
8581 *
8582 * Modifications:
8583 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8584 * I replaced API_END with API_END_NOPOP.
8585 *
8586 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8587 * Added a check for variable name validity.
8588 *
8589 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8590 * Made the error messages a little better.
8591 *
8592 * Robb Matzke, 2000-05-23
8593 * The old table of contents is discarded if the directory changes.
8594 *
8595 * Mark C. Miller, Wed Nov 11 09:19:20 PST 2009
8596 * Added check for valid centering.
8597 *
8598 * Mark C. Miller, Thu Feb 4 11:29:35 PST 2010
8599 * Removed upper bound restriction for nvars.
8600 *-------------------------------------------------------------------------*/
8601 PUBLIC int
DBPutQuadvar(DBfile * dbfile,const char * vname,const char * mname,int nvars,char const * const * varnames,DBVCP2_t vars,int const * dims,int ndims,DBVCP2_t mixvars,int mixlen,int datatype,int centering,DBoptlist const * optlist)8602 DBPutQuadvar(DBfile *dbfile, const char *vname, const char *mname, int nvars,
8603 char const * const *varnames, DBVCP2_t vars, int const *dims, int ndims,
8604 DBVCP2_t mixvars, int mixlen, int datatype, int centering,
8605 DBoptlist const *optlist)
8606 {
8607 int i, retval, is_empty = 1;
8608
8609 API_BEGIN2("DBPutQuadvar", int, -1, vname) {
8610 if (!dbfile)
8611 API_ERROR(NULL, E_NOFILE);
8612 if (SILO_Globals.enableGrabDriver == TRUE)
8613 API_ERROR("DBPutQuadvar", E_GRABBED) ;
8614 if (!vname || !*vname)
8615 API_ERROR("quadvar name", E_BADARGS);
8616 if (db_VariableNameValid(vname) == 0)
8617 API_ERROR("quadvar name", E_INVALIDNAME);
8618 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, vname))
8619 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8620 if (!mname || !*mname)
8621 API_ERROR("quadmesh name", E_BADARGS);
8622 if (db_VariableNameValid(mname) == 0)
8623 API_ERROR("quadmesh name", E_INVALIDNAME);
8624 if (ndims < 0)
8625 API_ERROR("ndims", E_BADARGS);
8626 if (!dims)
8627 API_ERROR("dims==0", E_BADARGS);
8628 for (i = 0; i < ndims; i++)
8629 {
8630 if (dims[i] != 0)
8631 {
8632 is_empty = 0;
8633 break;
8634 }
8635 }
8636 if (!is_empty)
8637 {
8638 int i;
8639 void **vars2 = (void**) vars;
8640 for (i = 0; i < ndims && dims; i++)
8641 if (!dims[i]) dims = 0;
8642 if (!dims)
8643 API_ERROR("dims=0 || dims[i]=0", E_BADARGS);
8644 if (nvars < 1)
8645 API_ERROR("nvars<1", E_BADARGS);
8646 for (i = 0; i < nvars && vars; i++)
8647 if (!vars2[i]) vars = 0;
8648 vars2 = (void**) mixvars;
8649 for (i = 0; i < nvars && mixvars; i++)
8650 if (!vars2[i]) mixvars = 0;
8651 for (i = 0; i < nvars && varnames; i++)
8652 if (!varnames[i] && !*varnames[i]) varnames = 0;
8653 if (!vars)
8654 API_ERROR("vars=0 || vars[i]=0", E_BADARGS);
8655 if (!varnames)
8656 API_ERROR("varnames=0 || varnames[i]=0||\"\"", E_BADARGS);
8657 if (mixlen < 0)
8658 API_ERROR("mixlen", E_BADARGS);
8659 if (!mixvars && mixlen)
8660 API_ERROR("mixvars", E_BADARGS);
8661 }
8662 else if (!SILO_Globals.allowEmptyObjects)
8663 {
8664 /* this is an empty object but we don't think it was intentional */
8665 API_ERROR("ndims=0", E_EMPTYOBJECT);
8666 }
8667 if (centering != DB_NODECENT && centering != DB_ZONECENT &&
8668 centering != DB_FACECENT && centering != DB_BNDCENT &&
8669 centering != DB_EDGECENT && centering != DB_BLOCKCENT)
8670 API_ERROR("centering", E_BADARGS);
8671 if (!dbfile->pub.p_qv)
8672 API_ERROR(dbfile->pub.name, E_NOTIMP);
8673
8674
8675 retval = (dbfile->pub.p_qv) (dbfile, vname, mname,
8676 nvars, varnames, vars, dims, ndims,
8677 mixvars, mixlen, datatype, centering,
8678 optlist);
8679 db_FreeToc(dbfile);
8680 API_RETURN(retval);
8681 }
8682 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8683 }
8684
8685 /*-------------------------------------------------------------------------
8686 * Function: DBPutQuadvar1
8687 *
8688 * Purpose: Same as DBPutQuadvar except for scalar variables.
8689 *
8690 * Return: Success: Object ID
8691 *
8692 * Failure: -1
8693 *
8694 * Programmer: matzke@viper
8695 * Tue Nov 8 13:07:45 PST 1994
8696 *
8697 * Modifications:
8698 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8699 * I replaced API_END with API_END_NOPOP.
8700 *
8701 * Robb Matzke, 2000-05-23
8702 * The old table of contents is discarded if the directory changes.
8703 *-------------------------------------------------------------------------*/
8704 PUBLIC int
DBPutQuadvar1(DBfile * dbfile,const char * vname,const char * mname,void const * var,int const * dims,int ndims,void const * mixvar,int mixlen,int datatype,int centering,DBoptlist const * optlist)8705 DBPutQuadvar1(DBfile *dbfile, const char *vname, const char *mname, void const *var,
8706 int const *dims, int ndims, void const *mixvar, int mixlen, int datatype,
8707 int centering, DBoptlist const *optlist)
8708 {
8709 char const *varnames[1];
8710 void const *vars[1] = {var};
8711 void const *mixvars[1] = {var};
8712 int retval;
8713
8714 API_BEGIN2("DBPutQuadvar1", int, -1, vname) {
8715 varnames[0] = vname;
8716 vars[0] = var;
8717 mixvars[0] = mixvar;
8718
8719 retval = DBPutQuadvar(dbfile, vname, mname, 1,
8720 varnames, vars, dims, ndims,
8721 mixvars, mixlen,
8722 datatype, centering, optlist);
8723 db_FreeToc(dbfile);
8724 API_RETURN(retval);
8725 }
8726 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8727 }
8728
8729 /*-------------------------------------------------------------------------
8730 * Function: DBPutUcdmesh
8731 *
8732 * Purpose: Accepts pointers to the coordinate arrays and writes
8733 * the mesh into a UCD-mesh object in the database.
8734 *
8735 * Return: Success: Object ID
8736 *
8737 * Failure: -1
8738 *
8739 * Programmer: matzke@viper
8740 * Tue Nov 8 13:13:46 PST 1994
8741 *
8742 * Modifications:
8743 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8744 * I replaced API_END with API_END_NOPOP.
8745 *
8746 * Sean Ahern, Mon Nov 2 17:51:55 PST 1998
8747 * Removed the requirement for a non-NULL coordnames parameter.
8748 *
8749 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8750 * Added a check for variable name validity.
8751 *
8752 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8753 * Made the error messages a little better.
8754 *
8755 * Robb Matzke, 2000-05-23
8756 * The old table of contents is discarded if the directory changes.
8757 *-------------------------------------------------------------------------*/
8758 PUBLIC int
DBPutUcdmesh(DBfile * dbfile,const char * name,int ndims,char const * const * coordnames,DBVCP2_t coords,int nnodes,int nzones,const char * zonel_name,const char * facel_name,int datatype,DBoptlist const * optlist)8759 DBPutUcdmesh(DBfile *dbfile, const char *name, int ndims,
8760 char const * const *coordnames, DBVCP2_t coords, int nnodes,
8761 int nzones, const char *zonel_name, const char *facel_name,
8762 int datatype, DBoptlist const *optlist)
8763 {
8764 int retval;
8765 char *zl_name;
8766
8767 API_BEGIN2("DBPutUcdmesh", int, -1, name) {
8768 if (!dbfile)
8769 API_ERROR(NULL, E_NOFILE);
8770 if (SILO_Globals.enableGrabDriver == TRUE)
8771 API_ERROR("DBPutUcdmesh", E_GRABBED) ;
8772 if (!name || !*name)
8773 API_ERROR("UCDmesh name", E_BADARGS);
8774 if (db_VariableNameValid(name) == 0)
8775 API_ERROR("UCDmesh name", E_INVALIDNAME);
8776 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8777 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8778 if (ndims < 0)
8779 API_ERROR("ndims<0", E_BADARGS);
8780 if (nnodes < 0)
8781 API_ERROR("nnodes<0", E_BADARGS);
8782 if (nnodes)
8783 {
8784 int i;
8785 void **coords2 = (void**) coords;
8786 if (nzones <= 0)
8787 API_ERROR("nzones<=0", E_BADARGS);
8788 for (i = 0; i < ndims && coords; i++)
8789 if (coords2[i] == 0) coords = 0;;
8790 if (!coords)
8791 API_ERROR("coords==0 || coords[i]==0", E_BADARGS);
8792 if ((zl_name = (char*)DBGetOption(optlist, DBOPT_PHZONELIST)))
8793 {
8794 if (!zl_name || !*zl_name)
8795 API_ERROR("zonelist name specified with DBOPT_PHZONELIST is null or \"\"", E_BADARGS);
8796 if (db_VariableNameValid(zl_name) == 0)
8797 API_ERROR("zonelist name specified with DBOPT_PHZONELIST", E_INVALIDNAME);
8798 }
8799 else if (zonel_name)
8800 {
8801 if (!*zonel_name)
8802 API_ERROR("zonel_name==\"\"", E_BADARGS);
8803 if (db_VariableNameValid(zonel_name) == 0)
8804 API_ERROR("zonel_name", E_INVALIDNAME);
8805 }
8806 else if (facel_name)
8807 {
8808 if (!*facel_name)
8809 API_ERROR("facel_name==\"\"", E_BADARGS);
8810 if (db_VariableNameValid(facel_name) == 0)
8811 API_ERROR("facel_name", E_INVALIDNAME);
8812 }
8813 else
8814 {
8815 API_ERROR("no zonelist or facelist specified", E_BADARGS);
8816 }
8817 }
8818 else if (!SILO_Globals.allowEmptyObjects)
8819 {
8820 /* this is an empty object but we don't know if it was intentional */
8821 API_ERROR("ndims==0 || nnodes==0", E_EMPTYOBJECT);
8822 }
8823
8824 if (!dbfile->pub.p_um)
8825 API_ERROR(dbfile->pub.name, E_NOTIMP);
8826
8827 retval = (dbfile->pub.p_um) (dbfile, name, ndims, coordnames,
8828 coords, nnodes, nzones,
8829 zonel_name, facel_name,
8830 datatype, optlist);
8831 db_FreeToc(dbfile);
8832 API_RETURN(retval);
8833 }
8834 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8835 }
8836
8837 /*-------------------------------------------------------------------------
8838 * Function: DBPutUcdsubmesh
8839 *
8840 * Purpose: Accepts names of parent mesh with coordinate arrays and writes
8841 * the mesh into a UCD-mesh object in the database.
8842 *
8843 * Return: Success: Object ID
8844 *
8845 * Failure: -1
8846 *
8847 * Programmer: reus@ferret
8848 * Wed Dec 9 15:17:00 PST 1998
8849 *
8850 * Modifications:
8851 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8852 * Added a check for variable name validity.
8853 *
8854 * Robb Matzke, 2000-05-23
8855 * The old table of contents is discarded if the directory changes.
8856 *-------------------------------------------------------------------------*/
8857 PUBLIC int
DBPutUcdsubmesh(DBfile * dbfile,const char * name,const char * parentmesh,int nzones,const char * zonel_name,const char * facel_name,DBoptlist const * optlist)8858 DBPutUcdsubmesh(DBfile *dbfile, const char *name, const char *parentmesh,
8859 int nzones, const char *zonel_name, const char *facel_name,
8860 DBoptlist const *optlist)
8861 {
8862 int retval;
8863
8864 API_DEPRECATE2("DBPutUcdsubmesh", int, -1, name, 4, 6, "MRG Trees") {
8865 if (!dbfile)
8866 API_ERROR(NULL, E_NOFILE);
8867 if (SILO_Globals.enableGrabDriver == TRUE)
8868 API_ERROR("DBPutUcdsubmesh", E_GRABBED) ;
8869 if (!name || !*name)
8870 API_ERROR("mesh name", E_BADARGS);
8871 if (db_VariableNameValid(name) == 0)
8872 API_ERROR("mesh name", E_INVALIDNAME);
8873 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
8874 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8875 if (!parentmesh || !*parentmesh)
8876 API_ERROR("parent mesh name", E_BADARGS);
8877 if (db_VariableNameValid(parentmesh) == 0)
8878 API_ERROR("parent mesh name", E_INVALIDNAME);
8879 if (nzones < 0)
8880 API_ERROR("nzones", E_BADARGS);
8881 if (!dbfile->pub.p_sm)
8882 API_ERROR(dbfile->pub.name, E_NOTIMP);
8883
8884
8885 retval = (dbfile->pub.p_sm) (dbfile, name, parentmesh,
8886 nzones, zonel_name,
8887 facel_name, optlist);
8888 db_FreeToc(dbfile);
8889 API_RETURN(retval);
8890 }
8891 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
8892 }
8893
8894 /*-------------------------------------------------------------------------
8895 * Function: DBPutUcdvar
8896 *
8897 * Purpose: Writes a variable associated with a UCD mesh into the
8898 * database. Note that variables will be either node-centered
8899 * or zone-centered. A UCD-var object contains the variable
8900 * values, plus the object ID of the associated UCD mesh. Other
8901 * information can also be included. This function is useful
8902 * for writing vector and tensor fields, wereas the companion
8903 * function, DBPutUcdvar1(), is appropriate for writing
8904 * scalar fields.
8905 *
8906 * Return: Success: Object ID
8907 *
8908 * Failure: -1
8909 *
8910 * Programmer: robb@cloud
8911 * Wed Nov 9 12:02:56 EST 1994
8912 *
8913 * Modifications:
8914 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
8915 * I replaced API_END with API_END_NOPOP.
8916 *
8917 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
8918 * Added a check for variable name validity.
8919 *
8920 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
8921 * Made the error messages a little better.
8922 *
8923 * Robb Matzke, 2000-05-23
8924 * The old table of contents is discarded if the directory changes.
8925 *
8926 * Mark C. Miller, Wed Nov 11 09:19:20 PST 2009
8927 * Added check for valid centering.
8928 *
8929 * Mark C. Miller, Thu Feb 4 11:28:55 PST 2010
8930 * Removed upper bound restriction on nvars.
8931 *-------------------------------------------------------------------------*/
8932 PUBLIC int
DBPutUcdvar(DBfile * dbfile,const char * vname,const char * mname,int nvars,char const * const * varnames,DBVCP2_t vars,int nels,DBVCP2_t mixvars,int mixlen,int datatype,int centering,DBoptlist const * optlist)8933 DBPutUcdvar(DBfile *dbfile, const char *vname, const char *mname, int nvars,
8934 char const * const *varnames, DBVCP2_t vars, int nels, DBVCP2_t mixvars,
8935 int mixlen, int datatype, int centering, DBoptlist const *optlist)
8936 {
8937 int retval;
8938
8939 API_BEGIN2("DBPutUcdvar", int, -1, vname) {
8940 if (!dbfile)
8941 API_ERROR(NULL, E_NOFILE);
8942 if (SILO_Globals.enableGrabDriver == TRUE)
8943 API_ERROR("DBPutUcdvar", E_GRABBED) ;
8944 if (!vname || !*vname)
8945 API_ERROR("UCDvar name", E_BADARGS);
8946 if (db_VariableNameValid(vname) == 0)
8947 API_ERROR("UCDvar name", E_INVALIDNAME);
8948 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, vname))
8949 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
8950 if (!mname || !*mname)
8951 API_ERROR("UCDmesh name", E_BADARGS);
8952 if (db_VariableNameValid(mname) == 0)
8953 API_ERROR("UCDmesh name", E_INVALIDNAME);
8954 if (nels < 0)
8955 API_ERROR("nels<0", E_BADARGS);
8956 if (nels)
8957 {
8958 int i;
8959 void **vars2 = (void**) vars;
8960 if (nvars <= 0)
8961 API_ERROR("nvars<0", E_BADARGS);
8962 for (i = 0; i < nvars && vars; i++)
8963 if (vars2[i] == 0) vars = 0;
8964 for (i = 0; i < nvars && varnames; i++)
8965 if (!varnames[i] && !*varnames[i]) varnames = 0;
8966 if (mixlen < 0)
8967 API_ERROR("mixlen", E_BADARGS);
8968 if (mixvars)
8969 {
8970 vars2 = (void**) mixvars;
8971 for (i = 0; i < nvars && mixvars; i++)
8972 if (vars2[i] == 0) mixvars = 0;
8973 }
8974 if (!vars)
8975 API_ERROR("vars=0 || vars[i]=0", E_BADARGS);
8976 if (!varnames)
8977 API_ERROR("varnames=0 || varnames[i]=0", E_BADARGS);
8978 if (mixlen && !mixvars)
8979 API_ERROR("mixvars=0 || mixvars[i]=0", E_BADARGS);
8980 }
8981 else if (!SILO_Globals.allowEmptyObjects)
8982 {
8983 /* this is an empty object but we don't know if it was intentional */
8984 API_ERROR("nvars=0 || nels==0", E_EMPTYOBJECT);
8985 }
8986 if (centering != DB_NODECENT && centering != DB_ZONECENT &&
8987 centering != DB_FACECENT && centering != DB_BNDCENT &&
8988 centering != DB_EDGECENT && centering != DB_BLOCKCENT)
8989 API_ERROR("centering", E_BADARGS);
8990 if (!dbfile->pub.p_uv)
8991 API_ERROR(dbfile->pub.name, E_NOTIMP);
8992
8993 retval = (dbfile->pub.p_uv) (dbfile, vname, mname,
8994 nvars, varnames, vars, nels, mixvars,
8995 mixlen, datatype, centering, optlist);
8996 db_FreeToc(dbfile);
8997 API_RETURN(retval);
8998 }
8999 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9000 }
9001
9002 /*-------------------------------------------------------------------------
9003 * Function: DBPutUcdvar1
9004 *
9005 * Purpose: Same as DBPutUcdvar() except for scalar variables.
9006 *
9007 * Return: Success: Object ID
9008 *
9009 * Failure: -1
9010 *
9011 * Programmer: robb@cloud
9012 * Wed Nov 9 12:14:28 EST 1994
9013 *
9014 * Modifications:
9015 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
9016 * I replaced API_END with API_END_NOPOP.
9017 *
9018 * Robb Matzke, 2000-05-23
9019 * The old table of contents is discarded if the directory changes.
9020 *-------------------------------------------------------------------------*/
9021 PUBLIC int
DBPutUcdvar1(DBfile * dbfile,const char * vname,const char * mname,void const * var,int nels,void const * mixvar,int mixlen,int datatype,int centering,DBoptlist const * optlist)9022 DBPutUcdvar1(DBfile *dbfile, const char *vname, const char *mname, void const *var,
9023 int nels, void const *mixvar, int mixlen, int datatype, int centering,
9024 DBoptlist const *optlist)
9025 {
9026 void const *vars[1] = {var};
9027 void const *mixvars[1] = {mixvar};
9028 char const *varnames[1];
9029 int retval;
9030
9031 API_BEGIN2("DBPutUcdvar1", int, -1, vname)
9032 {
9033 varnames[0] = vname;
9034 vars[0] = var;
9035 mixvars[0] = mixvar;
9036 retval = DBPutUcdvar(dbfile, vname, mname, 1, varnames, vars,
9037 nels, mixvars, mixlen, datatype, centering, optlist);
9038 db_FreeToc(dbfile);
9039 API_RETURN(retval);
9040 }
9041 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9042 }
9043
9044 /*-------------------------------------------------------------------------
9045 * Function: DBPutZonelist
9046 *
9047 * Purpose: Writes a zonelist object into the open database. The name
9048 * assigned to this object can in turn be used as the
9049 * `zonel_name' parameter to the DBPutUcdmesh() function.
9050 *
9051 * Return: Success: 0
9052 *
9053 * Failure: -1
9054 *
9055 * Programmer: robb@cloud
9056 * Wed Nov 9 12:20:22 EST 1994
9057 *
9058 * Modifications:
9059 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
9060 * I replaced API_END with API_END_NOPOP.
9061 *
9062 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
9063 * Added a check for variable name validity.
9064 *
9065 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
9066 * Made the error messages a little better.
9067 *
9068 * Robb Matzke, 2000-05-23
9069 * The old table of contents is discarded if the directory changes.
9070 *-------------------------------------------------------------------------*/
9071 PUBLIC int
DBPutZonelist(DBfile * dbfile,const char * name,int nzones,int ndims,int const * nodelist,int lnodelist,int origin,int const * shapesize,int const * shapecnt,int nshapes)9072 DBPutZonelist(DBfile *dbfile, const char *name, int nzones, int ndims,
9073 int const *nodelist, int lnodelist, int origin, int const *shapesize,
9074 int const *shapecnt, int nshapes)
9075 {
9076 int retval;
9077
9078 API_DEPRECATE2("DBPutZonelist", int, -1, name, 4, 6, "DBPutZonelist2()") {
9079 if (!dbfile)
9080 API_ERROR(NULL, E_NOFILE);
9081 if (SILO_Globals.enableGrabDriver == TRUE)
9082 API_ERROR("DBPutZonelist", E_GRABBED) ;
9083 if (!name || !*name)
9084 API_ERROR("zonelist name", E_BADARGS);
9085 if (db_VariableNameValid(name) == 0)
9086 API_ERROR("zonelist name", E_INVALIDNAME);
9087 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
9088 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
9089 if (nzones < 0)
9090 API_ERROR("nzones", E_BADARGS);
9091 if (nzones)
9092 {
9093 if (ndims <= 0)
9094 API_ERROR("ndims<=0", E_BADARGS);
9095 if (lnodelist <= 0)
9096 API_ERROR("lnodelist<=", E_BADARGS);
9097 if (!nodelist)
9098 API_ERROR("nodelist=0", E_BADARGS);
9099 if (0 != origin && 1 != origin)
9100 API_ERROR("origin!=0||1", E_BADARGS);
9101 if (nshapes <= 0)
9102 API_ERROR("nshapes<=0", E_BADARGS);
9103 if (!shapesize)
9104 API_ERROR("shapesize=0", E_BADARGS);
9105 if (!shapecnt)
9106 API_ERROR("shapecnt=0", E_BADARGS);
9107 }
9108 else if (!SILO_Globals.allowEmptyObjects)
9109 {
9110 /* this is an empty object but we don't know if it was intentional */
9111 API_ERROR("nzones=0", E_EMPTYOBJECT);
9112 }
9113 else
9114 {
9115 lnodelist = 0;
9116 nshapes = 0;
9117 }
9118 if (!dbfile->pub.p_zl)
9119 API_ERROR(dbfile->pub.name, E_NOTIMP);
9120
9121 retval = (dbfile->pub.p_zl) (dbfile, name, nzones, ndims,
9122 nodelist, lnodelist, origin, shapesize,
9123 shapecnt, nshapes);
9124 db_FreeToc(dbfile);
9125 API_RETURN(retval);
9126 }
9127 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9128 }
9129
9130 /*-------------------------------------------------------------------------
9131 * Function: DBPutZonelist2
9132 *
9133 * Purpose: Writes a zonelist object into the open database. The name
9134 * assigned to this object can in turn be used as the
9135 * `zonel_name' parameter to the DBPutUcdmesh() function.
9136 *
9137 * Return: Success: 0
9138 *
9139 * Failure: -1
9140 *
9141 * Programmer: brugger@kickit
9142 * Tue Mar 30 10:41:12 PST 1999
9143 *
9144 * Modifications:
9145 * Jeremy Meredith, Fri May 21 10:04:25 PDT 1999
9146 * Added an option list to the arguments and to the call to p_zl2().
9147 *
9148 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
9149 * Added a check for variable name validity.
9150 *
9151 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
9152 * Made the error messages a little better.
9153 *
9154 * Robb Matzke, 2000-05-23
9155 * The old table of contents is discarded if the directory changes.
9156 *-------------------------------------------------------------------------*/
9157 PUBLIC int
DBPutZonelist2(DBfile * dbfile,const char * name,int nzones,int ndims,int const * nodelist,int lnodelist,int origin,int lo_offset,int hi_offset,int const * shapetype,int const * shapesize,int const * shapecnt,int nshapes,DBoptlist const * optlist)9158 DBPutZonelist2(DBfile *dbfile, const char *name, int nzones, int ndims,
9159 int const *nodelist, int lnodelist, int origin, int lo_offset,
9160 int hi_offset, int const *shapetype, int const *shapesize, int const *shapecnt,
9161 int nshapes, DBoptlist const *optlist)
9162 {
9163 int retval;
9164
9165 API_BEGIN2("DBPutZonelist2", int, -1, name) {
9166 if (!dbfile)
9167 API_ERROR(NULL, E_NOFILE);
9168 if (SILO_Globals.enableGrabDriver == TRUE)
9169 API_ERROR("DBPutZonelist2", E_GRABBED) ;
9170 if (!name || !*name)
9171 API_ERROR("zonelist name", E_BADARGS);
9172 if (db_VariableNameValid(name) == 0)
9173 API_ERROR("zonelist name", E_INVALIDNAME);
9174 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
9175 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
9176 if (nzones < 0)
9177 API_ERROR("nzones", E_BADARGS);
9178 if (nzones)
9179 {
9180 if (ndims <= 0)
9181 API_ERROR("ndims<=0", E_BADARGS);
9182 if (lnodelist <= 0)
9183 API_ERROR("lnodelist<=0", E_BADARGS);
9184 if (nshapes <= 0)
9185 API_ERROR("nshapes<=0", E_BADARGS);
9186 if (!nodelist)
9187 API_ERROR("nodelist=0", E_BADARGS);
9188 if (!shapetype)
9189 API_ERROR("shapetype=0", E_BADARGS);
9190 if (!shapesize)
9191 API_ERROR("shapesize=0", E_BADARGS);
9192 if (!shapecnt)
9193 API_ERROR("shapecnt=0", E_BADARGS);
9194 if (0 != origin && 1 != origin)
9195 API_ERROR("origin!=0||1", E_BADARGS);
9196 if (lo_offset < 0)
9197 API_ERROR("lo_offset<0", E_BADARGS);
9198 if (hi_offset < 0)
9199 API_ERROR("hi_offset<0", E_BADARGS);
9200 #ifndef _MSC_VER
9201 #warning HI AND LO OFFSET NOT VALID IN PRESENCE OF EXPLICIT GHOST LABELS
9202 #endif
9203 }
9204 else if (!SILO_Globals.allowEmptyObjects)
9205 {
9206 /* this is an empty object but we don't know if it was intentional */
9207 API_ERROR("nzones=0", E_EMPTYOBJECT);
9208 }
9209 else
9210 {
9211 lnodelist = 0;
9212 nshapes = 0;
9213 }
9214 if (!dbfile->pub.p_zl2)
9215 API_ERROR(dbfile->pub.name, E_NOTIMP);
9216 retval = (dbfile->pub.p_zl2) (dbfile, name, nzones, ndims,
9217 nodelist, lnodelist, origin, lo_offset,
9218 hi_offset, shapetype, shapesize,
9219 shapecnt, nshapes, optlist);
9220 db_FreeToc(dbfile);
9221 API_RETURN(retval);
9222 }
9223 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9224 }
9225
9226 /*-------------------------------------------------------------------------
9227 * Function: DBPutPHZonelist
9228 *
9229 * Purpose: Writes a polyhedral zonelist object into the open database.
9230 * The name assigned to this object can in turn be used as the
9231 * parameter to a DBOPT_PHZONELIST option in the optlist passed to
9232 * the DBPutUcdmesh() function.
9233 *
9234 * Return: Success: 0
9235 *
9236 * Failure: -1
9237 *
9238 * Programmer: Mark C. Miller
9239 * Tuesday, July 26, 2004
9240 *
9241 *-------------------------------------------------------------------------*/
9242 PUBLIC int
DBPutPHZonelist(DBfile * dbfile,const char * name,int nfaces,int const * nodecnt,int lnodelist,int const * nodelist,const char * extface,int nzones,int const * facecnt,int lfacelist,int const * facelist,int origin,int lo_offset,int hi_offset,DBoptlist const * optlist)9243 DBPutPHZonelist(DBfile *dbfile, const char *name,
9244 int nfaces, int const *nodecnt, int lnodelist, int const *nodelist,
9245 const char *extface, int nzones, int const *facecnt, int lfacelist,
9246 int const *facelist, int origin, int lo_offset, int hi_offset,
9247 DBoptlist const *optlist)
9248 {
9249 int retval;
9250
9251 API_BEGIN2("DBPutPHZonelist", int, -1, name) {
9252
9253 if (!dbfile)
9254 API_ERROR(NULL, E_NOFILE);
9255 if (SILO_Globals.enableGrabDriver == TRUE)
9256 API_ERROR("DBPutPHZonelist", E_GRABBED) ;
9257 if (!name || !*name)
9258 API_ERROR("zonelist name", E_BADARGS);
9259 if (db_VariableNameValid(name) == 0)
9260 API_ERROR("zonelist name", E_INVALIDNAME);
9261 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
9262 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
9263 if (nfaces < 0)
9264 API_ERROR("nfaces<0", E_BADARGS);
9265 if (nfaces)
9266 {
9267 if (0 != origin && 1 != origin)
9268 API_ERROR("origin", E_BADARGS);
9269 if (!nodecnt)
9270 API_ERROR("nodecnt==0", E_BADARGS);
9271 if (!lnodelist)
9272 API_ERROR("lnodelist==0", E_BADARGS);
9273 if (!nodelist)
9274 API_ERROR("nodelist==0", E_BADARGS);
9275 if (nzones < 0)
9276 API_ERROR("nzones<0", E_BADARGS);
9277 if (nzones)
9278 {
9279 if ((lo_offset < 0) || (lo_offset >= nzones))
9280 API_ERROR("lo_offset", E_BADARGS);
9281 if ((hi_offset < 0) || (hi_offset >= nzones))
9282 API_ERROR("hi_offset", E_BADARGS);
9283 if (lo_offset > hi_offset)
9284 API_ERROR("hi_offset", E_BADARGS);
9285 if (!facecnt)
9286 API_ERROR("facecnt==0", E_BADARGS);
9287 if (!lfacelist)
9288 API_ERROR("lfacelist==0", E_BADARGS);
9289 if (!facelist)
9290 API_ERROR("facelist==0", E_BADARGS);
9291 }
9292 }
9293 else if (!SILO_Globals.allowEmptyObjects)
9294 {
9295 /* this is an empty object but we don't know if it was intentional */
9296 API_ERROR("nfaces==0", E_EMPTYOBJECT);
9297 }
9298 if (!dbfile->pub.p_phzl)
9299 API_ERROR(dbfile->pub.name, E_NOTIMP);
9300
9301 retval = (dbfile->pub.p_phzl) (dbfile, name, nfaces, nodecnt,
9302 lnodelist, nodelist, extface,
9303 nzones, facecnt, lfacelist, facelist,
9304 origin, lo_offset, hi_offset,
9305 optlist);
9306
9307 db_FreeToc(dbfile);
9308 API_RETURN(retval);
9309 }
9310 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9311 }
9312
9313 /*-------------------------------------------------------------------------
9314 * Function: DBPutCsgmesh
9315 *
9316 * Purpose: Writes a CSG (Constructive Solid Geometry) mesh object to
9317 * a silo database.
9318 *
9319 * Return: Success: Object ID
9320 *
9321 * Failure: -1
9322 *
9323 * Programmer: Mark C. Miller
9324 * Wed Jul 27 14:22:03 PDT 2005
9325 *-------------------------------------------------------------------------*/
9326 PUBLIC int
DBPutCsgmesh(DBfile * dbfile,const char * name,int ndims,int nbounds,const int * typeflags,const int * bndids,const void * coeffs,int lcoeffs,int datatype,const double * extents,const char * zonel_name,DBoptlist const * optlist)9327 DBPutCsgmesh(DBfile *dbfile, const char *name, int ndims,
9328 int nbounds,
9329 const int *typeflags, const int *bndids/*optional*/,
9330 const void *coeffs, int lcoeffs, int datatype,
9331 const double *extents, const char *zonel_name, DBoptlist const *optlist)
9332 {
9333 int retval;
9334
9335 API_BEGIN2("DBPutCsgmesh", int, -1, name) {
9336 if (!dbfile)
9337 API_ERROR(NULL, E_NOFILE);
9338 if (SILO_Globals.enableGrabDriver == TRUE)
9339 API_ERROR("DBPutCsgmesh", E_GRABBED) ;
9340 if (!name || !*name)
9341 API_ERROR("CSGmesh name", E_BADARGS);
9342 if (db_VariableNameValid(name) == 0)
9343 API_ERROR("CSGmesh name", E_INVALIDNAME);
9344 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
9345 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
9346 if (nbounds < 0)
9347 API_ERROR("nbounds<0", E_BADARGS);
9348 if (nbounds)
9349 {
9350 if (ndims < 0)
9351 API_ERROR("ndims<0", E_BADARGS);
9352 if (lcoeffs < 0)
9353 API_ERROR("lcoeffs<0", E_BADARGS);
9354 if (!(ndims == 2 || ndims == 3))
9355 API_ERROR("ndims must be either 2 or 3", E_BADARGS);
9356 if (!typeflags) API_ERROR("typeflags==0", E_BADARGS);
9357 if (!coeffs) API_ERROR("coeffs==0", E_BADARGS);
9358 if (!extents) API_ERROR("extents==0", E_BADARGS);
9359 if (!zonel_name || !*zonel_name) API_ERROR("zonel_name", E_BADARGS);
9360 if (db_VariableNameValid(zonel_name) == 0)
9361 API_ERROR("zonelist name", E_INVALIDNAME);
9362 }
9363 else if (!SILO_Globals.allowEmptyObjects)
9364 {
9365 API_ERROR("nbounds==0 || ndims==0 || lcoeffs==0", E_EMPTYOBJECT);
9366 }
9367 if (!dbfile->pub.p_csgm)
9368 API_ERROR(dbfile->pub.name, E_NOTIMP);
9369
9370 retval = (dbfile->pub.p_csgm) (dbfile, name, ndims,
9371 nbounds, typeflags, bndids, coeffs,
9372 lcoeffs, datatype, extents, zonel_name,
9373 optlist);
9374
9375 db_FreeToc(dbfile);
9376 API_RETURN(retval);
9377 }
9378 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9379 }
9380
9381 /*-------------------------------------------------------------------------
9382 * Function: DBGetCsgmesh
9383 *
9384 * Purpose: Allocates a DBcsgmesh data structure and reads a CSG mesh
9385 * from the data file.
9386 *
9387 * Return: Success: Pointer to the new DBcsgmesh struct
9388 *
9389 * Failure: NULL
9390 *
9391 * Programmer: Mark C. Miller
9392 * Wed Jul 27 14:22:03 PDT 2005
9393 *
9394 *-------------------------------------------------------------------------*/
9395 PUBLIC DBcsgmesh *
DBGetCsgmesh(DBfile * dbfile,const char * name)9396 DBGetCsgmesh(DBfile *dbfile, const char *name)
9397 {
9398 DBcsgmesh *csgm = NULL;
9399
9400 API_BEGIN2("DBGetCsgmesh", DBcsgmesh *, NULL, name) {
9401 if (!dbfile)
9402 API_ERROR(NULL, E_NOFILE);
9403 if (SILO_Globals.enableGrabDriver == TRUE)
9404 API_ERROR("DBGetCsgmesh", E_GRABBED) ;
9405 if (!name || !*name)
9406 API_ERROR("CSGmesh name", E_BADARGS);
9407 if (!dbfile->pub.g_csgm)
9408 API_ERROR(dbfile->pub.name, E_NOTIMP);
9409 csgm = ((dbfile->pub.g_csgm) (dbfile, name));
9410 if (!csgm)
9411 {
9412 API_RETURN(NULL);
9413 }
9414 API_RETURN(csgm);
9415 }
9416 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9417 }
9418
9419 /*-------------------------------------------------------------------------
9420 * Function: DBPutCSGZonelist
9421 *
9422 * Purpose: Writes a CSG zonelist object into the open database.
9423 * The name assigned to this object can in turn be used as the
9424 * `zonel_name' parameter to the DBPutCsgmesh() function.
9425 *
9426 * Return: Success: 0
9427 *
9428 * Failure: -1
9429 *
9430 * Programmer: Mark C. Miller
9431 * Wed Jul 27 14:22:03 PDT 2005
9432 *-------------------------------------------------------------------------*/
9433
9434 PUBLIC int
DBPutCSGZonelist(DBfile * dbfile,const char * name,int nregs,const int * typeflags,const int * leftids,const int * rightids,const void * xforms,int lxforms,int datatype,int nzones,const int * zonelist,DBoptlist const * optlist)9435 DBPutCSGZonelist(DBfile *dbfile, const char *name, int nregs,
9436 const int *typeflags,
9437 const int *leftids, const int *rightids,
9438 const void *xforms, int lxforms, int datatype,
9439 int nzones, const int *zonelist, DBoptlist const *optlist)
9440 {
9441 int retval;
9442
9443 API_BEGIN2("DBPutCSGZonelist", int, -1, name) {
9444 if (!dbfile)
9445 API_ERROR(NULL, E_NOFILE);
9446 if (SILO_Globals.enableGrabDriver == TRUE)
9447 API_ERROR("DBPutCSGZonelist", E_GRABBED) ;
9448 if (!name || !*name)
9449 API_ERROR("zonelist name", E_BADARGS);
9450 if (db_VariableNameValid(name) == 0)
9451 API_ERROR("zonelist name", E_INVALIDNAME);
9452 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
9453 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
9454 if (nzones)
9455 {
9456 if (nregs < 0)
9457 API_ERROR("nregs", E_BADARGS);
9458 if (nzones < 0)
9459 API_ERROR("nzones", E_BADARGS);
9460 if (!typeflags)
9461 API_ERROR("typeflags", E_BADARGS);
9462 if (!leftids)
9463 API_ERROR("leftids", E_BADARGS);
9464 if (!rightids)
9465 API_ERROR("rightids", E_BADARGS);
9466 if (!zonelist)
9467 API_ERROR("zonelist", E_BADARGS);
9468 if ((xforms && lxforms <= 0) || (!xforms && lxforms > 0))
9469 API_ERROR("xforms and lxforms", E_BADARGS);
9470 }
9471 else if (!SILO_Globals.allowEmptyObjects)
9472 {
9473 /* this is an empty object but we don't know if it was intentional */
9474 API_ERROR("nregs==0 || nzones==0", E_EMPTYOBJECT);
9475 }
9476
9477 if (!dbfile->pub.p_csgzl)
9478 API_ERROR(dbfile->pub.name, E_NOTIMP);
9479
9480 retval = (dbfile->pub.p_csgzl) (dbfile, name, nregs,
9481 typeflags, leftids, rightids,
9482 xforms, lxforms, datatype,
9483 nzones, zonelist, optlist);
9484 db_FreeToc(dbfile);
9485 API_RETURN(retval);
9486 }
9487 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9488 }
9489
9490 /*-------------------------------------------------------------------------
9491 * Function: DBGetCSGZonelist
9492 *
9493 * Purpose: Allocate and read a DBcsgzonelist structure.
9494 *
9495 * Return: Success: ptr to new DBcsgzonelist.
9496 *
9497 * Failure: NULL
9498 *
9499 * Programmer: Mark C. Miller
9500 * Wed Jul 27 14:22:03 PDT 2005
9501 *
9502 *-------------------------------------------------------------------------*/
9503 PUBLIC DBcsgzonelist*
DBGetCSGZonelist(DBfile * dbfile,const char * name)9504 DBGetCSGZonelist(DBfile *dbfile, const char *name)
9505 {
9506 DBcsgzonelist * retval = NULL;
9507
9508 API_BEGIN2("DBGetCSGZonelist", DBcsgzonelist *, NULL, name) {
9509 if (!dbfile)
9510 API_ERROR(NULL, E_NOFILE);
9511 if (SILO_Globals.enableGrabDriver == TRUE)
9512 API_ERROR("DBGetCSGZonelist", E_GRABBED) ;
9513 if (!name || !*name)
9514 API_ERROR("CSG zonelist name", E_BADARGS);
9515 if (!dbfile->pub.g_csgzl)
9516 API_ERROR(dbfile->pub.name, E_NOTIMP);
9517
9518 retval = (dbfile->pub.g_csgzl) (dbfile, name);
9519 API_RETURN(retval);
9520 }
9521 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9522 }
9523
9524 /*-------------------------------------------------------------------------
9525 * Function: DBPutCsgvar
9526 *
9527 * Purpose: Writes a variable associated with a CSG mesh into the
9528 * database. Note that variables will be either
9529 * boundary-centered or zone-centered. A CSG-var object
9530 * contains the variable values, plus the object ID of the
9531 * associated CSG mesh. Other information can also be included.
9532 *
9533 * Return: Success: Object ID
9534 *
9535 * Failure: -1
9536 *
9537 * Programmer: Mark C. Miller
9538 * Wed Jul 27 14:22:03 PDT 2005
9539 *
9540 *-------------------------------------------------------------------------*/
9541 PUBLIC int
DBPutCsgvar(DBfile * dbfile,const char * vname,const char * meshname,int nvars,char const * const * varnames,DBVCP2_t _vars,int nvals,int datatype,int centering,DBoptlist const * optlist)9542 DBPutCsgvar(DBfile *dbfile, const char *vname, const char *meshname,
9543 int nvars, char const * const *varnames, DBVCP2_t _vars,
9544 int nvals, int datatype, int centering, DBoptlist const *optlist)
9545 {
9546 int retval;
9547 void const * const *vars = (void const * const *) _vars;
9548
9549 API_BEGIN2("DBPutCsgvar", int, -1, vname) {
9550 if (!dbfile)
9551 API_ERROR(NULL, E_NOFILE);
9552 if (SILO_Globals.enableGrabDriver == TRUE)
9553 API_ERROR("DBPutCsgvar", E_GRABBED) ;
9554 if (!vname || !*vname)
9555 API_ERROR("CSGvar name", E_BADARGS);
9556 if (db_VariableNameValid(vname) == 0)
9557 API_ERROR("CSGvar name", E_INVALIDNAME);
9558 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, vname))
9559 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
9560 if (nvals < 0)
9561 API_ERROR("nvals<0", E_BADARGS);
9562 if (nvals)
9563 {
9564 int i;
9565 if (!meshname || !*meshname)
9566 API_ERROR("CSGmesh name", E_BADARGS);
9567 if (nvars <= 0)
9568 API_ERROR("nvars<0", E_BADARGS);
9569 if (db_VariableNameValid(meshname) == 0)
9570 API_ERROR("CSGmesh name", E_INVALIDNAME);
9571 for (i = 0; i < nvars && vars; i++)
9572 if (!vars[i]) vars = 0;
9573 for (i = 0; i < nvars && varnames; i++)
9574 if (!varnames[i] && !*varnames[i]) varnames = 0;
9575 if (!vars) API_ERROR("vars==0 || vars[i]==0", E_BADARGS);
9576 if (!varnames) API_ERROR("varnames==0 || varnames[i]==0", E_BADARGS);
9577 if (!(centering == DB_ZONECENT || centering == DB_BNDCENT))
9578 API_ERROR("centering", E_BADARGS);
9579 }
9580 else if (!SILO_Globals.allowEmptyObjects)
9581 {
9582 API_ERROR("nvars=0 || nvals=0", E_EMPTYOBJECT);
9583 }
9584 if (!dbfile->pub.p_csgv)
9585 API_ERROR(dbfile->pub.name, E_NOTIMP);
9586
9587 retval = (dbfile->pub.p_csgv) (dbfile, vname, meshname,
9588 nvars, varnames, vars, nvals,
9589 datatype, centering, optlist);
9590 db_FreeToc(dbfile);
9591 API_RETURN(retval);
9592 }
9593 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9594 }
9595
9596 /*-------------------------------------------------------------------------
9597 * Function: DBGetCsgvar
9598 *
9599 * Purpose: Allocates a DBcsgvar structure and reads a variable associated
9600 * with a CSG mesh from the database.
9601 *
9602 * Return: Success: Pointer to the new DBucdvar struct
9603 *
9604 * Failure: NULL
9605 *
9606 * Programmer: matzke@viper
9607 * Tue Nov 8 11:04:35 PST 1994
9608 *
9609 * Modifications:
9610 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
9611 * Added a check for variable name validity.
9612 *
9613 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
9614 * Made the error messages a little better.
9615 *-------------------------------------------------------------------------*/
9616 PUBLIC DBcsgvar *
DBGetCsgvar(DBfile * dbfile,const char * name)9617 DBGetCsgvar(DBfile *dbfile, const char *name)
9618 {
9619 DBcsgvar * retval = NULL;
9620
9621 API_BEGIN2("DBGetCsgvar", DBcsgvar *, NULL, name) {
9622 if (!dbfile)
9623 API_ERROR(NULL, E_NOFILE);
9624 if (SILO_Globals.enableGrabDriver == TRUE)
9625 API_ERROR("DBGetCsgvar", E_GRABBED) ;
9626 if (!name || !*name)
9627 API_ERROR("CSGvar name", E_BADARGS);
9628 if (!dbfile->pub.g_csgv)
9629 API_ERROR(dbfile->pub.name, E_NOTIMP);
9630
9631 retval = (dbfile->pub.g_csgv) (dbfile, name);
9632 API_RETURN(retval);
9633 }
9634 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
9635 }
9636
9637
9638 /*----------------------------------------------------------------------
9639 * Routine _DBstrprint
9640 *
9641 * Purpose
9642 *
9643 * This function prints an array of strings in either column- or
9644 * row-major order.
9645 *
9646 * Programmer
9647 *
9648 * Jeff Long
9649 * Arguments:
9650 * fp File pointer for output of printing
9651 * strs Array of character strings to print
9652 * nstrs Number of character strings in 'strs'
9653 * order Printing order: 'c' for by-column, 'r' for by-row
9654 * left_margin Width of left margin (in chars)
9655 * col_margin Width of empty spaces between columns (in chars)
9656 * line_width Width of entire output line.
9657 *
9658 * Modified
9659 * Robb Matzke, Wed Jan 11 06:41:23 PST 1995
9660 * Changed name from strprint since that conflicted with MeshTV.
9661 *
9662 * Eric Brugger, Tue Feb 7 09:06:58 PST 1995
9663 * I modified the argument declaration to reflect argument promotions.
9664 *---------------------------------------------------------------------*/
9665 INTERNAL int
_DBstrprint(FILE * fp,char * strs[],int nstrs,int order,int left_margin,int col_margin,int line_width)9666 _DBstrprint(FILE *fp, char *strs[], int nstrs, int order, int left_margin,
9667 int col_margin, int line_width)
9668 {
9669 char **sorted_strs = NULL;
9670 int i, j, index;
9671 int maxwidth;
9672 int nrows, ncols;
9673 double dtmp;
9674 char *me = "_DBstrprint";
9675
9676 if (nstrs <= 0)
9677 return db_perror("nstrs", E_BADARGS, me);
9678 if (left_margin < 0 || left_margin > line_width) {
9679 return db_perror("left margin", E_BADARGS, me);
9680 }
9681
9682 /*----------------------------------------
9683 * Sort strings into alphabetical order.
9684 *---------------------------------------*/
9685 sorted_strs = ALLOC_N(char *, nstrs);
9686 for (i = 0; i < nstrs; i++)
9687 sorted_strs[i] = strs[i];
9688
9689 _DBsort_list(sorted_strs, nstrs);
9690
9691 /*----------------------------------------
9692 * Find maximum string width.
9693 *---------------------------------------*/
9694 maxwidth = strlen(sorted_strs[0]);
9695
9696 for (i = 1; i < nstrs; i++) {
9697 maxwidth = MAX(maxwidth, (int)strlen(sorted_strs[i]));
9698 }
9699
9700 /*----------------------------------------
9701 * Determine number of columns and rows.
9702 *---------------------------------------*/
9703 ncols = (line_width - left_margin) / (maxwidth + col_margin);
9704 if (ncols <= 0) {
9705 FREE(sorted_strs);
9706 return (OOPS);
9707 }
9708
9709 dtmp = (double)nstrs / (double)ncols;
9710 nrows = (int)ceil(dtmp);
9711 if (nrows <= 0) {
9712 FREE(sorted_strs);
9713 return -1;
9714 }
9715
9716 /*----------------------------------------
9717 * Print strings in requested order.
9718 *---------------------------------------*/
9719
9720 if (order == 'c') {
9721 /*------------------------------
9722 * Print by column
9723 *-----------------------------*/
9724
9725 for (i = 0; i < nrows; i++) {
9726 index = i;
9727
9728 fprintf(fp, "%*s", left_margin, " ");
9729
9730 for (j = 0; j < ncols; j++) {
9731
9732 fprintf(fp, "%-*s%*s", maxwidth, sorted_strs[index],
9733 col_margin, " ");
9734
9735 index += nrows;
9736 if (index >= nstrs)
9737 break;
9738 }
9739 fprintf(fp, "\n");
9740 }
9741
9742 }
9743 else {
9744 /*------------------------------
9745 * Print by row
9746 *-----------------------------*/
9747
9748 for (i = 0; i < nrows; i++) {
9749 index = i * ncols;
9750
9751 fprintf(fp, "%*s", left_margin, " ");
9752
9753 for (j = 0; j < ncols; j++) {
9754
9755 fprintf(fp, "%-*s%*s", maxwidth, sorted_strs[index],
9756 col_margin, " ");
9757
9758 index++;
9759 if (index >= nstrs)
9760 break;
9761 }
9762 fprintf(fp, "\n");
9763 }
9764
9765 }
9766
9767 FREE(sorted_strs);
9768 return 0;
9769 }
9770
9771 static int
qsort_strcmp(const void * str1,const void * str2)9772 qsort_strcmp(const void *str1, const void *str2)
9773 {
9774 return(strcmp(*((const char **)str1), *((const char **)str2)));
9775 }
9776
9777 /*----------------------------------------------------------------------
9778 * Function _DBsort_list
9779 *
9780 * Purpose
9781 *
9782 * Sort a list of character strings. Algorithm taken from
9783 * _SX_sort_lists() -- courtesy of Stewart Brown.
9784 *
9785 * Modified
9786 * Robb Matzke, Wed Jan 11 06:39:16 PST 1995
9787 * Changed name from sort_list because it conflicts with MeshTV.
9788 *
9789 * Sean Ahern, Fri Mar 2 09:45:05 PST 2001
9790 * Changed this sort to a qsort, as suggested by Dan Schikore.
9791 *---------------------------------------------------------------------*/
9792 INTERNAL void
_DBsort_list(char ** ss,int n)9793 _DBsort_list(char **ss, int n)
9794 {
9795 qsort(ss, n, sizeof(char *), qsort_strcmp);
9796 }
9797
9798 /*---------------------------------------------------------------------------
9799 * arrminmax - Return the min and max value of the given float array.
9800 *
9801 * Modified
9802 * Robb Matzke, Wed Jan 11 06:43:08 PST 1995
9803 * Changed name from arrminmax since that conflicted with MeshTV.
9804 *
9805 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
9806 * Made the error messages a little better.
9807 *---------------------------------------------------------------------------*/
9808 INTERNAL int
_DBarrminmax(float arr[],int len,float * arr_min,float * arr_max)9809 _DBarrminmax(float arr[], int len, float *arr_min, float *arr_max)
9810 {
9811 int i;
9812 char *me = "_DBarrminmax";
9813
9814 if (!arr)
9815 return db_perror("arr pointer", E_BADARGS, me);
9816 if (len <= 0)
9817 return db_perror("len", E_BADARGS, me);
9818
9819 *arr_min = arr[0];
9820 *arr_max = arr[0];
9821
9822 for (i = 1; i < len; i++)
9823 {
9824 *arr_min = MIN(*arr_min, arr[i]);
9825 *arr_max = MAX(*arr_max, arr[i]);
9826 }
9827
9828 return 0;
9829 }
9830
9831 /*---------------------------------------------------------------------------
9832 * iarrminmax - Return the min and max value of the given int array.
9833 *
9834 * Modified:
9835 * Robb Matzke, Wed Jan 11 06:43:42 PST 1995
9836 * Changed name from iarrminmax since that conflicted with MeshTV.
9837 *
9838 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
9839 * Made the error messages a little better.
9840 *---------------------------------------------------------------------------*/
9841 INTERNAL int
_DBiarrminmax(int arr[],int len,int * arr_min,int * arr_max)9842 _DBiarrminmax(int arr[], int len, int *arr_min, int *arr_max)
9843 {
9844 int i;
9845 char *me = "_DBiarrminmax";
9846
9847 if (!arr)
9848 return db_perror("arr pointer", E_BADARGS, me);
9849 if (len <= 0)
9850 return db_perror("len", E_BADARGS, me);
9851
9852 *arr_min = arr[0];
9853 *arr_max = arr[0];
9854
9855 for (i = 1; i < len; i++)
9856 {
9857 *arr_min = MIN(*arr_min, arr[i]);
9858 *arr_max = MAX(*arr_max, arr[i]);
9859 }
9860
9861 return 0;
9862 }
9863
9864 /*---------------------------------------------------------------------------
9865 * darrminmax - Return the min and max value of the given double array.
9866 *
9867 * Modified:
9868 * Robb Matzke, Wed Jan 11 06:44:16 PST 1995
9869 * Changed name from darrminmax since that conflicted with MeshTV.
9870 *
9871 * Sean Ahern, Tue Sep 28 11:00:13 PDT 1999
9872 * Made the error messages a little better.
9873 *---------------------------------------------------------------------------*/
9874 INTERNAL int
_DBdarrminmax(double arr[],int len,double * arr_min,double * arr_max)9875 _DBdarrminmax(double arr[], int len, double *arr_min, double *arr_max)
9876 {
9877 int i;
9878 char *me = "_DBdarrminmax";
9879
9880 if (!arr)
9881 return db_perror("arr pointer", E_BADARGS, me);
9882 if (len <= 0)
9883 return db_perror("len", E_BADARGS, me);
9884
9885 *arr_min = arr[0];
9886 *arr_max = arr[0];
9887
9888 for (i = 1; i < len; i++)
9889 {
9890 *arr_min = MIN(*arr_min, arr[i]);
9891 *arr_max = MAX(*arr_max, arr[i]);
9892 }
9893
9894 return 0;
9895 }
9896
9897 /***********************************************************************
9898 *
9899 * Purpose: Return the min and max values of a subset of the given
9900 * array.
9901 *
9902 * Programmer: Eric S. Brugger
9903 * Date: May 26, 1995
9904 *
9905 * Input arguments:
9906 * arr : The array to evaluate.
9907 * datatype : The data type of the array.
9908 * nx : The x dimension of the array.
9909 * ny : The y dimension of the array.
9910 * nz : The z dimension of the array.
9911 * ixmin : The 0 origin min index in the x direction.
9912 * ixmax : The 0 origin max index in the x direction.
9913 * iymin : The 0 origin min index in the y direction.
9914 * iymax : The 0 origin max index in the y direction.
9915 * izmin : The 0 origin min index in the z direction.
9916 * izmax : The 0 origin max index in the z direction.
9917 *
9918 * Output arguments:
9919 * amin : The minimum value in the array.
9920 * amax : The maximum value in the array.
9921 *
9922 * Input/Output arguments:
9923 *
9924 * Notes:
9925 *
9926 * Modifications:
9927 * Eric Brugger, Tue May 30 17:03:51 PDT 1995
9928 * I changed the initial calculation of the index to use ixmin,
9929 * iymin, and izmin instead of i, j, k which were not initialized.
9930 *
9931 * Jim Reus, 23 Apr 97
9932 * I changed to prototype form, moved location within file.
9933 *
9934 * Eric Brugger, Thu Sep 23 15:05:18 PDT 1999
9935 * I removed the unused argument nz.
9936 ***********************************************************************/
9937
9938 INTERNAL int
_DBSubsetMinMax3(float arr[],int datatype,float * amin,float * amax,int nx,int ny,int ixmin,int ixmax,int iymin,int iymax,int izmin,int izmax)9939 _DBSubsetMinMax3(float arr[], int datatype, float *amin, float *amax , int nx,
9940 int ny, int ixmin, int ixmax, int iymin , int iymax,
9941 int izmin, int izmax)
9942 {
9943 int i, j, k, index, nxy;
9944 float tmin, tmax;
9945 double dtmin, dtmax;
9946 double *darr, *damin, *damax;
9947
9948 switch (datatype)
9949 {
9950 case DB_FLOAT:
9951
9952 nxy = nx * ny;
9953
9954 index = INDEX3(ixmin, iymin, izmin, nx, nxy);
9955 tmin = arr[index];
9956 tmax = arr[index];
9957
9958 for (k = izmin; k <= izmax; k++)
9959 {
9960 for (j = iymin; j <= iymax; j++)
9961 {
9962 for (i = ixmin; i <= ixmax; i++)
9963 {
9964 index = INDEX3(i, j, k, nx, nxy);
9965 tmin = MIN(tmin, arr[index]);
9966 tmax = MAX(tmax, arr[index]);
9967 }
9968 }
9969 }
9970
9971 *amin = tmin;
9972 *amax = tmax;
9973 break;
9974
9975 case DB_DOUBLE:
9976
9977 darr = (double *)arr;
9978
9979 nxy = nx * ny;
9980
9981 index = INDEX3(ixmin, iymin, izmin, nx, nxy);
9982 dtmin = darr[index];
9983 dtmax = darr[index];
9984
9985 for (k = izmin; k <= izmax; k++)
9986 {
9987 for (j = iymin; j <= iymax; j++)
9988 {
9989 for (i = ixmin; i <= ixmax; i++)
9990 {
9991 index = INDEX3(i, j, k, nx, nxy);
9992 dtmin = MIN(dtmin, darr[index]);
9993 dtmax = MAX(dtmax, darr[index]);
9994 }
9995 }
9996 }
9997
9998 damin = (double *)amin;
9999 damax = (double *)amax;
10000 *damin = dtmin;
10001 *damax = dtmax;
10002 break;
10003
10004 default:
10005 break;
10006 }
10007
10008 return 0;
10009 }
10010
10011 /*----------------------------------------------------------------------
10012 * Routine CSGM_CalcExtents
10013 *
10014 * Purpose
10015 *
10016 * Return the extents of the given csg mesh.
10017 *
10018 *--------------------------------------------------------------------*/
10019 INTERNAL int
CSGM_CalcExtents(int datatype,int ndims,int nbounds,const int * typeflags,const void * coeffs,double * min_extents,double * max_extents)10020 CSGM_CalcExtents(int datatype, int ndims, int nbounds,
10021 const int *typeflags, const void *coeffs,
10022 double *min_extents, double *max_extents)
10023 {
10024 min_extents[0] = -DBL_MAX;
10025 min_extents[1] = -DBL_MAX;
10026 min_extents[2] = -DBL_MAX;
10027 max_extents[0] = DBL_MAX;
10028 max_extents[1] = DBL_MAX;
10029 max_extents[2] = DBL_MAX;
10030 return 0;
10031 }
10032
10033 /*----------------------------------------------------------------------
10034 * Routine _DBQMCalcExtents
10035 *
10036 * Purpose
10037 *
10038 * Return the extents of the given quad mesh.
10039 *
10040 * Works for 1D, 2D and 3D meshes, collinear or non-collinear.
10041 *
10042 * Modification History
10043 * Jeff Long, 11/16/92
10044 * Modified handling of double precision coords so that extents
10045 * are returned as floats.
10046 *
10047 * Robb Matzke, Wed Jan 11 06:34:09 PST 1995
10048 * Changed name from QM_CalcExtents because it conflicts with MeshTV.
10049 *
10050 * Eric Brugger, Wed Feb 15 08:12:43 PST 1995
10051 * I removed the error message that precision had been lost.
10052 * Their is no loss of precision because all the casts from
10053 * double to float were done on pointers. Casting of a pointer
10054 * just makes the compiler happy and has no impact on the value
10055 * pointed to.
10056 *
10057 * Sean Ahern, Mon Oct 19 18:17:10 PDT 1998
10058 * Added the ability to have the extents returned either as float or
10059 * double.
10060 *--------------------------------------------------------------------*/
10061 INTERNAL int
_DBQMCalcExtents(DBVCP2_t coord_arrays,int datatype,int const * min_index,int const * max_index,int const * dims,int ndims,int coordtype,void * min_extents,void * max_extents)10062 _DBQMCalcExtents(DBVCP2_t coord_arrays, int datatype, int const *min_index,
10063 int const *max_index, int const *dims, int ndims, int coordtype,
10064 void *min_extents, void *max_extents)
10065 {
10066 float *x = NULL, *y = NULL, *z = NULL;
10067 double *dx = NULL, *dy = NULL, *dz = NULL;
10068 double *dmin_extents = NULL, *dmax_extents = NULL;
10069 float *fmin_extents = NULL, *fmax_extents = NULL;
10070 int i, is_empty = 1;
10071 char *me = "_DBQMCalcExtents";
10072
10073 for (i = 0; i < ndims; i++)
10074 {
10075 if (dims[i] > 0)
10076 {
10077 is_empty = 0;
10078 break;
10079 }
10080 }
10081
10082 if (is_empty) return 0;
10083
10084 if (datatype == DB_FLOAT)
10085 {
10086 fmin_extents = (float*)min_extents;
10087 fmax_extents = (float*)max_extents;
10088
10089 /* Initialize extent arrays */
10090 for (i = 0; i < ndims; i++) {
10091 fmin_extents[i] = 0.;
10092 fmax_extents[i] = 0.;
10093 }
10094 } else if (datatype == DB_DOUBLE)
10095 {
10096 dmin_extents = (double*)min_extents;
10097 dmax_extents = (double*)max_extents;
10098
10099 /* Initialize extent arrays */
10100 for (i = 0; i < ndims; i++) {
10101 dmin_extents[i] = 0.;
10102 dmax_extents[i] = 0.;
10103 }
10104 }
10105
10106 /* Read default coordinate variables. */
10107 switch (ndims) {
10108 case 3:
10109 z = ((float**)coord_arrays)[2];
10110 /* Fall through */
10111 case 2:
10112 y = ((float**)coord_arrays)[1];
10113 /* Fall through */
10114 case 1:
10115 x = ((float**)coord_arrays)[0];
10116 break;
10117 default:
10118 break;
10119 }
10120
10121 if (datatype == DB_DOUBLE) {
10122 dx = (double *)x;
10123 dy = (double *)y;
10124 dz = (double *)z;
10125 }
10126
10127 /* Get mesh coordinate extents. */
10128 switch (coordtype) {
10129
10130 case DB_COLLINEAR:
10131
10132 switch (ndims) {
10133 case 3:
10134 if (datatype == DB_DOUBLE) {
10135 dmin_extents[2] = dz[min_index[2]];
10136 dmax_extents[2] = dz[max_index[2]];
10137 }
10138 else {
10139 fmin_extents[2] = z[min_index[2]];
10140 fmax_extents[2] = z[max_index[2]];
10141 }
10142 case 2:
10143 if (datatype == DB_DOUBLE) {
10144 dmin_extents[1] = dy[min_index[1]];
10145 dmax_extents[1] = dy[max_index[1]];
10146 }
10147 else {
10148 fmin_extents[1] = y[min_index[1]];
10149 fmax_extents[1] = y[max_index[1]];
10150 }
10151 case 1:
10152 if (datatype == DB_DOUBLE) {
10153 dmin_extents[0] = dx[min_index[0]];
10154 dmax_extents[0] = dx[max_index[0]];
10155 }
10156 else {
10157 fmin_extents[0] = x[min_index[0]];
10158 fmax_extents[0] = x[max_index[0]];
10159 }
10160 break;
10161 }
10162 break;
10163
10164 case DB_NONCOLLINEAR:
10165
10166 switch (ndims) {
10167 case 3:
10168 if (datatype == DB_DOUBLE) {
10169 _DBSubsetMinMax3((float *)dx, datatype,
10170 (float *)(&dmin_extents[0]),
10171 (float *)(&dmax_extents[0]),
10172 dims[0], dims[1],
10173 min_index[0], max_index[0],
10174 min_index[1], max_index[1],
10175 min_index[2], max_index[2]);
10176 _DBSubsetMinMax3((float *)dy, datatype,
10177 (float *)(&dmin_extents[1]),
10178 (float *)(&dmax_extents[1]),
10179 dims[0], dims[1],
10180 min_index[0], max_index[0],
10181 min_index[1], max_index[1],
10182 min_index[2], max_index[2]);
10183 _DBSubsetMinMax3((float *)dz, datatype,
10184 (float *)(&dmin_extents[2]),
10185 (float *)(&dmax_extents[2]),
10186 dims[0], dims[1],
10187 min_index[0], max_index[0],
10188 min_index[1], max_index[1],
10189 min_index[2], max_index[2]);
10190 }
10191 else {
10192 _DBSubsetMinMax3(x, datatype,
10193 &fmin_extents[0], &fmax_extents[0],
10194 dims[0], dims[1],
10195 min_index[0], max_index[0],
10196 min_index[1], max_index[1],
10197 min_index[2], max_index[2]);
10198 _DBSubsetMinMax3(y, datatype,
10199 &fmin_extents[1], &fmax_extents[1],
10200 dims[0], dims[1],
10201 min_index[0], max_index[0],
10202 min_index[1], max_index[1],
10203 min_index[2], max_index[2]);
10204 _DBSubsetMinMax3(z, datatype,
10205 &fmin_extents[2], &fmax_extents[2],
10206 dims[0], dims[1],
10207 min_index[0], max_index[0],
10208 min_index[1], max_index[1],
10209 min_index[2], max_index[2]);
10210 }
10211 break;
10212 case 2:
10213 if (datatype == DB_DOUBLE) {
10214 _DBSubsetMinMax2((float *)dx, datatype,
10215 (float *)(&dmin_extents[0]),
10216 (float *)(&dmax_extents[0]),
10217 dims[0],
10218 min_index[0], max_index[0],
10219 min_index[1], max_index[1]);
10220 _DBSubsetMinMax2((float *)dy, datatype,
10221 (float *)(&dmin_extents[1]),
10222 (float *)(&dmax_extents[1]),
10223 dims[0],
10224 min_index[0], max_index[0],
10225 min_index[1], max_index[1]);
10226 }
10227 else {
10228
10229 _DBSubsetMinMax2(x, datatype,
10230 &fmin_extents[0], &fmax_extents[0],
10231 dims[0],
10232 min_index[0], max_index[0],
10233 min_index[1], max_index[1]);
10234
10235 _DBSubsetMinMax2(y, datatype,
10236 &fmin_extents[1], &fmax_extents[1],
10237 dims[0],
10238 min_index[0], max_index[0],
10239 min_index[1], max_index[1]);
10240 }
10241 break;
10242 case 1:
10243 return db_perror("1-d noncollinear", E_NOTIMP, me);
10244 }
10245 break;
10246
10247 default:
10248 return db_perror("default case", E_INTERNAL, me);
10249 }
10250
10251 return 0;
10252 }
10253
10254 /*--------------------------------------------------------------------------
10255 * Routine _DBSubsetMinMax2
10256 *
10257 * Purpose
10258 *
10259 * Return the min and max values of a subset of the given array.
10260 *
10261 * Paramters
10262 *
10263 * arr =| The array to evaluate
10264 * datatype =| The type of data pointed to by 'arr'. (float or double)
10265 * amin,amax |= Returned min,max values
10266 * nx,ny =| The dimensions of 'arr'
10267 * ixmin... =| The actual 0-origin indeces to use for subselection
10268 *
10269 * Modified
10270 * Robb Matzke, Wed Jan 11 06:46:23 PST 1995
10271 * Changed name from SubsetMinMax2 since that conflicted with MeshTV.
10272 *
10273 * Eric Brugger, Thu Mar 14 16:22:08 PST 1996
10274 * I corrected a bug in the calculation of the minimum, where it
10275 * got the initial minimum value by indexing into the coordinate
10276 * arrays as 1d arrays instead of a 2d arrays.
10277 *
10278 * Eric Brugger, Thu Sep 23 15:05:18 PDT 1999
10279 * I removed the unused argument ny.
10280 *--------------------------------------------------------------------------*/
10281 INTERNAL int
_DBSubsetMinMax2(void const * arr,int datatype,float * amin,float * amax,int nx,int ixmin,int ixmax,int iymin,int iymax)10282 _DBSubsetMinMax2(void const *arr, int datatype, float *amin, float *amax, int nx,
10283 int ixmin, int ixmax, int iymin, int iymax)
10284 {
10285 int k, j, index;
10286 float tmin, tmax;
10287 double dtmin, dtmax;
10288 double *darr = NULL, *damin = NULL, *damax = NULL;
10289 float *farr = NULL;
10290
10291 switch (datatype) {
10292 case DB_FLOAT:
10293
10294 farr = (float *)arr;
10295
10296 index = INDEX (ixmin, iymin, nx);
10297 tmin = farr[index];
10298 tmax = farr[index];
10299
10300 for (j = iymin; j <= iymax; j++) {
10301 for (k = ixmin; k <= ixmax; k++) {
10302 index = INDEX (k, j, nx);
10303 tmin = MIN (tmin, farr[index]);
10304 tmax = MAX (tmax, farr[index]);
10305 }
10306 }
10307 *amin = tmin;
10308 *amax = tmax;
10309 break;
10310
10311 case DB_DOUBLE:
10312
10313 darr = (double *)arr;
10314
10315 index = INDEX (ixmin, iymin, nx);
10316 dtmin = darr[index];
10317 dtmax = darr[index];
10318
10319 for (j = iymin; j <= iymax; j++) {
10320 for (k = ixmin; k <= ixmax; k++) {
10321 index = INDEX (k, j, nx);
10322 dtmin = MIN (dtmin, darr[index]);
10323 dtmax = MAX (dtmax, darr[index]);
10324 }
10325 }
10326
10327 damin = (double *)amin;
10328 damax = (double *)amax;
10329 *damin = dtmin;
10330 *damax = dtmax;
10331 break;
10332
10333 default:
10334 break;
10335 }
10336 return 0;
10337 }
10338
10339 /*----------------------------------------------------------------------
10340 * Routine UM_CalcExtents
10341 *
10342 * Purpose
10343 *
10344 * Return the extents of the given ucd mesh.
10345 *
10346 * Modifications:
10347 * Sean Ahern, Wed Oct 21 10:55:21 PDT 1998
10348 * Changed the function so that the min_extents and max_extents are
10349 * passed in as void* variables.
10350 *--------------------------------------------------------------------*/
10351 INTERNAL int
UM_CalcExtents(DBVCP2_t coord_arrays,int datatype,int ndims,int nnodes,void * min_extents,void * max_extents)10352 UM_CalcExtents(DBVCP2_t coord_arrays, int datatype, int ndims, int nnodes,
10353 void *min_extents, void *max_extents)
10354 {
10355 int i, j;
10356 double **dcoord_arrays = NULL;
10357 double *dmin_extents = NULL, *dmax_extents = NULL;
10358 float *fmin_extents = NULL, *fmax_extents = NULL;
10359 float **fcoord_arrays = NULL;
10360
10361 if (nnodes <= 0) return 0;
10362
10363 if (datatype == DB_DOUBLE) {
10364
10365 dmin_extents = (double *)min_extents;
10366 dmax_extents = (double *)max_extents;
10367 dcoord_arrays = (double **)coord_arrays;
10368
10369 /* Initialize extent arrays */
10370 for (i = 0; i < ndims; i++) {
10371 dmin_extents[i] = dcoord_arrays[i][0];
10372 dmax_extents[i] = dcoord_arrays[i][0];
10373 }
10374
10375 for (i = 0; i < ndims; i++) {
10376 for (j = 0; j < nnodes; j++) {
10377 dmin_extents[i] = MIN(dmin_extents[i], dcoord_arrays[i][j]);
10378 dmax_extents[i] = MAX(dmax_extents[i], dcoord_arrays[i][j]);
10379 }
10380 }
10381
10382 }
10383 else {
10384 fmin_extents = (float *)min_extents;
10385 fmax_extents = (float *)max_extents;
10386 fcoord_arrays = (float **)coord_arrays;
10387
10388 /* Initialize extent arrays */
10389 for (i = 0; i < ndims; i++) {
10390 fmin_extents[i] = fcoord_arrays[i][0];
10391 fmax_extents[i] = fcoord_arrays[i][0];
10392 }
10393
10394 for (i = 0; i < ndims; i++) {
10395 for (j = 0; j < nnodes; j++) {
10396 fmin_extents[i] = MIN(fmin_extents[i], fcoord_arrays[i][j]);
10397 fmax_extents[i] = MAX(fmax_extents[i], fcoord_arrays[i][j]);
10398 }
10399 }
10400
10401 }
10402
10403 return 0;
10404 }
10405
10406 /*-------------------------------------------------------------------------
10407 * Function: db_ProcessOptlist
10408 *
10409 * Purpose: Process the options list for an object and initializes the
10410 * object's global data. Each object type has its own global data
10411 * so that `cycle' for one type of object is different from
10412 * `cycle' for another type of object. This results form trying
10413 * to stay compatible with the previous version, where each
10414 * object had its own source file with global variables
10415 * declared `static'.
10416 *
10417 * Some objects share the same global data. They are:
10418 * DB_MULTIMESH and DB_MULTIVAR (_mm)
10419 * DB_POINTMESH and DB_POINTVAR (_pm)
10420 * DB_QUADMESH and DB_QUADVAR (_qm)
10421 * DB_UCDMESH and DB_UCDVAR (_um)
10422 *
10423 *
10424 * Return: Success: 0, no options or all options processed.
10425 *
10426 * Failure: >0, number of unrecognized options.
10427 * -1, bad objtype
10428 *
10429 * Programmer: matzke@viper
10430 * Wed Dec 14 13:36:04 PST 1994
10431 *
10432 * Modifications:
10433 * Eric Brugger, Fri Jan 12 18:36:56 PST 1996
10434 * I added the case for DB_MULTIMESH.
10435 *
10436 * Robb Matzke, 18 Jun 1997
10437 * Added DB_ASCII_LABEL for DB_QUADMESH and DB_QUADVAR.
10438 *
10439 * Eric Brugger, Wed Oct 15 15:37:22 PDT 1997
10440 * I added DBOPT_HI_OFFSET and DBOPT_LO_OFFSET to DB_UCDVAR.
10441 *
10442 * Eric Brugger, Thu Oct 16 10:31:26 PDT 1997
10443 * I added DBOPT_MATNOS and DBOPT_NMATNOS to DB_MULTIMAT (which
10444 * is covered by the DB_MULTIMESH case).
10445 *
10446 * Jeremy Meredith, Sept 18 1998
10447 * Added options DBOPT_MATNAME, DBOPT_NMAT, and DBOPT_NMATSPEC
10448 * to DB_MULTIMATSPECIES (covered by DB_MULTIMESH case).
10449 *
10450 * Jeremy Meredith, Fri May 21 10:04:25 PDT 1999
10451 * Added DBOPT_GROUPNUM to the point, quad, and ucd meshes.
10452 * Added DBOPT_BASEINDEX to the quad mesh; set it from the origin if needed.
10453 * Added DBOPT_NODENUM to the ucd mesh.
10454 * Added a DB_ZONELIST type.
10455 * Added DBOPT_ZONENUM to the ucd zonelist.
10456 * Added DBOPT_BLOCKORIGIN, _GROUPORIGIN, and _NGROUPS to the multimesh.
10457 *
10458 * Jeremy Meredith, Wed Jul 7 12:15:31 PDT 1999
10459 * I removed the DBOPT_ORIGIN from the species object.
10460 *
10461 * Sean Ahern, Tue Feb 5 10:22:25 PST 2002
10462 * Added names for materials.
10463 *
10464 * Brad Whitlock, Wed Jan 18 15:36:55 PST 2006
10465 * Added ascii_labels for ucdvars.
10466 *
10467 * Thomas R. Treadway, Wed Jun 28 10:31:45 PDT 2006
10468 * Added topo_dim to ucdmesh.
10469 *
10470 * Thomas R. Treadway, Thu Jul 6 17:05:24 PDT 2006
10471 * Added reference to curve options.
10472 *
10473 * Thomas R. Treadway, Thu Jul 20 11:06:27 PDT 2006
10474 * Added lgroupings, groupings, and groupnames to multimesh options.
10475 *
10476 * Mark C. Miller, Mon Aug 7 17:03:51 PDT 2006
10477 * Added DBOPT_MATCOLORS, DBOPT_MATNAMES options to multimesh
10478 *
10479 * Thomas R. Treadway, Tue Aug 15 14:05:59 PDT 2006
10480 * Added DBOPT_ALLOWMAT0
10481 *
10482 * Mark C. Miller, Tue Sep 8 15:40:51 PDT 2009
10483 * Added names and colors for species.
10484 *
10485 * Mark C. Miller, Wed Sep 23 11:49:34 PDT 2009
10486 * Added DBOPT_LLONGNZNUM for long long global node/zone numbers
10487 * to pointmeshes, ucdmeshes, zonelists.
10488 *
10489 * Mark C. Miller, Thu Nov 5 16:14:12 PST 2009
10490 * Added conserved/extensive options to all var objects.
10491 *
10492 * Mark C. Miller, Fri Nov 13 15:33:02 PST 2009
10493 * Add DBOPT_LLONGNZNUM to polyhedral zonelist object.
10494 *
10495 * Mark C. Miller, Wed Jul 14 20:36:23 PDT 2010
10496 * Added support for nameschemes options on multi-block objects.
10497 *-------------------------------------------------------------------------*/
10498 INTERNAL int
db_ProcessOptlist(int objtype,DBoptlist const * const optlist)10499 db_ProcessOptlist(int objtype, DBoptlist const * const optlist)
10500 {
10501 int i, j, *ip = NULL, unused = 0;
10502 char *me = "db_ProcessOptlist";
10503
10504 if (!optlist || optlist->numopts < 0)
10505 return 0;
10506
10507 for (i = 0; i < optlist->numopts; i++)
10508 {
10509 if (optlist->options[i] >= DBOPT_FIRST &&
10510 optlist->options[i] <= DBOPT_LAST)
10511 continue;
10512 return db_perror(NULL, E_BADOPTCLASS, me);
10513 }
10514
10515 switch (objtype)
10516 {
10517 case DB_CSGMESH:
10518 case DB_CSGVAR:
10519 for (i = 0; i < optlist->numopts; i++)
10520 {
10521 switch (optlist->options[i])
10522 {
10523 case DBOPT_TIME:
10524 _csgm._time = DEREF(float, optlist->values[i]);
10525 _csgm._time_set = TRUE;
10526 break;
10527
10528 case DBOPT_DTIME:
10529 _csgm._dtime = DEREF(double, optlist->values[i]);
10530 _csgm._dtime_set = TRUE;
10531 break;
10532
10533 case DBOPT_CYCLE:
10534 _csgm._cycle = DEREF(int, optlist->values[i]);
10535 break;
10536
10537 case DBOPT_LABEL:
10538 _csgm._label = (char *)optlist->values[i];
10539 break;
10540
10541 case DBOPT_XLABEL:
10542 _csgm._labels[0] = (char *)optlist->values[i];
10543 break;
10544
10545 case DBOPT_YLABEL:
10546 _csgm._labels[1] = (char *)optlist->values[i];
10547 break;
10548
10549 case DBOPT_ZLABEL:
10550 _csgm._labels[2] = (char *)optlist->values[i];
10551 break;
10552
10553 case DBOPT_UNITS:
10554 _csgm._unit = (char *)optlist->values[i];
10555 break;
10556
10557 case DBOPT_XUNITS:
10558 _csgm._units[0] = (char *)optlist->values[i];
10559 break;
10560
10561 case DBOPT_YUNITS:
10562 _csgm._units[1] = (char *)optlist->values[i];
10563 break;
10564
10565 case DBOPT_ZUNITS:
10566 _csgm._units[2] = (char *)optlist->values[i];
10567 break;
10568
10569 case DBOPT_USESPECMF:
10570 _csgm._use_specmf = DEREF(int, optlist->values[i]);
10571 break;
10572
10573 case DBOPT_GROUPNUM:
10574 DEPRECATE_MSG("DBOPT_GROUPNUM",4,6,"MRG Trees")
10575 _csgm._group_no = DEREF(int, optlist->values[i]);
10576 break;
10577
10578 case DBOPT_ORIGIN:
10579 _csgm._origin = DEREF(int, optlist->values[i]);
10580 break;
10581
10582 case DBOPT_BNDNAMES:
10583 _csgm._bndnames = (char **)optlist->values[i];
10584 break;
10585
10586 case DBOPT_HIDE_FROM_GUI:
10587 _csgm._guihide = DEREF(int, optlist->values[i]);
10588 break;
10589
10590 case DBOPT_MRGTREE_NAME:
10591 _csgm._mrgtree_name = (char *)optlist->values[i];
10592 break;
10593
10594 case DBOPT_REGION_PNAMES:
10595 _csgm._region_pnames = (char **) optlist->values[i];
10596 break;
10597
10598 case DBOPT_TV_CONNECTIVITY:
10599 _csgm._tv_connectivity = DEREF(int, optlist->values[i]);
10600 break;
10601
10602 case DBOPT_DISJOINT_MODE:
10603 _csgm._disjoint_mode = DEREF(int, optlist->values[i]);
10604 break;
10605
10606 case DBOPT_CONSERVED:
10607 _csgm._conserved = DEREF(int, optlist->values[i]);
10608 break;
10609
10610 case DBOPT_EXTENSIVE:
10611 _csgm._extensive = DEREF(int, optlist->values[i]);
10612 break;
10613
10614 case DBOPT_MISSING_VALUE:
10615 _csgm._missing_value = DEREF(double, optlist->values[i]);
10616 break;
10617
10618 case DBOPT_ALT_NODENUM_VARS:
10619 _csgm._alt_nodenum_vars = (char **) optlist->values[i];
10620 break;
10621
10622 default:
10623 unused++;
10624 break;
10625 }
10626 }
10627 break;
10628
10629 case DB_MATERIAL:
10630 for (i = 0; i < optlist->numopts; i++)
10631 {
10632 switch (optlist->options[i])
10633 {
10634 case DBOPT_MAJORORDER:
10635 _ma._majororder = DEREF(int, optlist->values[i]);
10636 break;
10637
10638 case DBOPT_ORIGIN:
10639 _ma._origin = DEREF(int, optlist->values[i]);
10640 break;
10641
10642 case DBOPT_MATNAMES:
10643 _ma._matnames = (char **) optlist->values[i];
10644 break;
10645
10646 case DBOPT_MATCOLORS:
10647 _ma._matcolors = (char **) optlist->values[i];
10648 break;
10649
10650 case DBOPT_ALLOWMAT0:
10651 _ma._allowmat0 = DEREF(int, optlist->values[i]);
10652 break;
10653
10654 case DBOPT_HIDE_FROM_GUI:
10655 _ma._guihide = DEREF(int, optlist->values[i]);
10656 break;
10657
10658 default:
10659 unused++;
10660 break;
10661 }
10662 }
10663 break;
10664
10665 case DB_MATSPECIES:
10666 for (i = 0; i < optlist->numopts; i++)
10667 {
10668 switch (optlist->options[i])
10669 {
10670 case DBOPT_MAJORORDER:
10671 _ms._majororder = DEREF(int, optlist->values[i]);
10672 break;
10673
10674 case DBOPT_HIDE_FROM_GUI:
10675 _ms._guihide = DEREF(int, optlist->values[i]);
10676 break;
10677
10678 case DBOPT_SPECNAMES:
10679 _ms._specnames = (char **) optlist->values[i];
10680 break;
10681
10682 case DBOPT_SPECCOLORS:
10683 _ms._speccolors = (char **) optlist->values[i];
10684 break;
10685
10686 default:
10687 unused++;
10688 break;
10689 }
10690 }
10691 break;
10692
10693 case DB_POINTMESH:
10694 case DB_POINTVAR:
10695 for (i = 0; i < optlist->numopts; i++)
10696 {
10697 switch (optlist->options[i])
10698 {
10699 case DBOPT_TIME:
10700 _pm._time = DEREF(float, optlist->values[i]);
10701 _pm._time_set = 1;
10702 break;
10703
10704 case DBOPT_DTIME:
10705 _pm._dtime = DEREF(double, optlist->values[i]);
10706 _pm._dtime_set = 1;
10707 break;
10708
10709 case DBOPT_CYCLE:
10710 _pm._cycle = DEREF(int, optlist->values[i]);
10711 break;
10712
10713 case DBOPT_NSPACE:
10714 _pm._nspace = DEREF(int, optlist->values[i]);
10715 break;
10716
10717 case DBOPT_ORIGIN:
10718 _pm._origin = DEREF(int, optlist->values[i]);
10719 break;
10720
10721 case DBOPT_HI_OFFSET:
10722 _pm._hi_offset = DEREF(int, optlist->values[i]);
10723 break;
10724
10725 case DBOPT_LO_OFFSET:
10726 _pm._lo_offset = DEREF(int, optlist->values[i]);
10727 break;
10728
10729 case DBOPT_LABEL:
10730 _pm._label = (char *)optlist->values[i];
10731 break;
10732
10733 case DBOPT_XLABEL:
10734 _pm._labels[0] = (char *)optlist->values[i];
10735 break;
10736
10737 case DBOPT_YLABEL:
10738 _pm._labels[1] = (char *)optlist->values[i];
10739 break;
10740
10741 case DBOPT_ZLABEL:
10742 _pm._labels[2] = (char *)optlist->values[i];
10743 break;
10744
10745 case DBOPT_UNITS:
10746 _pm._unit = (char *)optlist->values[i];
10747 break;
10748
10749 case DBOPT_XUNITS:
10750 _pm._units[0] = (char *)optlist->values[i];
10751 break;
10752
10753 case DBOPT_YUNITS:
10754 _pm._units[1] = (char *)optlist->values[i];
10755 break;
10756
10757 case DBOPT_ZUNITS:
10758 _pm._units[2] = (char *)optlist->values[i];
10759 break;
10760
10761 case DBOPT_GROUPNUM:
10762 DEPRECATE_MSG("DBOPT_GROUPNUM",4,6,"MRG Trees")
10763 _pm._group_no = DEREF(int, optlist->values[i]);
10764 break;
10765
10766 case DBOPT_HIDE_FROM_GUI:
10767 _pm._guihide = DEREF(int, optlist->values[i]);
10768 break;
10769
10770 case DBOPT_ASCII_LABEL:
10771 _pm._ascii_labels = DEREF(int, optlist->values[i]);
10772 break;
10773
10774 case DBOPT_NODENUM:
10775 _pm._gnodeno = (int*)optlist->values[i];
10776 break;
10777
10778 case DBOPT_MRGTREE_NAME:
10779 _pm._mrgtree_name = (char *)optlist->values[i];
10780 break;
10781
10782 case DBOPT_REGION_PNAMES:
10783 _pm._region_pnames = (char **) optlist->values[i];
10784 break;
10785
10786 case DBOPT_LLONGNZNUM:
10787 _pm._llong_gnodeno = DEREF(int, optlist->values[i]);
10788 break;
10789
10790 case DBOPT_CONSERVED:
10791 _pm._conserved = DEREF(int, optlist->values[i]);
10792 break;
10793
10794 case DBOPT_EXTENSIVE:
10795 _pm._extensive = DEREF(int, optlist->values[i]);
10796 break;
10797
10798 case DBOPT_MISSING_VALUE:
10799 _pm._missing_value = DEREF(double, optlist->values[i]);
10800 break;
10801
10802 case DBOPT_GHOST_NODE_LABELS:
10803 _pm._ghost_node_labels = (char *)optlist->values[i];
10804 break;
10805
10806 case DBOPT_ALT_NODENUM_VARS:
10807 _pm._alt_nodenum_vars = (char **) optlist->values[i];
10808 break;
10809
10810 default:
10811 unused++;
10812 break;
10813 }
10814 }
10815 break;
10816
10817 case DB_QUADMESH:
10818 case DB_QUADVAR:
10819 for (i = 0; i < optlist->numopts; i++)
10820 {
10821 switch (optlist->options[i])
10822 {
10823 case DBOPT_TIME:
10824 _qm._time = DEREF(float, optlist->values[i]);
10825 _qm._time_set = TRUE;
10826 break;
10827
10828 case DBOPT_DTIME:
10829 _qm._dtime = DEREF(double, optlist->values[i]);
10830 _qm._dtime_set = TRUE;
10831 break;
10832
10833 case DBOPT_CYCLE:
10834 _qm._cycle = DEREF(int, optlist->values[i]);
10835 break;
10836
10837 case DBOPT_COORDSYS:
10838 _qm._coord_sys = DEREF(int, optlist->values[i]);
10839 break;
10840
10841 case DBOPT_FACETYPE:
10842 _qm._facetype = DEREF(int, optlist->values[i]);
10843 break;
10844
10845 case DBOPT_MAJORORDER:
10846 _qm._majororder = DEREF(int, optlist->values[i]);
10847 break;
10848
10849 case DBOPT_NSPACE:
10850 _qm._nspace = DEREF(int, optlist->values[i]);
10851 break;
10852
10853 case DBOPT_ORIGIN:
10854 _qm._origin = DEREF(int, optlist->values[i]);
10855 if (! _qm._baseindex_set)
10856 {
10857 for (j = 0; j < _qm._ndims; j++)
10858 _qm._baseindex[j] = _qm._origin;
10859 }
10860 break;
10861
10862 case DBOPT_PLANAR:
10863 _qm._planar = DEREF(int, optlist->values[i]);
10864 break;
10865
10866 case DBOPT_HI_OFFSET:
10867 ip = (int *)optlist->values[i];
10868 for (j = 0; j < _qm._ndims; j++)
10869 _qm._hi_offset[j] = ip[j];
10870 break;
10871
10872 case DBOPT_LO_OFFSET:
10873 ip = (int *)optlist->values[i];
10874 for (j = 0; j < _qm._ndims; j++)
10875 _qm._lo_offset[j] = ip[j];
10876 break;
10877
10878 case DBOPT_LABEL:
10879 _qm._label = (char *)optlist->values[i];
10880 break;
10881
10882 case DBOPT_XLABEL:
10883 _qm._labels[0] = (char *)optlist->values[i];
10884 break;
10885
10886 case DBOPT_YLABEL:
10887 _qm._labels[1] = (char *)optlist->values[i];
10888 break;
10889
10890 case DBOPT_ZLABEL:
10891 _qm._labels[2] = (char *)optlist->values[i];
10892 break;
10893
10894 case DBOPT_UNITS:
10895 _qm._unit = (char *)optlist->values[i];
10896 break;
10897
10898 case DBOPT_XUNITS:
10899 _qm._units[0] = (char *)optlist->values[i];
10900 break;
10901
10902 case DBOPT_YUNITS:
10903 _qm._units[1] = (char *)optlist->values[i];
10904 break;
10905
10906 case DBOPT_ZUNITS:
10907 _qm._units[2] = (char *)optlist->values[i];
10908 break;
10909
10910 case DBOPT_USESPECMF:
10911 _qm._use_specmf = DEREF(int, optlist->values[i]);
10912 break;
10913
10914 case DBOPT_ASCII_LABEL:
10915 _qm._ascii_labels = DEREF(int, optlist->values[i]);
10916 break;
10917
10918 case DBOPT_GROUPNUM:
10919 DEPRECATE_MSG("DBOPT_GROUPNUM",4,6,"MRG Trees")
10920 _qm._group_no = DEREF(int, optlist->values[i]);
10921 break;
10922
10923 case DBOPT_BASEINDEX:
10924 ip = (int *)optlist->values[i];
10925 for (j = 0; j < _qm._ndims; j++)
10926 _qm._baseindex[j] = ip[j];
10927 _qm._baseindex_set = TRUE;
10928 break;
10929
10930 case DBOPT_HIDE_FROM_GUI:
10931 _qm._guihide = DEREF(int, optlist->values[i]);
10932 break;
10933
10934 case DBOPT_MRGTREE_NAME:
10935 _qm._mrgtree_name = (char *)optlist->values[i];
10936 break;
10937
10938 case DBOPT_REGION_PNAMES:
10939 _qm._region_pnames = (char **) optlist->values[i];
10940 break;
10941
10942 case DBOPT_CONSERVED:
10943 _qm._conserved = DEREF(int, optlist->values[i]);
10944 break;
10945
10946 case DBOPT_EXTENSIVE:
10947 _qm._extensive = DEREF(int, optlist->values[i]);
10948 break;
10949
10950 case DBOPT_MISSING_VALUE:
10951 _qm._missing_value = DEREF(double, optlist->values[i]);
10952 break;
10953
10954 case DBOPT_GHOST_NODE_LABELS:
10955 _qm._ghost_node_labels = (char *)optlist->values[i];
10956 break;
10957
10958 case DBOPT_GHOST_ZONE_LABELS:
10959 _qm._ghost_zone_labels = (char *)optlist->values[i];
10960 break;
10961
10962 case DBOPT_ALT_NODENUM_VARS:
10963 _qm._alt_nodenum_vars = (char **) optlist->values[i];
10964 break;
10965
10966 case DBOPT_ALT_ZONENUM_VARS:
10967 _qm._alt_zonenum_vars = (char **) optlist->values[i];
10968 break;
10969
10970 default:
10971 unused++;
10972 break;
10973 }
10974 }
10975 break;
10976
10977 case DB_UCDMESH:
10978 case DB_UCDVAR:
10979 for (i = 0; i < optlist->numopts; i++)
10980 {
10981 switch (optlist->options[i])
10982 {
10983 case DBOPT_TIME:
10984 _um._time = DEREF(float, optlist->values[i]);
10985 _um._time_set = TRUE;
10986 break;
10987
10988 case DBOPT_DTIME:
10989 _um._dtime = DEREF(double, optlist->values[i]);
10990 _um._dtime_set = TRUE;
10991 break;
10992
10993 case DBOPT_CYCLE:
10994 _um._cycle = DEREF(int, optlist->values[i]);
10995 break;
10996
10997 case DBOPT_COORDSYS:
10998 _um._coord_sys = DEREF(int, optlist->values[i]);
10999 break;
11000
11001 case DBOPT_TOPO_DIM:
11002 /* The value of '_topo_dim' member is designed such
11003 that a value of zero (which can be a valid topological
11004 dimension specified by a caller) represents the
11005 NOT SET value. So, we always add 1 to whatever the
11006 caller gives us. */
11007 _um._topo_dim = DEREF(int, optlist->values[i])+1;
11008 break;
11009
11010 case DBOPT_FACETYPE:
11011 _um._facetype = DEREF(int, optlist->values[i]);
11012 break;
11013
11014 case DBOPT_ORIGIN:
11015 _um._origin = DEREF(int, optlist->values[i]);
11016 break;
11017
11018 case DBOPT_PLANAR:
11019 _um._planar = DEREF(int, optlist->values[i]);
11020 break;
11021
11022 case DBOPT_LABEL:
11023 _um._label = (char *)optlist->values[i];
11024 break;
11025
11026 case DBOPT_XLABEL:
11027 _um._labels[0] = (char *)optlist->values[i];
11028 break;
11029
11030 case DBOPT_YLABEL:
11031 _um._labels[1] = (char *)optlist->values[i];
11032 break;
11033
11034 case DBOPT_ZLABEL:
11035 _um._labels[2] = (char *)optlist->values[i];
11036 break;
11037
11038 case DBOPT_UNITS:
11039 _um._unit = (char *)optlist->values[i];
11040 break;
11041
11042 case DBOPT_XUNITS:
11043 _um._units[0] = (char *)optlist->values[i];
11044 break;
11045
11046 case DBOPT_YUNITS:
11047 _um._units[1] = (char *)optlist->values[i];
11048 break;
11049
11050 case DBOPT_ZUNITS:
11051 _um._units[2] = (char *)optlist->values[i];
11052 break;
11053
11054 case DBOPT_USESPECMF:
11055 _um._use_specmf = DEREF(int, optlist->values[i]);
11056 break;
11057
11058 case DBOPT_ASCII_LABEL:
11059 _um._ascii_labels = DEREF(int, optlist->values[i]);
11060 break;
11061
11062 case DBOPT_HI_OFFSET:
11063 _um._hi_offset = DEREF(int, optlist->values[i]);
11064 _um._hi_offset_set = TRUE;
11065 break;
11066
11067 case DBOPT_LO_OFFSET:
11068 _um._lo_offset = DEREF(int, optlist->values[i]);
11069 _um._lo_offset_set = TRUE;
11070 break;
11071
11072 case DBOPT_GROUPNUM:
11073 DEPRECATE_MSG("DBOPT_GROUPNUM",4,6,"MRG Trees")
11074 _um._group_no = DEREF(int, optlist->values[i]);
11075 break;
11076
11077 case DBOPT_NODENUM:
11078 _um._gnodeno = (int*)optlist->values[i];
11079 break;
11080
11081 case DBOPT_PHZONELIST:
11082 _um._phzl_name = (char *)optlist->values[i];
11083 break;
11084
11085 case DBOPT_HIDE_FROM_GUI:
11086 _um._guihide = DEREF(int, optlist->values[i]);
11087 break;
11088
11089 case DBOPT_MRGTREE_NAME:
11090 _um._mrgtree_name = (char *)optlist->values[i];
11091 break;
11092
11093 case DBOPT_REGION_PNAMES:
11094 _um._region_pnames = (char **) optlist->values[i];
11095 break;
11096
11097 case DBOPT_TV_CONNECTIVITY:
11098 _um._tv_connectivity = DEREF(int, optlist->values[i]);
11099 break;
11100
11101 case DBOPT_DISJOINT_MODE:
11102 _um._disjoint_mode = DEREF(int, optlist->values[i]);
11103 break;
11104
11105 case DBOPT_LLONGNZNUM:
11106 _um._llong_gnodeno = DEREF(int, optlist->values[i]);
11107 break;
11108
11109 case DBOPT_CONSERVED:
11110 _um._conserved = DEREF(int, optlist->values[i]);
11111 break;
11112
11113 case DBOPT_EXTENSIVE:
11114 _um._extensive = DEREF(int, optlist->values[i]);
11115 break;
11116
11117 case DBOPT_MISSING_VALUE:
11118 _um._missing_value = DEREF(double, optlist->values[i]);
11119 break;
11120
11121 case DBOPT_GHOST_NODE_LABELS:
11122 _um._ghost_node_labels = (char *)optlist->values[i];
11123 break;
11124
11125 case DBOPT_ALT_NODENUM_VARS:
11126 _um._alt_nodenum_vars = (char **) optlist->values[i];
11127 break;
11128
11129 default:
11130 unused++;
11131 break;
11132 }
11133 }
11134 break;
11135
11136 case DB_ZONELIST:
11137 for (i = 0; i < optlist->numopts; i++)
11138 {
11139 switch (optlist->options[i])
11140 {
11141 case DBOPT_ZONENUM:
11142 _uzl._gzoneno = (int*)optlist->values[i];
11143 break;
11144
11145 case DBOPT_LLONGNZNUM:
11146 _uzl._llong_gzoneno = DEREF(int, optlist->values[i]);
11147 break;
11148
11149 case DBOPT_GHOST_ZONE_LABELS:
11150 _uzl._ghost_zone_labels = (char *)optlist->values[i];
11151 break;
11152
11153 case DBOPT_ALT_ZONENUM_VARS:
11154 _uzl._alt_zonenum_vars = (char **) optlist->values[i];
11155 break;
11156
11157 default:
11158 unused++;
11159 break;
11160 }
11161 }
11162 break;
11163
11164 case DB_PHZONELIST:
11165 for (i = 0; i < optlist->numopts; i++)
11166 {
11167 switch (optlist->options[i])
11168 {
11169 case DBOPT_ZONENUM:
11170 _phzl._gzoneno = (int*)optlist->values[i];
11171 break;
11172
11173 case DBOPT_LLONGNZNUM:
11174 _phzl._llong_gzoneno = DEREF(int, optlist->values[i]);
11175 break;
11176
11177 case DBOPT_GHOST_ZONE_LABELS:
11178 _phzl._ghost_zone_labels = (char *)optlist->values[i];
11179 break;
11180
11181 case DBOPT_ALT_ZONENUM_VARS:
11182 _phzl._alt_zonenum_vars = (char **) optlist->values[i];
11183 break;
11184
11185 default:
11186 unused++;
11187 break;
11188 }
11189 }
11190 break;
11191
11192 case DB_CSGZONELIST:
11193 for (i = 0; i < optlist->numopts; i++)
11194 {
11195 switch (optlist->options[i])
11196 {
11197 case DBOPT_REGNAMES:
11198 _csgzl._regnames = (char **) optlist->values[i];
11199 break;
11200
11201 case DBOPT_ZONENAMES:
11202 _csgzl._zonenames = (char **) optlist->values[i];
11203 break;
11204
11205 case DBOPT_ALT_ZONENUM_VARS:
11206 _csgzl._alt_zonenum_vars = (char **) optlist->values[i];
11207 break;
11208
11209 default:
11210 unused++;
11211 break;
11212 }
11213 }
11214 break;
11215
11216 case DB_MULTIMESH:
11217 for (i = 0; i < optlist->numopts; i++)
11218 {
11219 switch (optlist->options[i])
11220 {
11221 case DBOPT_TIME:
11222 _mm._time = DEREF(float, optlist->values[i]);
11223 _mm._time_set = TRUE;
11224 break;
11225
11226 case DBOPT_DTIME:
11227 _mm._dtime = DEREF(double, optlist->values[i]);
11228 _mm._dtime_set = TRUE;
11229 break;
11230
11231 case DBOPT_CYCLE:
11232 _mm._cycle = DEREF(int, optlist->values[i]);
11233 break;
11234
11235 case DBOPT_MATNOS:
11236 _mm._matnos = (int *) optlist->values[i];
11237 break;
11238
11239 case DBOPT_NMATNOS:
11240 _mm._nmatnos = DEREF(int, optlist->values[i]);
11241 break;
11242
11243 case DBOPT_MATNAME:
11244 _mm._matname = (char *) optlist->values[i];
11245 break;
11246
11247 case DBOPT_NMAT:
11248 _mm._nmat = DEREF(int,optlist->values[i]);
11249 break;
11250
11251 case DBOPT_NMATSPEC:
11252 _mm._nmatspec = (int *) optlist->values[i];
11253 break;
11254
11255 case DBOPT_BLOCKORIGIN:
11256 _mm._blockorigin = DEREF(int, optlist->values[i]);
11257 break;
11258
11259 case DBOPT_GROUPORIGIN:
11260 DEPRECATE_MSG("DBOPT_GROUPORIGIN",4,6,"MRG Trees")
11261 _mm._grouporigin = DEREF(int, optlist->values[i]);
11262 break;
11263
11264 case DBOPT_NGROUPS:
11265 DEPRECATE_MSG("DBOPT_NGROUPS",4,6,"MRG Trees")
11266 _mm._ngroups = DEREF(int, optlist->values[i]);
11267 break;
11268
11269 case DBOPT_EXTENTS_SIZE:
11270 _mm._extentssize = DEREF(int, optlist->values[i]);
11271 break;
11272
11273 case DBOPT_EXTENTS:
11274 _mm._extents = (double *) optlist->values[i];
11275 break;
11276
11277 case DBOPT_ZONECOUNTS:
11278 _mm._zonecounts = (int *) optlist->values[i];
11279 break;
11280
11281 case DBOPT_MIXLENS:
11282 _mm._mixlens = (int *) optlist->values[i];
11283 break;
11284
11285 case DBOPT_MATCOUNTS:
11286 _mm._matcounts = (int *) optlist->values[i];
11287 break;
11288
11289 case DBOPT_MATLISTS:
11290 _mm._matlists = (int *) optlist->values[i];
11291 break;
11292
11293 case DBOPT_HAS_EXTERNAL_ZONES:
11294 _mm._has_external_zones = (int *) optlist->values[i];
11295 break;
11296
11297 case DBOPT_HIDE_FROM_GUI:
11298 _mm._guihide = DEREF(int, optlist->values[i]);
11299 break;
11300
11301 case DBOPT_GROUPINGS_SIZE:
11302 DEPRECATE_MSG("DBOPT_GROUPINGS_SIZE",4,6,"MRG Trees")
11303 _mm._lgroupings = DEREF(int, optlist->values[i]);
11304 break;
11305
11306 case DBOPT_GROUPINGS:
11307 DEPRECATE_MSG("DBOPT_GROUPINGS",4,6,"MRG Trees")
11308 _mm._groupings = (int *) optlist->values[i];
11309 break;
11310
11311 case DBOPT_GROUPINGNAMES:
11312 DEPRECATE_MSG("DBOPT_GROUPINGNAMES",4,6,"MRG Trees")
11313 _mm._groupnames = (char **) optlist->values[i];
11314 break;
11315
11316 case DBOPT_MATCOLORS:
11317 _mm._matcolors = (char **) optlist->values[i];
11318 break;
11319
11320 case DBOPT_MATNAMES:
11321 _mm._matnames = (char **) optlist->values[i];
11322 break;
11323
11324 case DBOPT_ALLOWMAT0:
11325 _mm._allowmat0 = DEREF(int, optlist->values[i]);
11326 break;
11327
11328 case DBOPT_MRGTREE_NAME:
11329 _mm._mrgtree_name = (char *)optlist->values[i];
11330 break;
11331
11332 case DBOPT_REGION_PNAMES:
11333 _mm._region_pnames = (char **) optlist->values[i];
11334 break;
11335
11336 case DBOPT_MMESH_NAME:
11337 _mm._mmesh_name = (char *)optlist->values[i];
11338 break;
11339
11340 case DBOPT_TENSOR_RANK:
11341 _mm._tensor_rank = DEREF(int, optlist->values[i]);
11342 break;
11343
11344 case DBOPT_TV_CONNECTIVITY:
11345 _mm._tv_connectivity = DEREF(int, optlist->values[i]);
11346 break;
11347
11348 case DBOPT_DISJOINT_MODE:
11349 _mm._disjoint_mode = DEREF(int, optlist->values[i]);
11350 break;
11351
11352 case DBOPT_TOPO_DIM:
11353 /* The value of '_topo_dim' member is designed such
11354 that a value of zero (which can be a valid topological
11355 dimension specified by a caller) represents the
11356 NOT SET value. So, we always add 1 to whatever the
11357 caller gives us. */
11358 _mm._topo_dim = DEREF(int, optlist->values[i])+1;
11359 break;
11360
11361 case DBOPT_SPECNAMES:
11362 _mm._specnames = (char **) optlist->values[i];
11363 break;
11364
11365 case DBOPT_SPECCOLORS:
11366 _mm._speccolors = (char **) optlist->values[i];
11367 break;
11368
11369 case DBOPT_CONSERVED:
11370 _mm._conserved = DEREF(int, optlist->values[i]);
11371 break;
11372
11373 case DBOPT_EXTENSIVE:
11374 _mm._extensive = DEREF(int, optlist->values[i]);
11375 break;
11376
11377 case DBOPT_MB_FILE_NS:
11378 _mm._file_ns = (char *) optlist->values[i];
11379 break;
11380
11381 case DBOPT_MB_BLOCK_NS:
11382 _mm._block_ns = (char *) optlist->values[i];
11383 break;
11384
11385 case DBOPT_MB_BLOCK_TYPE:
11386 _mm._block_type = DEREF(int, optlist->values[i]);
11387 break;
11388
11389 case DBOPT_MB_EMPTY_LIST:
11390 _mm._empty_list = (int *) optlist->values[i];
11391 break;
11392
11393 case DBOPT_MB_EMPTY_COUNT:
11394 _mm._empty_cnt = DEREF(int, optlist->values[i]);
11395 break;
11396
11397 case DBOPT_MB_REPR_BLOCK_IDX:
11398 /* +1 to support zero value indicating NOT SET */
11399 _mm._repr_block_idx = DEREF(int,optlist->values[i])+1;
11400 break;
11401
11402 case DBOPT_MISSING_VALUE:
11403 _mm._missing_value = DEREF(double, optlist->values[i]);
11404 break;
11405
11406 case DBOPT_ALT_NODENUM_VARS:
11407 _mm._alt_nodenum_vars = (char**) optlist->values[i];
11408 break;
11409
11410 case DBOPT_ALT_ZONENUM_VARS:
11411 _mm._alt_zonenum_vars = (char**) optlist->values[i];
11412 break;
11413
11414 default:
11415 unused++;
11416 break;
11417 }
11418 }
11419 break;
11420
11421 case DB_CURVE:
11422 for (i = 0; i < optlist->numopts; i++)
11423 {
11424 switch (optlist->options[i])
11425 {
11426 case DBOPT_LABEL:
11427 _cu._label = (char *)optlist->values[i];
11428 break;
11429
11430 case DBOPT_XLABEL:
11431 _cu._labels[0] = (char *)optlist->values[i];
11432 break;
11433
11434 case DBOPT_YLABEL:
11435 _cu._labels[1] = (char *)optlist->values[i];
11436 break;
11437
11438 case DBOPT_XUNITS:
11439 _cu._units[0] = (char *)optlist->values[i];
11440 break;
11441
11442 case DBOPT_YUNITS:
11443 _cu._units[1] = (char *)optlist->values[i];
11444 break;
11445
11446 case DBOPT_XVARNAME:
11447 _cu._varname[0] = (char *)optlist->values[i];
11448 break;
11449
11450 case DBOPT_YVARNAME:
11451 _cu._varname[1] = (char *)optlist->values[i];
11452 break;
11453
11454 case DBOPT_HIDE_FROM_GUI:
11455 _cu._guihide = DEREF(int, optlist->values[i]);
11456 break;
11457
11458 case DBOPT_REFERENCE:
11459 _cu._reference = (char *)optlist->values[i];
11460 break;
11461
11462 case DBOPT_COORDSYS:
11463 _cu._coord_sys = DEREF(int, optlist->values[i]);
11464 break;
11465
11466 case DBOPT_MISSING_VALUE:
11467 _cu._missing_value = DEREF(double, optlist->values[i]);
11468 break;
11469
11470 default:
11471 unused++;
11472 break;
11473 }
11474 }
11475 break;
11476
11477 case DB_DEFVARS:
11478 for (i = 0; i < optlist->numopts; i++)
11479 {
11480 switch (optlist->options[i])
11481 {
11482 case DBOPT_HIDE_FROM_GUI:
11483 _dv._guihide = DEREF(int, optlist->values[i]);
11484 break;
11485
11486 default:
11487 unused++;
11488 break;
11489 }
11490 }
11491 break;
11492
11493 case DB_MRGTREE:
11494 for (i = 0; i < optlist->numopts; i++)
11495 {
11496 switch (optlist->options[i])
11497 {
11498 case DBOPT_MRGV_ONAMES:
11499 _mrgt._mrgvar_onames = (char **) optlist->values[i];
11500 break;
11501
11502 case DBOPT_MRGV_RNAMES:
11503 _mrgt._mrgvar_rnames = (char **) optlist->values[i];
11504 break;
11505
11506 default:
11507 unused++;
11508 break;
11509 }
11510 }
11511 break;
11512
11513 default:
11514 return db_perror(NULL, E_NOTIMP, me);
11515 }
11516
11517 return 0;
11518 }
11519
11520 /*-------------------------------------------------------------------------
11521 * Function: DBInqCompoundarray
11522 *
11523 * Purpose: Inquire compound array attributes
11524 *
11525 * Return: Success: OKAY
11526 *
11527 * Failure: OOPS
11528 *
11529 * Arguments:
11530 * dbfile ptr to data file
11531 * array_name array name
11532 *
11533 * Output args
11534 * elemnames simple array names
11535 * elemlengths simple array sizes
11536 * nelems number of simple arrys
11537 * nvalues number of values
11538 * datatype value data type
11539 *
11540 * Programmer: matzke@viper
11541 * Tue Oct 25 13:58:53 PDT 1994
11542 *
11543 * Modifications:
11544 * matzke@viper, Mon Oct 31 13:39:10 PST 1994
11545 * No longer calls DBGetCompoundarray.
11546 *
11547 * Eric Brugger, Tue Feb 7 08:09:26 PST 1995
11548 * I replaced API_END with API_END_NOPOP.
11549 *
11550 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
11551 * Added a check for variable name validity.
11552 *-------------------------------------------------------------------------*/
11553 PUBLIC int
DBInqCompoundarray(DBfile * dbfile,const char * array_name,char ** elemnames[],int ** elemlengths,int * nelems,int * nvalues,int * datatype)11554 DBInqCompoundarray(DBfile *dbfile, const char *array_name,
11555 char **elemnames[], int **elemlengths, int *nelems,
11556 int *nvalues, int *datatype)
11557
11558 {
11559 DBcompoundarray *ca = NULL;
11560
11561 API_BEGIN2("DBInqCompoundarray", int, -1, array_name) {
11562 if (!array_name || !*array_name)
11563 API_ERROR("array name", E_BADARGS);
11564 if (SILO_Globals.enableGrabDriver == TRUE)
11565 API_ERROR("DBInqCompoundarray", E_GRABBED) ;
11566 if (elemnames)
11567 *elemnames = NULL;
11568 if (elemlengths)
11569 *elemlengths = NULL;
11570 if (nelems)
11571 *nelems = 0;
11572 if (nvalues)
11573 *nvalues = 0;
11574 if (datatype)
11575 *datatype = 0;
11576
11577 if (!dbfile->pub.g_ca)
11578 API_ERROR(dbfile->pub.name, E_NOTIMP);
11579 ca = DBGetCompoundarray(dbfile, array_name);
11580 if (!ca)
11581 API_ERROR("DBGetCompoundarray", E_CALLFAIL);
11582
11583 if (elemnames) {
11584 *elemnames = ca->elemnames;
11585 ca->elemnames = NULL; /*so we don't free it... */
11586 }
11587 if (elemlengths) {
11588 *elemlengths = ca->elemlengths;
11589 ca->elemlengths = NULL;
11590 }
11591 if (nelems)
11592 *nelems = ca->nelems;
11593 if (nvalues)
11594 *nvalues = ca->nvalues;
11595 if (datatype)
11596 *datatype = ca->datatype;
11597
11598 DBFreeCompoundarray(ca);
11599 }
11600 API_END;
11601
11602 return(0);
11603 }
11604
11605 /*-------------------------------------------------------------------------
11606 * Function: DBGetComponentNames
11607 *
11608 * Purpose: Returns the component names for the specified object.
11609 * Each component name also has a variable name under which
11610 * the component value is stored in the data file. The
11611 * COMP_NAMES and FILE_NAMES output arguments will point to
11612 * an array of pointers to names. Each name as well as the
11613 * two arrays will be allocated with `malloc'.
11614 *
11615 * Return: Success: Number of components found for the
11616 * specified object.
11617 *
11618 * Failure: zero.
11619 *
11620 * Programmer: Robb Matzke
11621 * robb@callisto.nuance.mdn.com
11622 * May 20, 1996
11623 *
11624 * Modifications:
11625 * Sean Ahern, Tue Sep 28 10:48:06 PDT 1999
11626 * Added a check for variable name validity.
11627 *
11628 * Mark C. Miller, Tue Sep 6 10:57:55 PDT 2005
11629 * Deprecated this function
11630 *-------------------------------------------------------------------------*/
11631 PUBLIC int
DBGetComponentNames(DBfile * dbfile,const char * objname,char *** comp_names,char *** file_names)11632 DBGetComponentNames(DBfile *dbfile, const char *objname,
11633 char ***comp_names, char ***file_names)
11634 {
11635 int retval;
11636
11637 API_DEPRECATE2("DBGetComponentNames", int, -1, objname, 4,6,"")
11638 {
11639 if (!dbfile)
11640 API_ERROR(NULL, E_NOFILE);
11641 if (!dbfile->pub.g_compnames)
11642 API_ERROR(dbfile->pub.name, E_NOTIMP);
11643 if (!objname || !*objname)
11644 API_ERROR("object name", E_BADARGS);
11645
11646 retval = (dbfile->pub.g_compnames) (dbfile, objname,
11647 comp_names, file_names);
11648 API_RETURN(retval);
11649 }
11650 API_END_NOPOP; /* If API_RETURN above is removed, use API_END instead */
11651 }
11652
11653 /*----------------------------------------------------------------------
11654 * Routine db_SplitShapelist
11655 *
11656 * Purpose
11657 *
11658 * Split the shapecnts in the zone list so that an entry in the
11659 * shapecnt array will either refer to all real zones or all ghost
11660 * zones.
11661 *
11662 * Programmer
11663 *
11664 * Eric Brugger, January 22, 1999
11665 *
11666 * Notes
11667 *
11668 * Modifications
11669 * Eric Brugger, Wed Mar 31 11:36:42 PST 1999
11670 * Modify the routine to handle polyhedra. This turned out to be
11671 * a significant rewrite of the routine.
11672 *
11673 * Eric Brugger, Tue Apr 20 09:24:51 PDT 1999
11674 * Correct a bug where the nshapes field was always zero when the
11675 * shapetype field was NULL.
11676 *
11677 * Jeremy Meredith, Fri Aug 13 13:53:57 PDT 1999
11678 * Corrected a bug where nshapes was still not incremented enough if
11679 * shapetype was NULL. This was causing ghost zones to disappear.
11680 *
11681 * Mark C. Miller, Mon Jun 21 18:06:36 PDT 2004
11682 * Moved from silo_pdb.c to public place where any driver can call
11683 *--------------------------------------------------------------------*/
11684 INTERNAL int
db_SplitShapelist(DBucdmesh * um)11685 db_SplitShapelist (DBucdmesh *um)
11686 {
11687 int *shapecnt=NULL, *shapesize=NULL, *shapetype=NULL, nshapes;
11688 int *zonelist=NULL, nzones;
11689 int min_index, max_index;
11690 int *shapecnt2=NULL, *shapesize2=NULL, *shapetype2=NULL, nshapes2;
11691 int i, iz, izl, deltaiz;
11692 int isplit, splits[3];
11693
11694 shapecnt = um->zones->shapecnt;
11695 shapesize = um->zones->shapesize;
11696 shapetype = um->zones->shapetype;
11697 nshapes = um->zones->nshapes;
11698 zonelist = um->zones->nodelist;
11699 min_index = um->zones->min_index;
11700 max_index = um->zones->max_index;
11701 nzones = um->zones->nzones;
11702
11703 nshapes2 = 0;
11704 shapecnt2 = ALLOC_N (int, nshapes+2);
11705 shapesize2 = ALLOC_N (int, nshapes+2);
11706 if (shapetype != NULL)
11707 {
11708 shapetype2 = ALLOC_N (int, nshapes+2);
11709 }
11710
11711 if (min_index > 0)
11712 {
11713 splits[0] = min_index;
11714 splits[1] = max_index + 1;
11715 splits[2] = nzones;
11716 }
11717 else
11718 {
11719 splits[0] = max_index + 1;
11720 splits[1] = nzones;
11721 splits[2] = 0;
11722 }
11723
11724 isplit = 0;
11725 i = 0;
11726 iz = 0;
11727 izl = 0;
11728 while (iz < nzones)
11729 {
11730 if (splits[isplit] - iz >= shapecnt[i])
11731 {
11732 shapecnt2 [nshapes2] = shapecnt[i];
11733 shapesize2[nshapes2] = shapesize[i];
11734 if (shapetype != NULL)
11735 {
11736 shapetype2[nshapes2] = shapetype[i];
11737 }
11738 nshapes2++;
11739 isplit += (splits[isplit] - iz == shapecnt[i]) ? 1 : 0;
11740 iz += shapecnt[i];
11741 if (shapetype != NULL && shapetype[i] == DB_ZONETYPE_POLYHEDRON)
11742 {
11743 izl += shapesize[i];
11744 }
11745 else
11746 {
11747 izl += shapesize[i] * shapecnt[i];
11748 }
11749 i++;
11750 }
11751 else
11752 {
11753 deltaiz = splits[isplit] - iz;
11754 shapecnt2[nshapes2] = deltaiz;
11755 if (shapetype != NULL && shapetype[i] == DB_ZONETYPE_POLYHEDRON)
11756 {
11757 int j, k;
11758 int izlInit, nFaces;
11759
11760 izlInit = izl;
11761 for (j = 0; j < deltaiz; j++)
11762 {
11763 nFaces = zonelist[izl++];
11764 for (k = 0; k < nFaces; k++)
11765 {
11766 izl += zonelist[izl] + 1;
11767 }
11768 }
11769 shapesize2[nshapes2] = izl - izlInit;
11770 shapesize[i] -= izl - izlInit;
11771 }
11772 else
11773 {
11774 izl += shapesize[i] * deltaiz;
11775 shapesize2[nshapes2] = shapesize[i];
11776 }
11777 if (shapetype != NULL)
11778 {
11779 shapetype2[nshapes2] = shapetype[i];
11780 }
11781 nshapes2++;
11782 shapecnt[i] -= deltaiz;
11783 isplit++;
11784 iz += deltaiz;
11785 }
11786 }
11787
11788 FREE (shapecnt);
11789 FREE (shapesize);
11790 FREE (shapetype);
11791 um->zones->shapecnt = shapecnt2;
11792 um->zones->shapesize = shapesize2;
11793 um->zones->shapetype = shapetype2;
11794 um->zones->nshapes = nshapes2;
11795
11796 return 0;
11797 }
11798
11799 /*----------------------------------------------------------------------
11800 * Routine db_ResetGlobalData_Csgmesh
11801 *
11802 * Purpose
11803 *
11804 * Reset global data to default values. For internal use only.
11805 *
11806 * Programmer
11807 *
11808 * Mark C. Miller, Wed Aug 3 14:39:03 PDT 2005
11809 *
11810 * Modifications:
11811 * Mark C. Miller, Mon Jan 12 16:29:19 PST 2009
11812 * Removed explicit setting of data members already handled
11813 * correctly by memset to zero.
11814 *--------------------------------------------------------------------*/
11815 INTERNAL int
db_ResetGlobalData_Csgmesh()11816 db_ResetGlobalData_Csgmesh () {
11817
11818 memset(&_csgm, 0, sizeof(_csgm));
11819 _csgm._use_specmf = DB_OFF;
11820 _csgm._group_no = -1;
11821 _csgm._missing_value = DB_MISSING_VALUE_NOT_SET;
11822
11823 return 0;
11824 }
11825 /*----------------------------------------------------------------------
11826 * Routine db_ResetGlobalData_PointMesh
11827 *
11828 * Purpose
11829 *
11830 * Reset global data to default values. For internal use only.
11831 *
11832 * Programmer
11833 *
11834 * Jeffery W. Long, NSSD-B
11835 *
11836 * Notes
11837 *
11838 * It is assumed that _ndims has a valid value before this
11839 * function is invoked. (It is assigned to _nspace.)
11840 *
11841 * Modifications
11842 *
11843 * Al Leibee, Mon Apr 18 07:45:58 PDT 1994
11844 * Added _dtime.
11845 *
11846 * Jeremy Meredith, Fri May 21 10:04:25 PDT 1999
11847 * Init group_no to -1.
11848 *
11849 * Mark C. Miller, Mon Jun 21 18:06:36 PDT 2004
11850 * Moved from silo_pdb.c to public place where any driver can call
11851 *
11852 * Mark C. Miller, Mon Jan 12 16:29:19 PST 2009
11853 * Removed explicit setting of data members already handled
11854 * correctly by memset to zero.
11855 *--------------------------------------------------------------------*/
11856 INTERNAL int
db_ResetGlobalData_PointMesh(int ndims)11857 db_ResetGlobalData_PointMesh (int ndims) {
11858
11859 memset(&_pm, 0, sizeof(_pm));
11860 _pm._ndims = ndims;
11861 _pm._nspace = ndims;
11862 _pm._group_no = -1;
11863 _pm._missing_value = DB_MISSING_VALUE_NOT_SET;
11864 return 0;
11865 }
11866
11867 /*----------------------------------------------------------------------
11868 * Routine db_ResetGlobalData_QuadMesh
11869 *
11870 * Purpose
11871 *
11872 * Reset global data to default values. For internal use only.
11873 *
11874 * Programmer
11875 *
11876 * Jeffery W. Long, NSSD-B
11877 *
11878 * Notes
11879 *
11880 * It is assumed that _ndims has a valid value before this
11881 * function is invoked. (It is assigned to _nspace.)
11882 *
11883 * Modifications
11884 *
11885 * Al Leibee, Wed Aug 3 16:57:38 PDT 1994
11886 * Added _use_specmf.
11887 *
11888 * Al Leibee, Sun Apr 17 07:54:25 PDT 1994
11889 * Added dtime.
11890 *
11891 * Robb Matzke, 18 Jun 1997
11892 * Initialize ascii_labels field to FALSE.
11893 *
11894 * Eric Brugger, Mon Oct 6 15:11:26 PDT 1997
11895 * I modified the routine to initialize lo_offset and hi_offset.
11896 *
11897 * Jeremy Meredith, Fri May 21 10:04:25 PDT 1999
11898 * Init group_no to -1. Init baseindex and baseindex_set.
11899 *
11900 * Mark C. Miller, Mon Jun 21 18:06:36 PDT 2004
11901 * Moved from silo_pdb.c to public place where any driver can call
11902 *
11903 * Mark C. Miller, Mon Jan 12 16:29:19 PST 2009
11904 * Removed explicit setting of data members already handled
11905 * correctly by memset to zero.
11906 *--------------------------------------------------------------------*/
11907 INTERNAL int
db_ResetGlobalData_QuadMesh(int ndims)11908 db_ResetGlobalData_QuadMesh (int ndims) {
11909
11910 FREE(_qm._meshname);
11911 memset(&_qm, 0, sizeof(_qm));
11912
11913 _qm._coord_sys = DB_OTHER;
11914 _qm._facetype = DB_RECTILINEAR;
11915 _qm._ndims = ndims;
11916 _qm._nspace = ndims;
11917 _qm._planar = DB_AREA;
11918 _qm._use_specmf = DB_OFF;
11919 _qm._group_no = -1;
11920 _qm._missing_value = DB_MISSING_VALUE_NOT_SET;
11921
11922 return 0;
11923 }
11924
11925
11926 /*-------------------------------------------------------------------------
11927 * Function: db_ResetGlobalData_Curve
11928 *
11929 * Purpose: Reset global data to default values.
11930 *
11931 * Return: void
11932 *
11933 * Programmer: Robb Matzke
11934 * robb@callisto.nuance.com
11935 * May 16, 1996
11936 *
11937 * Modifications:
11938 *
11939 * Mark C. Miller, Mon Jun 21 18:06:36 PDT 2004
11940 * Moved from silo_pdb.c to public place where any driver can call
11941 *-------------------------------------------------------------------------*/
11942 INTERNAL void
db_ResetGlobalData_Curve(void)11943 db_ResetGlobalData_Curve (void) {
11944
11945 memset (&_cu, 0, sizeof(_cu)) ;
11946 _cu._missing_value = DB_MISSING_VALUE_NOT_SET;
11947 }
11948
11949 /*----------------------------------------------------------------------
11950 * Routine db_ResetGlobalData_Ucdmesh
11951 *
11952 * Purpose
11953 *
11954 * Reset global data to default values. For internal use only.
11955 *
11956 * Programmer
11957 *
11958 * Jeffery W. Long, NSSD-B
11959 *
11960 * Notes
11961 *
11962 * It is assumed that _ndims has a valid value before this
11963 * function is invoked. (It is assigned to _nspace.)
11964 *
11965 * Modifications
11966 * Al Leibee, Wed Aug 3 16:57:38 PDT 1994
11967 * Added _use_specmf.
11968 *
11969 * Al Leibee, Mon Apr 18 07:45:58 PDT 1994
11970 * Added _dtime.
11971 *
11972 * Eric Brugger, Wed Oct 15 14:45:47 PDT 1997
11973 * Added _hi_offset and _lo_offset.
11974 *
11975 * Jeremy Meredith, Fri May 21 10:04:25 PDT 1999
11976 * Init group_no to -1.
11977 *
11978 * Mark C. Miller, Mon Jun 21 18:06:36 PDT 2004
11979 * Moved from silo_pdb.c to public place where any driver can call
11980 *
11981 * Brad Whitlock, Wed Jan 18 15:38:39 PST 2006
11982 * Added _ascii_labels.
11983 *
11984 * Thomas R. Treadway, Wed Jun 28 10:31:45 PDT 2006
11985 * Added _topo_dim..
11986 *
11987 * Mark C. Miller, Tue Jan 6 22:12:43 PST 2009
11988 * Made default value for topo_dim to be NOT SET (-1).
11989 *
11990 * Mark C. Miller, Mon Jan 12 16:26:08 PST 2009
11991 * Replaced 'topo_dim' with 'tdim_plus1', removed it from being
11992 * explicitly set. Likewise, removed explicit setting of other
11993 * entries that are already correctly handled by memset to zero.
11994 *--------------------------------------------------------------------*/
11995 INTERNAL int
db_ResetGlobalData_Ucdmesh(int ndims,int nnodes,int nzones)11996 db_ResetGlobalData_Ucdmesh (int ndims, int nnodes, int nzones) {
11997
11998 memset(&_um, 0, sizeof(_um));
11999 _um._coord_sys = DB_OTHER;
12000 _um._facetype = DB_RECTILINEAR;
12001 _um._ndims = ndims;
12002 _um._nnodes = nnodes;
12003 _um._nzones = nzones;
12004 _um._planar = DB_OTHER;
12005 _um._use_specmf = DB_OFF;
12006 _um._group_no = -1;
12007 _um._missing_value = DB_MISSING_VALUE_NOT_SET;
12008
12009 return 0;
12010 }
12011
12012 /*----------------------------------------------------------------------
12013 * Routine db_ResetGlobalData_Ucdzonelist
12014 *
12015 * Purpose
12016 *
12017 * Reset global data to default values. For internal use only.
12018 *
12019 * Programmer
12020 *
12021 * Jeremy Meredith, May 21 1999
12022 *
12023 * Notes
12024 *
12025 * Modifications
12026 *
12027 * Hank Childs, Thu Jan 6 16:10:03 PST 2000
12028 * Added void to function signature to avoid compiler warning.
12029 *
12030 * Mark C. Miller, Mon Jun 21 18:06:36 PDT 2004
12031 * Moved from silo_pdb.c to public place where any driver can call
12032 *--------------------------------------------------------------------*/
12033 INTERNAL int
db_ResetGlobalData_Ucdzonelist(void)12034 db_ResetGlobalData_Ucdzonelist (void) {
12035
12036 memset(&_uzl, 0, sizeof(_uzl));
12037
12038 return 0;
12039 }
12040
12041 /*----------------------------------------------------------------------
12042 * Routine db_ResetGlobalData_MultiMesh
12043 *
12044 * Purpose
12045 *
12046 * Reset global data to default values. For internal use only.
12047 *
12048 * Programmer
12049 *
12050 * Eric Brugger, January 12, 1996
12051 *
12052 * Notes
12053 *
12054 * Modifications
12055 * Eric Brugger, Thu Oct 16 10:40:00 PDT 1997
12056 * I added the options DBOPT_MATNOS and DBOPT_NMATNOS.
12057 *
12058 * Jeremy Meredith Sept 18 1998
12059 * Added options DBOPT_MATNAME, DBOPT_NMAT, and DBOPT_NMATSPEC.
12060 *
12061 * Jeremy Meredith, Fri May 21 10:04:25 PDT 1999
12062 * Added _blockorigin, _grouporigin, and _ngroups.
12063 *
12064 * Mark C. Miller, Mon Jun 21 18:06:36 PDT 2004
12065 * Moved from silo_pdb.c to public place where any driver can call
12066 *
12067 * Thomas R. Treadway, Thu Jul 20 11:06:27 PDT 2006
12068 * Added _lgroupings, _groupings, and _groupnames.
12069 *
12070 * Mark C. Miller, Mon Jan 12 16:28:18 PST 2009
12071 * Removed explicit setting of members already correctly handled
12072 * by memset to zero.
12073 *
12074 * Mark C. Miller, Thu Aug 30 17:55:43 PDT 2012
12075 * Removed setting nmatnos to -1.
12076 *--------------------------------------------------------------------*/
12077 INTERNAL int
db_ResetGlobalData_MultiMesh(void)12078 db_ResetGlobalData_MultiMesh (void) {
12079 memset(&_mm, 0, sizeof(_mm));
12080 _mm._nmat = -1;
12081 _mm._blockorigin = 1;
12082 _mm._grouporigin = 1;
12083 _mm._missing_value = DB_MISSING_VALUE_NOT_SET;
12084 return 0;
12085 }
12086
12087 /*----------------------------------------------------------------------
12088 * Routine db_ResetGlobalData_Defvars
12089 *
12090 * Purpose
12091 *
12092 * Reset global data to default values. For internal use only.
12093 *
12094 * Programmer:
12095 *
12096 * Mark C. Miller, March 22, 2006
12097 *--------------------------------------------------------------------*/
12098 INTERNAL int
db_ResetGlobalData_Defvars(void)12099 db_ResetGlobalData_Defvars (void) {
12100 memset(&_dv, 0, sizeof(_dv));
12101 return 0;
12102 }
12103
12104 INTERNAL int
db_ResetGlobalData_Mrgtree(void)12105 db_ResetGlobalData_Mrgtree (void) {
12106 memset(&_mrgt, 0, sizeof(_mrgt));
12107 return 0;
12108 }
12109
12110 /*----------------------------------------------------------------------
12111 * Routine db_FullName2BaseName
12112 *
12113 * Purpose
12114 *
12115 * Given a the full path name of an object in the db, return
12116 * the object's basename.
12117 *
12118 * Programmer
12119 *
12120 * Mark C. Miller, June 22, 2004
12121 *
12122 * Modifications:
12123 * Mark C. Miller, Thu Sep 7 10:50:55 PDT 2006
12124 * Made it just use Jim Reus' new basename routine.
12125 *--------------------------------------------------------------------*/
12126 INTERNAL char *
db_FullName2BaseName(const char * path)12127 db_FullName2BaseName(const char *path)
12128 {
12129 return db_basename(path);
12130 }
12131
12132 /*----------------------------------------------------------------------
12133 * Purpose
12134 *
12135 * catenate an array of strings into a single, semicolon seperated
12136 * string list
12137 *
12138 * Programmer
12139 *
12140 * Mark C. Miller, July 20, 2005
12141 *
12142 * Modifications:
12143 * Mark C. Miller, Wed Oct 3 21:51:42 PDT 2007
12144 * Made it handle null string as no chars output and empty string
12145 * ("") as '\n' output so during readback, we can construct either
12146 * null ptrs or emtpy strings correctly.
12147 * Made it handle a variable length list where n is unspecified.
12148 *
12149 * Mark C. Miller, Wed Jul 14 20:38:46 PDT 2010
12150 * Made this function public, replacing 'db_' with 'DB' in name.
12151 *--------------------------------------------------------------------*/
12152 PUBLIC void
DBStringArrayToStringList(char const * const * strArray,int n,char ** strList,int * m)12153 DBStringArrayToStringList(
12154 char const * const *strArray,
12155 int n,
12156 char **strList,
12157 int *m
12158 )
12159 {
12160 int i, len;
12161 char *s = NULL;
12162
12163 /* if n is unspecified, determine it by counting forward until
12164 we get a null pointer */
12165 if (n < 0)
12166 {
12167 n = 0;
12168 while (strArray[n] != 0)
12169 n++;
12170 }
12171
12172 /*
12173 * Create a string which is a semi-colon separated list of strings
12174 */
12175 for (i=len=0; i<n; i++)
12176 {
12177 if (strArray[i])
12178 len += strlen(strArray[i])+1;
12179 else
12180 len += 2;
12181 }
12182 s = (char*)malloc(len+1);
12183 for (i=len=0; i<n; i++) {
12184 if (i) s[len++] = ';';
12185 if (strArray[i])
12186 {
12187 strcpy(s+len, strArray[i]);
12188 len += strlen(strArray[i]);
12189 }
12190 else
12191 {
12192 s[len++] = '\n';
12193 }
12194 }
12195 len++; /*count last null*/
12196
12197 *strList = s;
12198 *m = len;
12199 }
12200
12201 /*----------------------------------------------------------------------
12202 * Purpose
12203 *
12204 * Decompose a single, semicolon seperated string list into an array
12205 * of strings
12206 *
12207 * Programmer
12208 *
12209 * Mark C. Miller, July 20, 2005
12210 *
12211 * Modfications:
12212 *
12213 * Mark C. Miller, Fri Jul 14 23:39:32 PDT 2006
12214 * Fixed problem with empty strings in the input list being skipped
12215 *
12216 * Mark C. Miller, Wed Oct 3 21:54:35 PDT 2007
12217 * Made it return empty or null strings depending on input
12218 * Made it handle a variable length list where n is unspecified
12219 *
12220 * Mark C. Miller, Mon Nov 9 12:10:47 PST 2009
12221 * Added logic to handle swapping of slash character between
12222 * windows/linux. Note that swapping of slash character only
12223 * makes sense in certain context and only when it appears in
12224 * a string BEFORE a colon character. We try to minimize the
12225 * amount of work we do looking for a colon character by
12226 * remembering where we find it in the last substring.
12227 *
12228 * Mark C. Miller, Thu Dec 17 17:09:27 PST 2009
12229 * Fixed UMR on strLen when n>=0.
12230 *
12231 * Mark C. Miller, Wed Jul 14 20:38:46 PDT 2010
12232 * Made this function public, replacing 'db_' with 'DB' in name.
12233 * Merged fixes from 4.7.3 patches to fix problems with swaping
12234 * the slash character.
12235 *
12236 * Mark C. Miller, Wed Jun 30 16:01:17 PDT 2010
12237 * Made logic for handling slash swap more sane. Now, swapping is
12238 * performed AFTER the list of strings has been broken out into
12239 * separate arrays.
12240 *
12241 * Mark C. Miller, Fri Oct 12 22:57:23 PDT 2012
12242 * Changed interface to return value for number of strings as well
12243 * as accept an input value or nothing at all.
12244 *--------------------------------------------------------------------*/
12245 PUBLIC char **
DBStringListToStringArray(char const * strList,int * _n,int skipSemicolonAtIndexZero)12246 DBStringListToStringArray(char const *strList, int *_n, int skipSemicolonAtIndexZero)
12247 {
12248 int i, l, n, add1 = 0;
12249 char **retval;
12250
12251 /* if n is unspecified (<0), compute it by counting semicolons */
12252 if (_n == 0 || *_n < 0)
12253 {
12254 add1 = 1;
12255 n = 1;
12256 i = (skipSemicolonAtIndexZero&&strList[0]==';')?1:0;
12257 while (strList[i] != '\0')
12258 {
12259 if (strList[i] == ';')
12260 n++;
12261 i++;
12262 }
12263 }
12264 else
12265 {
12266 n = *_n;
12267 }
12268
12269 retval = (char**) calloc(n+add1, sizeof(char*));
12270 for (i=0, l=(skipSemicolonAtIndexZero&&strList[0]==';')?1:0; i<n; i++)
12271 {
12272 if (strList[l] == ';')
12273 {
12274 retval[i] = STRDUP("");
12275 l += 1;
12276 }
12277 else if (strList[l] == '\n')
12278 {
12279 retval[i] = 0;
12280 l += 2;
12281 }
12282 else
12283 {
12284 int len, lstart = l;
12285 while (strList[l] != ';' && strList[l] != '\0')
12286 l++;
12287 len = l-lstart;
12288 retval[i] = (char *) malloc(len+1);
12289 memcpy(retval[i],&strList[lstart],len);
12290 retval[i][len] = '\0';
12291 l++;
12292 }
12293 }
12294 if (add1) retval[i] = 0;
12295
12296 /* Return value of n computed if requested */
12297 if (_n && *_n < 0) *_n = n;
12298
12299 return retval;
12300 }
12301
12302 INTERNAL int
db_StringListToStringArrayMBOpt(char * strList,char *** retArray,char ** alloc_flag,int nblocks)12303 db_StringListToStringArrayMBOpt(char *strList, char ***retArray, char **alloc_flag, int nblocks)
12304 {
12305 int i=0, s=0, n=0, hasColon=0, nearlyDone = 0, completelyDone = 0, slashCharsToSwap[128];
12306 char **strArray;
12307 static char const *me = "DBStringListToStringArrayMBOpt";
12308
12309 if (!strList) return 0;
12310
12311 if (nblocks <= 0)
12312 return db_perror("nblocks", E_BADARGS, me);
12313
12314 strArray = (char **) malloc(nblocks * sizeof(char*));
12315 if (strList[0] == ';')
12316 i = 1;
12317 strArray[n++] = &strList[i];
12318 while (!completelyDone)
12319 {
12320 switch (strList[i])
12321 {
12322 case '\0':
12323 completelyDone = 1; // note fall-through to next case
12324 case ';':
12325 {
12326 strList[i] = '\0';
12327 if (!completelyDone) i++;
12328 if (strList[i] != '\0')
12329 strArray[n++] = &strList[i];
12330 if (hasColon)
12331 {
12332 int j;
12333 for (j = 0; j < hasColon; j++)
12334 #if !defined(_WIN32)
12335 strList[slashCharsToSwap[j]] = '/';
12336 #else
12337 strList[slashCharsToSwap[j]] = '\\';
12338 #endif
12339 }
12340 s = 0;
12341 hasColon = 0;
12342 break;
12343 }
12344 #if !defined(_WIN32) /* linux case */
12345 case '\\':
12346 #else /* windows case */
12347 case '/':
12348 #endif
12349 {
12350 if (hasColon)
12351 break;
12352 slashCharsToSwap[s++] = i;
12353 if (s == sizeof(slashCharsToSwap)/sizeof(slashCharsToSwap[0]))
12354 {
12355 free(strList);
12356 free(strArray);
12357 return db_perror("exceeded slashCharsToSwap size", E_INTERNAL, me);
12358 }
12359 break;
12360 }
12361 case ':':
12362 {
12363 hasColon = s;
12364 break;
12365 }
12366 }
12367 if (!completelyDone)
12368 {
12369 if (strList[i] != '\0')
12370 i++;
12371 if (strList[i] == '\0')
12372 nearlyDone = 1;
12373 }
12374 }
12375
12376 if (n != nblocks)
12377 {
12378 free(strArray);
12379 return db_perror("incorrect number of block names", E_INTERNAL, me);
12380 }
12381
12382 /* ensure we store the originally allocated pointer for later free's */
12383 *alloc_flag = strList;
12384
12385 *retArray = strArray;
12386
12387 return 0;
12388 }
12389
12390 /*-------------------------------------------------------------------------
12391 * Function: DBSortObjectsByOffset
12392 *
12393 * Purpose: Determines the offset within the Silo file of each object
12394 * in the list of objects passed in and returns an array
12395 * and returns an integer array indicating their ordering.
12396 *
12397 * Return: Success: Non-zero.
12398 * Failure: zero.
12399 *
12400 * Programmer: Mark C. Miller, Thu Jul 15 06:40:27 PDT 2010
12401 *-------------------------------------------------------------------------*/
12402 PUBLIC int
DBSortObjectsByOffset(DBfile * dbfile,int nobjs,const char * const * const names,int * ordering)12403 DBSortObjectsByOffset(DBfile *dbfile, int nobjs,
12404 const char *const *const names, int *ordering)
12405 {
12406 int retval;
12407
12408 API_BEGIN2("DBSortObjectsByOffset", int, -1, api_dummy);
12409 {
12410 if (!dbfile)
12411 API_ERROR(NULL, E_NOFILE);
12412 if (nobjs <= 0)
12413 API_ERROR("nobjs", E_BADARGS);
12414 if (!names)
12415 API_ERROR("names", E_BADARGS);
12416 if (!ordering)
12417 API_ERROR("ordering", E_BADARGS);
12418 if (!dbfile->pub.sort_obo)
12419 API_ERROR(dbfile->pub.name, E_NOTIMP);
12420
12421 retval = (dbfile->pub.sort_obo) (dbfile, nobjs, names, ordering);
12422
12423 API_RETURN(retval);
12424 }
12425 API_END_NOPOP; /* If API_RETURN above is removed, use API_END instead */
12426 }
12427
12428 /*----------------------------------------------------------------------
12429 * Purpose
12430 *
12431 * Break an extend driver id into type and subtype
12432 *
12433 * Programmer
12434 *
12435 * Mark C. Miller, July 31, 2006
12436 *
12437 * Modifications:
12438 * Mark C. Miller, Mon Aug 21 23:14:29 PDT 2006
12439 * Made code that references DB_HDF5 conditionally compiled
12440 *
12441 * Mark C. Miller, Thu Feb 11 09:51:28 PST 2010
12442 * Changed logic for how subtype is handled.
12443 *
12444 * Mark C. Miller, Thu Feb 25 19:00:09 PST 2010
12445 * Versions of silo 4.7.2 and earlier used a bit of a brain dead way
12446 * to specify alternative HDF5 vfds by manipulating the high order
12447 * bits in the integer 'type' arg to DBCreate/DBOpen. For example, the
12448 * default HDF5 driver was '7' while HDF5 w/STDIO vfd was '0x200'. This
12449 * was inflexible and unable to handle the large variety of options
12450 * available in HDF5.
12451 *
12452 * Versions of silo newer than 4.7.2 use a global array of options
12453 * sets registered and stored in the SILO_Globals structure. So,
12454 * a particular set of HDF5 vfd options is identified by a single
12455 * integer indexing into this global list of options. It is this integer
12456 * index that is shifted left by 11 bits to make space for the primary
12457 * Silo driver id (e.g. DB_PDB or DB_HDF5) and obsoleted HDF5 vfd
12458 * specifications and then OR'd into the integer 'type' arg in the
12459 * DBCreate/DBOpen calls to specify HDF5 vfd options.
12460 *
12461 * In the initial implementation of this new approach using a global
12462 * array of options sets, we allowed for a total of 32 (5 bits)
12463 * options sets plus another 10 default options sets for convenience.
12464 * But, we don't actually store the 10 default options set and use
12465 * only the integer identifer between 0 and 9 to identify them.
12466 * So, the identifier for a given options set ranges from 0...41
12467 * requiring a total of 6 bits. Those 6 bits are 0x1F800.
12468 *--------------------------------------------------------------------*/
12469 INTERNAL void
db_DriverTypeAndFileOptionsSetId(int driver,int * type,int * _opts_set_id)12470 db_DriverTypeAndFileOptionsSetId(int driver, int *type, int *_opts_set_id)
12471 {
12472 int theType = driver&0xF;
12473 int opts_set_id = 0;
12474
12475 if (driver > DB_NFORMATS)
12476 {
12477 opts_set_id = (driver&0x1F800)>>11;
12478 #ifdef DB_HDF5X
12479 if (theType == DB_HDF5X)
12480 {
12481 int obsolete_subType = driver&0x700;
12482 switch (obsolete_subType)
12483 {
12484 case DB_HDF5_SEC2_OBSOLETE:
12485 opts_set_id = DB_FILE_OPTS_H5_DEFAULT_SEC2;
12486 break;
12487 case DB_HDF5_STDIO_OBSOLETE:
12488 opts_set_id = DB_FILE_OPTS_H5_DEFAULT_STDIO;
12489 break;
12490 case DB_HDF5_CORE_OBSOLETE:
12491 opts_set_id = DB_FILE_OPTS_H5_DEFAULT_CORE;
12492 break;
12493 case DB_HDF5_MPIO_OBSOLETE:
12494 opts_set_id = DB_FILE_OPTS_H5_DEFAULT_MPIO;
12495 break;
12496 case DB_HDF5_MPIOP_OBSOLETE:
12497 opts_set_id = DB_FILE_OPTS_H5_DEFAULT_MPIP;
12498 break;
12499 default:
12500 break;
12501 }
12502 }
12503 #endif
12504 }
12505
12506 if (type) *type = theType;
12507 if (_opts_set_id) *_opts_set_id = opts_set_id;
12508 }
12509
12510 /*
12511 *
12512 * The following data structures and functions for manipulating
12513 * character strings representing pathnames was originally written
12514 * by James F. Reus as part of the DSL Library. It was extracted from
12515 * DSL and adapted, slightly, for use in the Silo library by Mark C. Miller
12516 *
12517 * BEGIN CODE FROM JIM REUS' DSL {
12518 *
12519 */
12520
db_absoluteOf_path(const char * cwg,const char * pathname)12521 char *db_absoluteOf_path (const char *cwg,
12522 const char *pathname)
12523 { char *result;
12524
12525 if (pathname && strlen(pathname))
12526 { if (db_isAbsolute_path(pathname))
12527 result = db_normalize_path(pathname);
12528 else if (cwg && strlen(cwg))
12529 result = db_join_path(cwg,pathname);
12530 else
12531 result = _db_safe_strdup("");
12532 }
12533 else
12534 {
12535 result = _db_safe_strdup("");
12536 }
12537 return result;
12538 }
12539
12540 /*-------------------------------------------------------------------------- - -
12541 |
12542 | Description: This function returns a string representing the basename part
12543 | of the given pathname (stripping off the parent path). Note
12544 | that special cases arise...
12545 |
12546 | pathname == 0 Return value is 0.
12547 | pathname == "/" Return value is "/".
12548 | pathname == "/base" Return value is "base".
12549 | pathname == "base" Return value is "base".
12550 | pathname == "path/base" Return value is "base".
12551 |
12552 | Return: A pointer to a NULL-terminated string is returned when this
12553 | function is successful. Note that this string is constructed
12554 | from allocated dynamic memory, it is up to the caller to
12555 | release this string when it is no longer needed. A 0
12556 | pointer is returned on error.
12557 |
12558 +-----------------------------------------------------------------------------*/
12559
db_basename(const char * pathname)12560 char *db_basename ( const char *pathname )
12561 { char *result;
12562
12563 result = 0;
12564 { if (0 < strlen(pathname))
12565 { if (strcmp(pathname,"/") == 0)
12566 result = STRDUP("/");
12567 else
12568 { int i;
12569
12570 for (i=(int)strlen(pathname)-1; 0<=i; --i)
12571 if (pathname[i] == '/')
12572 { result = STRDUP(&(pathname[i+1]));
12573 goto theExit;
12574 }
12575 result = STRDUP(pathname);
12576 }
12577 }
12578 }
12579 theExit:
12580 return result;
12581 }
12582
12583 /*-------------------------------------------------------------------------- - -
12584 |
12585 | Description: This function is used to release all storage associated
12586 | with the given pathname component list. Such a pathname
12587 | component list is typically derived from a NULL-terminated
12588 | string using the db_split_path() function.
12589 |
12590 | Return: A 0 pointer is always returned.
12591 |
12592 +-----------------------------------------------------------------------------*/
12593
db_cleanup_path(db_Pathname * p)12594 db_Pathname *db_cleanup_path ( db_Pathname *p )
12595 {
12596 { if (p != 0)
12597 { while (p->firstComponent != 0)
12598 { db_PathnameComponent *c;
12599
12600 c = p->firstComponent;
12601 p->firstComponent = c->nextComponent;
12602 if (c->nextComponent == 0)
12603 p->lastComponent = 0;
12604 else
12605 c->nextComponent->prevComponent = 0;
12606 if (c->name != 0)
12607 { free(c->name);
12608 c->name = 0;
12609 }
12610 c->prevComponent = 0;
12611 c->nextComponent = 0;
12612 free(c);
12613 }
12614 free(p);
12615 p = 0;
12616 }
12617 }
12618 return p;
12619 }
12620
12621 /*-------------------------------------------------------------------------- - -
12622 |
12623 | Description: This function returns a string representing the dirname part
12624 | of the given pathname (stripping off the parent path). Note
12625 | that special cases arise...
12626 |
12627 | pathname == 0 Return value is 0.
12628 | pathname == "/" Return value is "".
12629 | pathname == "/base" Return value is "/".
12630 | pathname == "base" Return value is ".".
12631 | pathname == "path/base" Return value is "path".
12632 |
12633 | Return: A pointer to a NULL-terminated string is returned when this
12634 | function is successful. Note that this string is constructed
12635 | from allocated dynamic memory, it is up to the caller to
12636 | release this string when it is no longer needed. A 0
12637 | pointer is returned on error.
12638 |
12639 +-----------------------------------------------------------------------------*/
12640
db_dirname(const char * pathname)12641 char *db_dirname ( const char *pathname )
12642 { char *result;
12643
12644 result = 0;
12645 { if (0 < strlen(pathname))
12646 { if (strcmp(pathname,"/") == 0)
12647 result = STRDUP("");
12648 else
12649 { int i;
12650 char tmp[32767];
12651
12652 strcpy(tmp,pathname);
12653 for (i=(int)strlen(tmp)-1; 0<=i; --i)
12654 if (tmp[i] == '/')
12655 { if (i == 0)
12656 tmp[1] = '\0';
12657 else
12658 tmp[i] = '\0';
12659 result = STRDUP(tmp);
12660 goto theExit;
12661 }
12662 result = STRDUP(".");
12663 }
12664 }
12665 }
12666 theExit:
12667 return result;
12668 }
12669
12670 /*-------------------------------------------------------------------------- - -
12671 |
12672 | Description: This function is used to determine if the given pathname
12673 | is an absolute pathname. Note that this is really just a
12674 | test for a leading '/'.
12675 |
12676 | Return: A value of TRUE is returned when the function is
12677 | successful, otherwise a value of FALSE is returned.
12678 |
12679 +-----------------------------------------------------------------------------*/
12680
db_isAbsolute_path(const char * pathname)12681 int db_isAbsolute_path ( const char *pathname )
12682 { int result;
12683
12684 result = FALSE;
12685 if (0 < strlen(pathname))
12686 if (pathname[0] == '/')
12687 result = TRUE;
12688 return result;
12689 }
12690
12691 /*-------------------------------------------------------------------------- - -
12692 |
12693 | Description: This function is used to determine if the given pathname is an
12694 | relative pathname. Note that this is really just a test for a
12695 | leading '/'.
12696 |
12697 | Return: A value of TRUE is returned when the function is
12698 | successful, otherwise a value of FALSE is returned.
12699 +-----------------------------------------------------------------------------*/
12700
db_isRelative_path(const char * pathname)12701 int db_isRelative_path ( const char *pathname )
12702 { int result;
12703
12704 result = FALSE;
12705 if (0 < strlen(pathname))
12706 if (pathname[0] != '/')
12707 result = TRUE;
12708 return result;
12709 }
12710
12711 /*-------------------------------------------------------------------------- - -
12712 |
12713 | Description: This function joins the two given pathname components to form
12714 | a new pathname. The result is normalized to deal properly
12715 | with absolute pathnames, `.' and `..' components. For
12716 | example: joining "abc/def" and "../xyz/123" would result
12717 | in "abc/xyz/123". Note that joining "abc/123" and "/xyz"
12718 | will yield "/xyz" since the second part is an absolute
12719 | path. Note that the first operand, a, is treated as the
12720 | "root" for any '.' or '..' in operand b.
12721 |
12722 | Return: A pointer to a NULL-terminated string is returned when this
12723 | function is successful. Note that this string is constructed
12724 | from allocated dynamic memory, it is up to the caller to
12725 | release this string when it is no longer needed. A 0
12726 | pointer is returned on error.
12727 |
12728 | Modifications:
12729 |
12730 | Mark C. Miller, Wed Oct 18 08:41:33 PDT 2006
12731 | Fixed bug where result was set at top of function but then uninitialized
12732 | tmp was tested at end causing result to be set to zero
12733 +-----------------------------------------------------------------------------*/
12734
db_join_path(const char * a,const char * b)12735 char *db_join_path ( const char *a,
12736 const char *b )
12737 { char *result;
12738 char *tmp;
12739
12740 if (strlen(b) == 0)
12741 return db_normalize_path(a);
12742 else if (strlen(a) == 0)
12743 return db_normalize_path(b);
12744 else if (db_isAbsolute_path(b))
12745 return db_normalize_path(b);
12746 else
12747 { db_Pathname *Pa;
12748
12749 tmp = 0;
12750 if ((Pa=db_split_path(a)) != 0)
12751 { db_Pathname *Pb;
12752
12753 if ((Pb=db_split_path(b)) != 0)
12754 { db_Pathname *t;
12755
12756 if ((t=(db_Pathname *)malloc(sizeof(db_Pathname))) != 0)
12757 { db_PathnameComponent *c;
12758 int ok;
12759
12760 t->firstComponent = 0;
12761 t->lastComponent = 0;
12762 ok = TRUE;
12763 c = Pa->firstComponent;
12764 while (c != 0)
12765 { db_PathnameComponent *k;
12766
12767 if ((k=(db_PathnameComponent *)malloc(sizeof(db_PathnameComponent))) != 0)
12768 { if (c->name != 0)
12769 k->name = STRDUP(c->name);
12770 else
12771 k->name = 0;
12772 k->prevComponent = t->lastComponent;
12773 k->nextComponent = 0;
12774 if (t->lastComponent == 0)
12775 t->firstComponent = k;
12776 else
12777 t->lastComponent->nextComponent = k;
12778 t->lastComponent = k;
12779 }
12780 else
12781 { ok = FALSE;
12782 break;
12783 }
12784 c = c->nextComponent;
12785 }
12786 if (ok)
12787 { c = Pb->firstComponent;
12788 while (c != 0)
12789 { db_PathnameComponent *k;
12790
12791 if ((k=(db_PathnameComponent *)malloc(sizeof(db_PathnameComponent))) != 0)
12792 { if (c->name != 0)
12793 k->name = STRDUP(c->name);
12794 else
12795 k->name = 0;
12796 k->prevComponent = t->lastComponent;
12797 k->nextComponent = 0;
12798 if (t->lastComponent == 0)
12799 t->firstComponent = k;
12800 else
12801 t->lastComponent->nextComponent = k;
12802 t->lastComponent = k;
12803 }
12804 else
12805 { ok = FALSE;
12806 break;
12807 }
12808 c = c->nextComponent;
12809 }
12810 if (ok)
12811 tmp = db_unsplit_path(t);
12812 }
12813 db_cleanup_path(t);
12814 }
12815 db_cleanup_path(Pb);
12816 }
12817 db_cleanup_path(Pa);
12818 }
12819 }
12820 if (tmp != 0)
12821 {
12822 result = db_normalize_path(tmp);
12823 free(tmp);
12824 }
12825 else
12826 result = 0;
12827 return result;
12828 }
12829
12830 /*-------------------------------------------------------------------------- - -
12831 |
12832 | Description: This function is used to normalize the given pathname, dealing
12833 | with dots, double-dots and such.
12834 |
12835 | This function resolves:
12836 |
12837 | - double slashes (such as abc//123)
12838 | - trailing slashes (such as abc/)
12839 | - embedded single dots (such as abc/./123) except for
12840 | some leading dots.
12841 | - name-double dot sets (such as abc/../123)
12842 |
12843 | Return: A pointer to a NULL-terminated string is returned when this
12844 | function is successful. Note that this string is constructed
12845 | from allocated dynamic memory, it is up to the caller to
12846 | release this string when it is no longer needed. A 0
12847 | pointer is returned on error.
12848 |
12849 +-----------------------------------------------------------------------------*/
12850
db_normalize_path(const char * pathname)12851 char *db_normalize_path ( const char *pathname )
12852 { char *result;
12853
12854 result = 0;
12855 if (0 < strlen(pathname))
12856 { db_Pathname *p;
12857
12858 /*--------------------------------------
12859 |
12860 | Break into separate components...
12861 |
12862 +-------------------------------------*/
12863
12864 if ((p=(db_split_path(pathname))) != 0)
12865 { db_PathnameComponent *c;
12866
12867 /*--------------------------------------
12868 |
12869 | Eliminate . components
12870 |
12871 +-------------------------------------*/
12872
12873 c = p->firstComponent;
12874 while (c != 0)
12875 { if (c != p->firstComponent)
12876 { if (c->name && (strcmp(c->name,".") == 0))
12877 { db_PathnameComponent *cc;
12878
12879 cc = c->nextComponent;
12880 if (c->prevComponent == 0)
12881 p->firstComponent = c->nextComponent;
12882 else
12883 c->prevComponent->nextComponent = c->nextComponent;
12884 if (c->nextComponent == 0)
12885 p->lastComponent = c->prevComponent;
12886 else
12887 c->nextComponent->prevComponent = c->prevComponent;
12888 free(c->name);
12889 c->name = 0;
12890 c->prevComponent = 0;
12891 c->nextComponent = 0;
12892 free(c);
12893 c = cc;
12894 }
12895 else
12896 c = c->nextComponent;
12897 }
12898 else
12899 c = c->nextComponent;
12900 }
12901
12902 /*--------------------------------------
12903 |
12904 | Eliminate .. components, note
12905 | that this process is a little
12906 | tougher then the . case, this
12907 | is due to things like ../../a/b
12908 |
12909 +-------------------------------------*/
12910
12911 tryAgain:c = p->firstComponent;
12912 while (c != 0)
12913 { if (c->name && (strcmp(c->name,"..") == 0))
12914 { db_PathnameComponent *k;
12915
12916 if ((k=c->prevComponent) != 0)
12917 { if (k->name != 0 && strcmp(k->name,"..") != 0)
12918 {
12919 if (k->prevComponent == 0)
12920 p->firstComponent = k->nextComponent;
12921 else
12922 k->prevComponent->nextComponent = k->nextComponent;
12923 if (k->nextComponent == 0)
12924 p->lastComponent = k->prevComponent;
12925 else
12926 k->nextComponent->prevComponent = k->prevComponent;
12927 if (k->name != 0)
12928 free(k->name);
12929 k->name = 0;
12930 k->prevComponent = 0;
12931 k->nextComponent = 0;
12932 free(k);
12933 k = 0;
12934 if (c->prevComponent == 0)
12935 p->firstComponent = c->nextComponent;
12936 else
12937 c->prevComponent->nextComponent = c->nextComponent;
12938 if (c->nextComponent == 0)
12939 p->lastComponent = c->prevComponent;
12940 else
12941 c->nextComponent->prevComponent = c->prevComponent;
12942 if (c->name != 0)
12943 free(c->name);
12944 c->name = 0;
12945 c->prevComponent = 0;
12946 c->nextComponent = 0;
12947 free(c);
12948 c = 0;
12949 goto tryAgain;
12950 }
12951 }
12952 }
12953 c = c->nextComponent;
12954 }
12955
12956 /*--------------------------------------
12957 |
12958 | Rejoin components into a string...
12959 |
12960 +-------------------------------------*/
12961
12962 result = db_unsplit_path(p);
12963 db_cleanup_path(p);
12964 }
12965 }
12966 return result;
12967 }
12968
makePathname(void)12969 static db_Pathname *makePathname ( void )
12970 { db_Pathname *p;
12971
12972 if ((p=(db_Pathname *)malloc(sizeof(db_Pathname))) != 0)
12973 { p->firstComponent = 0;
12974 p->lastComponent = 0;
12975 }
12976 return p;
12977 }
12978
appendComponent(db_Pathname * p,char * s)12979 static db_Pathname *appendComponent ( db_Pathname *p, char *s )
12980 { if (p == 0)
12981 p = makePathname();
12982 if (p != 0)
12983 { db_PathnameComponent *c;
12984
12985 if ((c=(db_PathnameComponent *)malloc(sizeof(db_PathnameComponent))) != 0)
12986 { c->name = STRDUP(s);
12987 c->prevComponent = p->lastComponent;
12988 c->nextComponent = 0;
12989 if (p->lastComponent == 0)
12990 p->firstComponent = c;
12991 else
12992 p->lastComponent->nextComponent = c;
12993 p->lastComponent = c;
12994 }
12995 }
12996 return p;
12997 }
12998
12999 /*-------------------------------------------------------------------------- - -
13000 |
13001 | Description: This function splits a given pathname into its components.
13002 | The split is generally made at the embedded slashes (/),
13003 | forming a linked list of pathname components. For example
13004 | the pathname "abc/def/123/xyz" has four components: "abc",
13005 | "def", "123", and "xyz". Note that the list of components
13006 | returned by this function is formed using allocated dynamic
13007 | memory and should be released using the db_cleanup_path()
13008 | function when it is no longer needed. This function is
13009 | intended for internal use only.
13010 |
13011 | Return: A pointer to the first component of a list of pathname
13012 | components is returned when this function succeeds, otherwise
13013 | a 0 pointer is returned.
13014 |
13015 +-----------------------------------------------------------------------------*/
13016
db_split_path(const char * pathname)13017 db_Pathname *db_split_path ( const char *pathname )
13018 { db_Pathname *result;
13019
13020 result = 0;
13021 if (0 < strlen(pathname))
13022 { if ((result=makePathname()) != 0)
13023 { int L;
13024 int state;
13025 char tmp[32767];
13026
13027 L = 0;
13028 tmp[L] = '\0';
13029 state = 0;
13030 for (;;)
13031 { char c;
13032
13033 c = *pathname;
13034 switch (state)
13035 { case 0: switch (c)
13036 { case '\0': goto done;
13037 case '/': result = appendComponent(result,0);
13038 state = 1;
13039 break;
13040 default: L = 0;
13041 tmp[L] = c;
13042 L += 1;
13043 tmp[L] = '\0';
13044 state = 2;
13045 break;
13046 }
13047 break;
13048 case 1: switch (c)
13049 { case '\0': goto done;
13050 case '/': state = 1;
13051 break;
13052 default: L = 0;
13053 tmp[L] = c;
13054 L += 1;
13055 tmp[L] = '\0';
13056 state = 2;
13057 break;
13058 }
13059 break;
13060 case 2: switch (c)
13061 { case '\0': result = appendComponent(result,tmp);
13062 goto done;
13063 case '/': result = appendComponent(result,tmp);
13064 state = 1;
13065 break;
13066 default: tmp[L] = c;
13067 L += 1;
13068 tmp[L] = '\0';
13069 state = 2;
13070 break;
13071 }
13072 break;
13073 }
13074 pathname += 1;
13075 }
13076 done: ;
13077 }
13078 }
13079 return result;
13080 }
13081
13082 /*------------------------------------------------------------------------------
13083 |
13084 | Description: This function forms a pathname string from a linked set of
13085 | pathname components. Note that this function is intended for
13086 | internal use only.
13087 |
13088 | Modifications:
13089 | Mark C. Miller, Wed Jul 11 17:01:09 PDT 2012
13090 | Initialize tmp buffer to the empty string with tmp[0] = '\0'
13091 +-----------------------------------------------------------------------------*/
13092
db_unsplit_path(const db_Pathname * p)13093 char *db_unsplit_path ( const db_Pathname *p )
13094 { char *result;
13095
13096 result = 0;
13097 if (p != 0)
13098 { db_PathnameComponent *c;
13099 int first;
13100 int slashed;
13101 static char tmp[4096];
13102
13103 tmp[0] = '\0';
13104 first = TRUE;
13105 slashed = FALSE;
13106 c = p->firstComponent;
13107 while (c != 0)
13108 {
13109 if ((c->name == 0) || (strlen(c->name) == 0))
13110 { strcpy(tmp,"/");
13111 slashed = TRUE;
13112 }
13113 else
13114 { if ((!slashed) && (!first))
13115 { strcat(tmp,"/");
13116 slashed = TRUE;
13117 }
13118 strcat(tmp,c->name);
13119 slashed = FALSE;
13120 }
13121 first = FALSE;
13122 c = c->nextComponent;
13123 }
13124 result = STRDUP(tmp);
13125 }
13126 return result;
13127 }
13128
13129 /*
13130 * END CODE FROM JIM REUS' DSL }
13131 */
13132
13133 static void
DBFreeMrgnode(DBmrgtnode * tnode,int walk_order,void * data)13134 DBFreeMrgnode(DBmrgtnode *tnode, int walk_order, void *data)
13135 {
13136 if (tnode == 0)
13137 return;
13138 FREE(tnode->name);
13139 if (tnode->narray > 0)
13140 {
13141 if (strchr(tnode->names[0], '%') == 0)
13142 {
13143 int i;
13144 for (i = 0; i < tnode->narray; i++)
13145 FREE(tnode->names[i]);
13146 FREE(tnode->names);
13147 }
13148 else
13149 {
13150 FREE(tnode->names[0]);
13151 FREE(tnode->names);
13152 }
13153 }
13154 FREE(tnode->maps_name);
13155 FREE(tnode->seg_ids);
13156 FREE(tnode->seg_lens);
13157 FREE(tnode->seg_types);
13158 FREE(tnode->children);
13159 FREE(tnode);
13160 }
13161
DBFreeMrgtree(DBmrgtree * tree)13162 void DBFreeMrgtree(DBmrgtree *tree)
13163 {
13164 if (tree == 0)
13165 return;
13166 DBWalkMrgtree(tree, (DBmrgwalkcb) DBFreeMrgnode, 0, DB_POSTORDER);
13167 FREE(tree->name);
13168 FREE(tree->src_mesh_name);
13169 if (tree->mrgvar_onames)
13170 {
13171 int i = 0;
13172 while (tree->mrgvar_onames[i] != 0)
13173 {
13174 FREE(tree->mrgvar_onames[i]);
13175 i++;
13176 }
13177 FREE(tree->mrgvar_onames);
13178 }
13179 if (tree->mrgvar_rnames)
13180 {
13181 int i = 0;
13182 while (tree->mrgvar_rnames[i] != 0)
13183 {
13184 FREE(tree->mrgvar_rnames[i]);
13185 i++;
13186 }
13187 FREE(tree->mrgvar_rnames);
13188 }
13189 FREE(tree);
13190 }
13191
DBPrintMrgtree(DBmrgtnode * tnode,int walk_order,void * data)13192 void DBPrintMrgtree(DBmrgtnode *tnode, int walk_order, void *data)
13193 {
13194 FILE *f = (FILE *) data;
13195 int level = -1;
13196 DBmrgtnode *tmp = tnode;
13197
13198 /* walk to top to determine level of indentation */
13199 while (tmp != 0)
13200 {
13201 tmp = tmp->parent;
13202 level++;
13203 }
13204 level *= 3;
13205
13206 if (f == 0)
13207 f = stdout;
13208
13209 /* print this node using special '*' field width specifier */
13210 fprintf(f, "%*s name = \"%s\" {\n", level, "", tnode->name);
13211 fprintf(f, "%*s walk_order = %d\n", level, "", tnode->walk_order);
13212 fprintf(f, "%*s parent = \"%s\"\n", level, "", tnode->parent?tnode->parent->name:"");
13213 fprintf(f, "%*s narray = %d\n", level, "", tnode->narray);
13214 if (tnode->narray > 0)
13215 {
13216 if (strchr(tnode->names[0], '%') == 0)
13217 {
13218 int j;
13219 fprintf(f, "%*s names = ...\n", level, "");
13220 for (j = 0; j < tnode->narray; j++)
13221 fprintf(f, "%*s \"%s\"\n", level, "", tnode->names[j]);
13222 }
13223 else
13224 {
13225 fprintf(f, "%*s names = \"%s\"\n", level, "", tnode->names[0]);
13226 }
13227 }
13228 fprintf(f, "%*s type_info_bits = %d\n", level, "", tnode->type_info_bits);
13229 fprintf(f, "%*s max_children = %d\n", level, "", tnode->max_children);
13230 fprintf(f, "%*s maps_name = \"%s\"\n", level, "", tnode->maps_name?tnode->maps_name:"");
13231 fprintf(f, "%*s nsegs = %d\n", level, "", tnode->nsegs);
13232 if (tnode->nsegs > 0)
13233 {
13234 int j;
13235 fprintf(f, "%*s segments = ids | lens | types\n", level, "");
13236 for (j = 0; j < tnode->nsegs*(tnode->narray?tnode->narray:1); j++)
13237 fprintf(f, "%*s %.10d|%.10d|%.10d\n", level, "",
13238 tnode->seg_ids[j], tnode->seg_lens[j], tnode->seg_types[j]);
13239
13240 }
13241 fprintf(f, "%*s num_children = %d\n", level, "", tnode->num_children);
13242 if (tnode->num_children > 0)
13243 {
13244 int j;
13245 for (j = 0; j < tnode->num_children && tnode->children[j] != 0; j++)
13246 fprintf(f, "%*s \"%s\"\n", level, "", tnode->children[j]->name);
13247 }
13248 fprintf(f, "%*s} \"%s\"\n", level, "", tnode->name);
13249 }
13250
13251 void
DBLinearizeMrgtree(DBmrgtnode * tnode,int walk_order,void * data)13252 DBLinearizeMrgtree(DBmrgtnode *tnode, int walk_order, void *data)
13253 {
13254 DBmrgtnode **ltree = (DBmrgtnode **) data;
13255 ltree[walk_order] = tnode;
13256 tnode->walk_order = walk_order;
13257 }
13258
13259 static void
DBWalkMrgtree_r(DBmrgtnode const * node,int * walk_order,DBmrgwalkcb wcb,void * wdata,int traversal_flags)13260 DBWalkMrgtree_r(DBmrgtnode const *node, int *walk_order, DBmrgwalkcb wcb, void *wdata,
13261 int traversal_flags)
13262 {
13263 if (node == 0)
13264 return;
13265
13266 /* if we're at a terminal node, issue the callback */
13267 if (node->children == 0)
13268 {
13269 wcb(node, *walk_order, wdata);
13270 (*walk_order)++;
13271 }
13272 else
13273 {
13274 int i;
13275
13276 /* issue callback first if in pre-order mode */
13277 if (traversal_flags & DB_PREORDER)
13278 {
13279 wcb(node, *walk_order, wdata);
13280 (*walk_order)++;
13281 }
13282
13283 /* recurse on all the children */
13284 for (i = 0; i < node->num_children && node->children[i] != 0; i++)
13285 DBWalkMrgtree_r(node->children[i], walk_order, wcb, wdata,
13286 traversal_flags);
13287
13288 /* issue callback last if in post-order mode */
13289 if (traversal_flags & DB_POSTORDER)
13290 {
13291 wcb(node, *walk_order, wdata);
13292 (*walk_order)++;
13293 }
13294 }
13295 }
13296
13297 void
DBWalkMrgtree(DBmrgtree const * tree,DBmrgwalkcb cb,void * wdata,int traversal_flags)13298 DBWalkMrgtree(DBmrgtree const *tree, DBmrgwalkcb cb, void *wdata, int traversal_flags)
13299 {
13300 int walk_order = 0;
13301 DBmrgtnode *start = tree->root;
13302
13303 if (cb == 0)
13304 return;
13305
13306 if (traversal_flags & DB_FROMCWR)
13307 start = tree->cwr;
13308
13309 DBWalkMrgtree_r(start, &walk_order, cb, wdata, traversal_flags);
13310 }
13311
13312 PUBLIC DBmrgtree *
DBMakeMrgtree(int source_mesh_type,int type_info_bits,int max_root_descendents,DBoptlist * opts)13313 DBMakeMrgtree(int source_mesh_type, int type_info_bits,
13314 int max_root_descendents, DBoptlist *opts)
13315 {
13316 DBmrgtree *tree = NULL;
13317 DBmrgtnode *root = NULL;
13318
13319 API_BEGIN("DBMakeMrgtree", DBmrgtree *, NULL) {
13320 if (!(source_mesh_type == DB_MULTIMESH ||
13321 source_mesh_type == DB_QUADMESH ||
13322 source_mesh_type == DB_UCDMESH ||
13323 source_mesh_type == DB_POINTMESH ||
13324 source_mesh_type == DB_CSGMESH ||
13325 source_mesh_type == DB_CURVE))
13326 API_ERROR("source_mesh_type", E_BADARGS);
13327 if (type_info_bits != 0)
13328 API_ERROR("type_info_bits", E_BADARGS);
13329 if (max_root_descendents <= 0)
13330 API_ERROR("max_root_descendents", E_BADARGS);
13331 tree = ALLOC(DBmrgtree);
13332 if (!tree) API_ERROR(NULL, E_NOMEM);
13333 memset(tree, 0, sizeof(DBmrgtree));
13334 root = ALLOC(DBmrgtnode);
13335 if (!root) {
13336 FREE(tree);
13337 API_ERROR(NULL, E_NOMEM);
13338 }
13339 memset(root, 0, sizeof(DBmrgtnode));
13340 root->children = ALLOC_N(DBmrgtnode*, max_root_descendents);
13341 if (!root->children) {
13342 FREE(root);
13343 FREE(tree);
13344 API_ERROR(NULL, E_NOMEM);
13345 }
13346
13347 /* fill in the tree header */
13348 tree->type_info_bits = type_info_bits;
13349 tree->src_mesh_type = source_mesh_type;
13350 tree->src_mesh_name = 0;
13351 tree->name = 0;
13352
13353 /* update internal node info */
13354 root->walk_order = -1;
13355 root->parent = 0;
13356
13357 /* update client data data */
13358 root->name = STRDUP("whole");
13359 root->narray = 0;
13360 root->names = 0;
13361 root->type_info_bits = 0;
13362 root->num_children = 0;
13363 root->max_children = max_root_descendents;
13364 root->maps_name = 0;
13365 root->nsegs = 0;
13366 root->seg_ids = 0;
13367 root->seg_lens = 0;
13368 root->seg_types = 0;
13369
13370 /* add the new tnode to the tree */
13371 tree->root = root;
13372 tree->cwr = root;
13373 tree->num_nodes = 1;
13374
13375 API_RETURN(tree);
13376 }
13377 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
13378 }
13379
13380 PUBLIC int
DBAddRegion(DBmrgtree * tree,const char * region_name,int type_info_bits,int max_descendents,const char * maps_name,int nsegs,int const * seg_ids,int const * seg_lens,int const * seg_types,DBoptlist const * opts)13381 DBAddRegion(DBmrgtree *tree, const char *region_name,
13382 int type_info_bits, int max_descendents,
13383 const char *maps_name, int nsegs, int const *seg_ids,
13384 int const *seg_lens, int const *seg_types, DBoptlist const *opts)
13385 {
13386 DBmrgtnode *tnode = NULL;
13387
13388 API_BEGIN("DBAddRegion", int, -1) {
13389
13390 if (!tree)
13391 API_ERROR("tree pointer", E_BADARGS);
13392 if (!region_name || !*region_name)
13393 API_ERROR("region_name", E_BADARGS);
13394 if (type_info_bits != 0)
13395 API_ERROR("type_info_bits", E_BADARGS);
13396 if (max_descendents < 0)
13397 API_ERROR("max_descendents", E_BADARGS);
13398 if (tree->cwr->num_children >= tree->cwr->max_children) {
13399 API_ERROR("exceeded max_descendents", E_BADARGS);
13400 }
13401 if (nsegs > 0)
13402 {
13403 if (seg_ids == 0)
13404 API_ERROR("seg_ids", E_BADARGS);
13405 if (seg_lens == 0)
13406 API_ERROR("seg_lens", E_BADARGS);
13407 if (seg_types == 0)
13408 API_ERROR("seg_types", E_BADARGS);
13409 }
13410 if (NULL == (tnode = ALLOC(DBmrgtnode)))
13411 API_ERROR(NULL, E_NOMEM);
13412 memset(tnode, 0, sizeof(DBmrgtnode));
13413 if (NULL == (tnode->children = ALLOC_N(DBmrgtnode*, max_descendents)) &&
13414 max_descendents) {
13415 FREE(tnode);
13416 API_ERROR(NULL, E_NOMEM);
13417 }
13418
13419 /* update internal node info */
13420 tnode->walk_order = -1;
13421 tnode->parent = tree->cwr;
13422
13423 /* update client data data */
13424 tnode->name = STRDUP(region_name);
13425 tnode->narray = 0;
13426 tnode->names = 0;
13427 tnode->type_info_bits = type_info_bits;
13428 tnode->num_children = 0;
13429 tnode->max_children = max_descendents;
13430 tnode->maps_name = STRDUP(maps_name);
13431 tnode->nsegs = nsegs;
13432 if (nsegs > 0)
13433 {
13434 int i;
13435
13436 tnode->seg_ids = ALLOC_N(int, nsegs);
13437 tnode->seg_lens = ALLOC_N(int, nsegs);
13438 tnode->seg_types = ALLOC_N(int, nsegs);
13439
13440 if (!tnode->seg_ids || !tnode->seg_lens || !tnode->seg_types)
13441 {
13442 FREE(tnode->seg_types);
13443 FREE(tnode->seg_lens);
13444 FREE(tnode->seg_ids);
13445 FREE(tnode->maps_name);
13446 FREE(tnode->name);
13447 FREE(tnode->children);
13448 FREE(tnode);
13449 API_ERROR(NULL, E_NOMEM);
13450 }
13451
13452 for (i = 0; i < nsegs; i++)
13453 {
13454 tnode->seg_ids[i] = seg_ids[i];
13455 tnode->seg_lens[i] = seg_lens[i];
13456 tnode->seg_types[i] = seg_types[i];
13457 }
13458 }
13459 else
13460 {
13461 tnode->seg_ids = 0;
13462 tnode->seg_lens = 0;
13463 tnode->seg_types = 0;
13464 }
13465
13466
13467 /* add the new tnode to the tree */
13468 tree->cwr->children[tree->cwr->num_children] = tnode;
13469 tree->cwr->num_children++;
13470 tree->num_nodes++;
13471
13472 }
13473 API_END;
13474
13475 return(tree->cwr->num_children-1);
13476 }
13477
13478 PUBLIC int
DBAddRegionArray(DBmrgtree * tree,int nregns,char const * const * regn_names,int type_info_bits,char const * maps_name,int nsegs,int const * seg_ids,int const * seg_lens,int const * seg_types,DBoptlist const * opts)13479 DBAddRegionArray(DBmrgtree *tree, int nregns,
13480 char const * const *regn_names, int type_info_bits,
13481 char const *maps_name, int nsegs, int const *seg_ids,
13482 int const *seg_lens, int const *seg_types, DBoptlist const *opts)
13483 {
13484 DBmrgtnode *tnode = NULL;
13485 int i;
13486
13487 API_BEGIN("DBAddRegionArray", int, -1) {
13488
13489 if (!tree)
13490 API_ERROR("tree pointer", E_BADARGS);
13491 if (nregns <= 0)
13492 API_ERROR("nregns", E_BADARGS);
13493 if (tree->cwr->num_children + nregns > tree->cwr->max_children) {
13494 API_ERROR("exceeded max_descendents", E_BADARGS);
13495 }
13496 if (NULL == (tnode = ALLOC(DBmrgtnode)))
13497 API_ERROR(NULL, E_NOMEM);
13498 memset(tnode, 0, sizeof(DBmrgtnode));
13499 if (nsegs > 0)
13500 {
13501 if (seg_ids == 0)
13502 API_ERROR("seg_ids", E_BADARGS);
13503 if (seg_lens == 0)
13504 API_ERROR("seg_lens", E_BADARGS);
13505 if (seg_types == 0)
13506 API_ERROR("seg_types", E_BADARGS);
13507 }
13508
13509 /* update internal node info */
13510 tnode->walk_order = -1;
13511 tnode->parent = tree->cwr;
13512
13513 /* update client data data */
13514 tnode->name = 0;
13515 tnode->narray = nregns;
13516 if (strchr(regn_names[0], '%') != 0)
13517 {
13518 if (NULL == (tnode->names = ALLOC_N(char*, 1))) {
13519 FREE(tnode);
13520 API_ERROR(NULL, E_NOMEM);
13521 }
13522 tnode->names[0] = STRDUP(regn_names[0]);
13523 }
13524 else
13525 {
13526 if (NULL == (tnode->names = ALLOC_N(char*, nregns))) {
13527 FREE(tnode);
13528 API_ERROR(NULL, E_NOMEM);
13529 }
13530 for (i = 0; i < nregns; i++)
13531 tnode->names[i] = STRDUP(regn_names[i]);
13532 }
13533 tnode->type_info_bits = type_info_bits;
13534 tnode->num_children = 0;
13535 tnode->max_children = 0;
13536 tnode->children = 0;
13537 tnode->maps_name = STRDUP(maps_name);
13538 tnode->nsegs = nsegs;
13539 if (nsegs > 0)
13540 {
13541 tnode->seg_ids = ALLOC_N(int, nsegs*nregns);
13542 tnode->seg_lens = ALLOC_N(int, nsegs*nregns);
13543 tnode->seg_types = ALLOC_N(int, nsegs*nregns);
13544
13545 if (!tnode->seg_ids || !tnode->seg_lens || !tnode->seg_types) {
13546 FREE(tnode->seg_types);
13547 FREE(tnode->seg_lens);
13548 FREE(tnode->seg_ids);
13549 if (strchr(regn_names[0], '%') != 0) {
13550 FREE(tnode->names[0]);
13551 FREE(tnode->names);
13552 } else {
13553 for (i = 0; i < nregns; i++)
13554 FREE(tnode->names[i]);
13555 FREE(tnode->names);
13556 }
13557 FREE(tnode);
13558 API_ERROR(NULL, E_NOMEM);
13559 }
13560
13561 for (i = 0; i < nsegs*nregns; i++)
13562 {
13563 tnode->seg_ids[i] = seg_ids[i];
13564 tnode->seg_lens[i] = seg_lens[i];
13565 tnode->seg_types[i] = seg_types[i];
13566 }
13567 }
13568 else
13569 {
13570 tnode->seg_ids = 0;
13571 tnode->seg_lens = 0;
13572 tnode->seg_types = 0;
13573 }
13574
13575 /* add the new tnode to the tree */
13576 tree->cwr->children[tree->cwr->num_children] = tnode;
13577 tree->cwr->num_children++;
13578 tree->num_nodes++;
13579
13580 }
13581 API_END;
13582
13583 return(tree->cwr->num_children-1);
13584 }
13585
13586 PUBLIC int
DBSetCwr(DBmrgtree * tree,char const * path)13587 DBSetCwr(DBmrgtree *tree, char const *path)
13588 {
13589 int retval = -1;
13590
13591 API_BEGIN("DBSetCwr", int, -1)
13592 {
13593 if (tree == 0)
13594 API_ERROR("tree", E_BADARGS);
13595 if (!path || !*path)
13596 API_ERROR("path", E_BADARGS);
13597 if (path[0] == '.' && path[1] == '.')
13598 {
13599 DBmrgtnode *tnode = tree->cwr;
13600 if (tnode != tree->root)
13601 {
13602 tree->cwr = tnode->parent;
13603 retval = 1;
13604 }
13605 }
13606 else
13607 {
13608 DBmrgtnode *tnode = tree->cwr;
13609 int i = 0;
13610 while (i < tnode->num_children)
13611 {
13612 if (strcmp(tnode->children[i]->name, path) == 0)
13613 {
13614 tree->cwr = tnode->children[i];
13615 break;
13616 }
13617 i++;
13618 }
13619 if (i < tnode->num_children)
13620 retval = i;
13621 }
13622 API_RETURN(retval);
13623 }
13624 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
13625 }
13626
13627 PUBLIC char const *
DBGetCwr(DBmrgtree * tree)13628 DBGetCwr(DBmrgtree *tree)
13629 {
13630 const char *retval = NULL;
13631
13632 API_BEGIN("DBGetCwr", const char *, NULL)
13633 {
13634 if (tree == 0)
13635 API_ERROR("tree", E_BADARGS);
13636
13637 retval = tree->cwr->name;
13638 API_RETURN(retval);
13639 }
13640 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
13641 }
13642
13643 PUBLIC int
DBPutMrgtree(DBfile * dbfile,char const * name,char const * mesh_name,DBmrgtree const * tree,DBoptlist const * opts)13644 DBPutMrgtree(DBfile *dbfile, char const *name, char const *mesh_name,
13645 DBmrgtree const *tree, DBoptlist const *opts)
13646 {
13647 int retval;
13648
13649 API_BEGIN2("DBPutMrgtree", int, -1, name)
13650 {
13651 if (!dbfile)
13652 API_ERROR(NULL, E_NOFILE);
13653 if (SILO_Globals.enableGrabDriver == TRUE)
13654 API_ERROR("DBPutMrgtree", E_GRABBED) ;
13655 if (!name || !*name)
13656 API_ERROR("mrgtree name", E_BADARGS);
13657 if (db_VariableNameValid(name) == 0)
13658 API_ERROR("mrgtree name", E_INVALIDNAME);
13659 if (!mesh_name || !*mesh_name)
13660 API_ERROR("mesh_name", E_BADARGS);
13661 if (db_VariableNameValid(mesh_name) == 0)
13662 API_ERROR("mesh_name", E_INVALIDNAME);
13663 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
13664 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
13665 if (NULL == dbfile->pub.p_mrgt)
13666 API_ERROR(dbfile->pub.name, E_NOTIMP);
13667
13668 retval = (dbfile->pub.p_mrgt) (dbfile, name, mesh_name,
13669 tree, opts);
13670
13671 db_FreeToc(dbfile);
13672 API_RETURN(retval);
13673 }
13674 API_END_NOPOP; /* BEWARE: If API_RETURN above is removed use API_END */
13675 }
13676
13677 PUBLIC DBmrgtree *
DBGetMrgtree(DBfile * dbfile,const char * name)13678 DBGetMrgtree(DBfile *dbfile, const char *name)
13679 {
13680 DBmrgtree *retval = NULL;
13681
13682 API_BEGIN2("DBGetMrgtree", DBmrgtree *, NULL, name) {
13683 if (!dbfile)
13684 API_ERROR(NULL, E_NOFILE);
13685 if (SILO_Globals.enableGrabDriver == TRUE)
13686 API_ERROR("DBGetMrgtree", E_GRABBED) ;
13687 if (!name || !*name)
13688 API_ERROR("mrgtree name", E_BADARGS);
13689 if (!dbfile->pub.g_mrgt)
13690 API_ERROR(dbfile->pub.name, E_NOTIMP);
13691
13692 retval = (dbfile->pub.g_mrgt) (dbfile, name);
13693 API_RETURN(retval);
13694 }
13695 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
13696 }
13697
13698 PUBLIC int
DBPutGroupelmap(DBfile * dbfile,const char * name,int num_segments,int const * groupel_types,int const * segment_lengths,int const * segment_ids,int const * const * segment_data,DBVCP2_t segment_fracs,int fracs_data_type,DBoptlist const * opts)13699 DBPutGroupelmap(DBfile *dbfile, const char *name,
13700 int num_segments, int const *groupel_types, int const *segment_lengths,
13701 int const *segment_ids, int const * const *segment_data, DBVCP2_t segment_fracs,
13702 int fracs_data_type, DBoptlist const *opts)
13703 {
13704 int retval;
13705
13706 API_BEGIN2("DBGroupelmap", int, -1, name) {
13707 if (!dbfile)
13708 API_ERROR(NULL, E_NOFILE);
13709 if (SILO_Globals.enableGrabDriver == TRUE)
13710 API_ERROR("DBPutGroupelmap", E_GRABBED) ;
13711 if (!name || !*name)
13712 API_ERROR("groupel map name", E_BADARGS);
13713 if (db_VariableNameValid(name) == 0)
13714 API_ERROR("groupel map name", E_INVALIDNAME);
13715 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
13716 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
13717 if (num_segments < 0)
13718 API_ERROR("num_segments", E_BADARGS);
13719 if (!groupel_types)
13720 API_ERROR("groupel_types", E_BADARGS);
13721 if (!segment_lengths)
13722 API_ERROR("segment_lengths", E_BADARGS);
13723 if (!segment_data)
13724 API_ERROR("segment_data", E_BADARGS);
13725 if (!dbfile->pub.p_grplm)
13726 API_ERROR(dbfile->pub.name, E_NOTIMP);
13727
13728 retval = (dbfile->pub.p_grplm) (dbfile, name,
13729 num_segments, groupel_types, segment_lengths, segment_ids,
13730 segment_data, segment_fracs, fracs_data_type, opts);
13731
13732 db_FreeToc(dbfile);
13733 API_RETURN(retval);
13734 }
13735 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
13736 }
13737
13738 PUBLIC DBgroupelmap *
DBGetGroupelmap(DBfile * dbfile,const char * name)13739 DBGetGroupelmap(DBfile *dbfile, const char *name)
13740 {
13741 DBgroupelmap *retval = NULL;
13742
13743 API_BEGIN2("DBGetGroupelmap", DBgroupelmap *, NULL, name) {
13744 if (!dbfile)
13745 API_ERROR(NULL, E_NOFILE);
13746 if (SILO_Globals.enableGrabDriver == TRUE)
13747 API_ERROR("DBGetGroupelmap", E_GRABBED) ;
13748 if (!name || !*name)
13749 API_ERROR("groupel map name", E_BADARGS);
13750 if (!dbfile->pub.g_grplm)
13751 API_ERROR(dbfile->pub.name, E_NOTIMP);
13752
13753 retval = (dbfile->pub.g_grplm) (dbfile, name);
13754 API_RETURN(retval);
13755 }
13756 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
13757 }
13758
13759 PUBLIC int
DBPutMrgvar(DBfile * dbfile,const char * name,const char * mrgt_name,int ncomps,char const * const * compnames,int nregns,char const * const * reg_pnames,int datatype,DBVCP2_t data,DBoptlist const * opts)13760 DBPutMrgvar(DBfile *dbfile, const char *name, const char *mrgt_name,
13761 int ncomps, char const * const *compnames, int nregns, char const * const *reg_pnames,
13762 int datatype, DBVCP2_t data, DBoptlist const *opts)
13763 {
13764 int retval;
13765
13766 API_BEGIN2("DBPutMrgvar", int, -1, name) {
13767 if (!dbfile)
13768 API_ERROR(NULL, E_NOFILE);
13769 if (SILO_Globals.enableGrabDriver == TRUE)
13770 API_ERROR("DBPutMrgvar", E_GRABBED) ;
13771 if (!name || !*name)
13772 API_ERROR("mrgvar name", E_BADARGS);
13773 if (db_VariableNameValid(name) == 0)
13774 API_ERROR("mrgvar name", E_INVALIDNAME);
13775 if (!mrgt_name || !*mrgt_name)
13776 API_ERROR("mrgt_name", E_BADARGS);
13777 if (db_VariableNameValid(mrgt_name) == 0)
13778 API_ERROR("mrgt_name", E_INVALIDNAME);
13779 if (!SILO_Globals.allowOverwrites && DBInqVarExists(dbfile, name))
13780 API_ERROR("overwrite not allowed", E_NOOVERWRITE);
13781 if (nregns < 0)
13782 API_ERROR("nregns", E_BADARGS);
13783 if (ncomps < 0)
13784 API_ERROR("ncomps", E_BADARGS);
13785 if (!reg_pnames)
13786 API_ERROR("reg_pnames", E_BADARGS);
13787 if (!data)
13788 API_ERROR("data", E_BADARGS);
13789 if (!dbfile->pub.p_mrgv)
13790 API_ERROR(dbfile->pub.name, E_NOTIMP);
13791
13792 retval = (dbfile->pub.p_mrgv) (dbfile, name, mrgt_name, ncomps,
13793 compnames, nregns, reg_pnames, datatype, data, opts);
13794
13795 db_FreeToc(dbfile);
13796 API_RETURN(retval);
13797 }
13798 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
13799 }
13800
13801 PUBLIC DBmrgvar *
DBGetMrgvar(DBfile * dbfile,const char * name)13802 DBGetMrgvar(DBfile *dbfile, const char *name)
13803 {
13804 DBmrgvar *retval = NULL;
13805
13806 API_BEGIN2("DBGetMrgvar", DBmrgvar *, NULL, name) {
13807 if (!dbfile)
13808 API_ERROR(NULL, E_NOFILE);
13809 if (SILO_Globals.enableGrabDriver == TRUE)
13810 API_ERROR("DBGetMrgvar", E_GRABBED) ;
13811 if (!name || !*name)
13812 API_ERROR("mrgvar name", E_BADARGS);
13813 if (!dbfile->pub.g_mrgv)
13814 API_ERROR(dbfile->pub.name, E_NOTIMP);
13815
13816 retval = (dbfile->pub.g_mrgv) (dbfile, name);
13817 API_RETURN(retval);
13818 }
13819 API_END_NOPOP; /*BEWARE: If API_RETURN above is removed use API_END */
13820 }
13821 /**********************************************************************
13822 *
13823 * Purpose: Provide a strdup command which correctly handles
13824 * a NULL string.
13825 *
13826 * Programmer: Sean Ahern
13827 * Date: April 1999
13828 *
13829 * Input arguments:
13830 * s The string to copy.
13831 *
13832 * Global variables:
13833 * None
13834 *
13835 * Local variables:
13836 * retval The new string, with memory allocated.
13837 *
13838 * Assumptions and Comments:
13839 *
13840 * Modifications:
13841 *
13842 * Lisa J. Roberts, Tue Jul 27 12:44:57 PDT 1999
13843 * Modified the function so it returns the string.
13844 *
13845 * Jeremy Meredith, Tue Aug 31 13:41:29 PDT 1999
13846 * Made it handle 0-length strings correctly.
13847 *
13848 * Thomas R. Treadway, Wed Nov 28 15:25:53 PST 2007
13849 * Moved from src/swat/sw_string.c
13850 *
13851 ***********************************************************************/
13852 char *
_db_safe_strdup(const char * s)13853 _db_safe_strdup(const char *s)
13854 {
13855 char *retval = NULL;
13856 int n;
13857
13858 if (!s)
13859 return NULL;
13860
13861 n = strlen(s);
13862 retval = (char*)malloc(sizeof(char)*(n+1));
13863 memcpy(retval, s, n);
13864 retval[n] = '\0';
13865
13866 return(retval);
13867 }
13868
13869 /*-------------------------------------------------------------------------
13870 * Function: different
13871 *
13872 * Purpose: Determines if A and B are same or different based on an
13873 * absolute tolerance and relative tolerance. A and B differ
13874 * if and only if
13875 *
13876 * | A-B | > ABSTOL
13877 *
13878 * or
13879 *
13880 * 2 | A-B |
13881 * --------- > RELTOL
13882 * | A+B |
13883 *
13884 * If ABSTOL or RELTOL is negative then the corresponding
13885 * test is not performed. If both are negative then this
13886 * function degenerates to a `!=' operator.
13887 *
13888 * Return: Success: 0 if same, 1 if different.
13889 *
13890 * Failure: never fails
13891 *
13892 * Programmer: Robb Matzke
13893 * matzke@viper.llnl.gov
13894 * Feb 6 1997
13895 *
13896 * Modifications:
13897 *
13898 * Mark C. Miller, Wed Nov 11 22:18:17 PST 2009
13899 * Added suppot for alternate relative diff option.
13900 *
13901 * Mark C. Miller, Tue Feb 7 15:18:38 PST 2012
13902 * Made reltol_eps diff mutually exclusive with abstol || reltol diff.
13903 *-------------------------------------------------------------------------
13904 */
DBIsDifferentDouble(double a,double b,double abstol,double reltol,double reltol_eps)13905 int DBIsDifferentDouble(double a, double b, double abstol, double reltol, double reltol_eps)
13906 {
13907 double num, den;
13908
13909 /*
13910 * First, see if we should use the alternate diff.
13911 * check |A-B|/(|A|+|B|+EPS) in a way that won't overflow.
13912 */
13913 if (reltol_eps >= 0 && reltol > 0)
13914 {
13915 if ((a<0 && b>0) || (b<0 && a>0)) {
13916 num = fabs (a/2 - b/2);
13917 den = fabs (a/2) + fabs(b/2) + reltol_eps/2;
13918 reltol /= 2;
13919 } else {
13920 num = fabs (a - b);
13921 den = fabs (a) + fabs(b) + reltol_eps;
13922 }
13923 if (0.0==den && num) return 1;
13924 if (num/den > reltol) return 1;
13925 return 0;
13926 }
13927 else /* use the old Abs|Rel difference test */
13928 {
13929 /*
13930 * Now the |A-B| but make sure it doesn't overflow which can only
13931 * happen if one is negative and the other is positive.
13932 */
13933 if (abstol>0) {
13934 if ((a<0 && b>0) || (b<0 && a>0)) {
13935 if (fabs (a/2 - b/2) > abstol/2) return 1;
13936 } else {
13937 if (fabs(a-b) > abstol) return 1;
13938 }
13939 }
13940
13941 /*
13942 * Now check 2|A-B|/|A+B| in a way that won't overflow.
13943 */
13944 if (reltol>0) {
13945 if ((a<0 && b>0) || (b<0 && a>0)) {
13946 num = fabs (a/2 - b/2);
13947 den = fabs (a/2 + b/2);
13948 reltol /= 2;
13949 } else {
13950 num = fabs (a - b);
13951 den = fabs (a/2 + b/2);
13952 }
13953 if (0.0==den && num) return 1;
13954 if (num/den > reltol) return 1;
13955 }
13956
13957 if (abstol>0 || reltol>0) return 0;
13958 }
13959
13960 /*
13961 * Otherwise do a normal exact comparison.
13962 */
13963 return a!=b;
13964 }
13965
13966 /*-------------------------------------------------------------------------
13967 * Function: differentll
13968 *
13969 * Purpose: Implement above difference function for long long type.
13970 *
13971 * Programmer: Mark C. Miller, Mon Dec 7 07:05:39 PST 2009
13972 *
13973 * Modifications:
13974 * Mark C. Miller, Mon Dec 7 09:50:19 PST 2009
13975 * Change conditional compilation logic to compile this routine
13976 * whenever a double is NOT sufficient to hold full precision of long
13977 * or long long.
13978 *
13979 * Mark C. Miller, Mon Jan 11 16:20:16 PST 2010
13980 * Made it compiled UNconditionally.
13981 *-------------------------------------------------------------------------
13982 */
13983 #define FABS(A) ((A)<0?-(A):(A))
DBIsDifferentLongLong(long long a,long long b,double abstol,double reltol,double reltol_eps)13984 int DBIsDifferentLongLong(long long a, long long b, double abstol, double reltol, double reltol_eps)
13985 {
13986
13987 long long num, den;
13988
13989 /*
13990 * First, see if we should use the alternate diff.
13991 * check |A-B|/(|A|+|B|+EPS) in a way that won't overflow.
13992 */
13993 if (reltol_eps >= 0 && reltol > 0)
13994 {
13995 if ((a<0 && b>0) || (b<0 && a>0)) {
13996 num = FABS (a/2 - b/2);
13997 den = FABS (a/2) + FABS(b/2) + reltol_eps/2;
13998 reltol /= 2;
13999 } else {
14000 num = FABS (a - b);
14001 den = FABS (a) + FABS(b) + reltol_eps;
14002 }
14003 if (0.0==den && num) return 1;
14004 if (num/den > reltol) return 1;
14005 return 0;
14006 }
14007 else
14008 {
14009 /*
14010 * Now the |A-B| but make sure it doesn't overflow which can only
14011 * happen if one is negative and the other is positive.
14012 */
14013 if (abstol>0) {
14014 if ((a<0 && b>0) || (b<0 && a>0)) {
14015 if (FABS(a/2 - b/2) > abstol/2) return 1;
14016 } else {
14017 if (FABS(a-b) > abstol) return 1;
14018 }
14019 }
14020
14021 /*
14022 * Now check 2|A-B|/|A+B| in a way that won't overflow.
14023 */
14024 if (reltol>0) {
14025 if ((a<0 && b>0) || (b<0 && a>0)) {
14026 num = FABS (a/2 - b/2);
14027 den = FABS (a/2 + b/2);
14028 reltol /= 2;
14029 } else {
14030 num = FABS (a - b);
14031 den = FABS (a/2 + b/2);
14032 }
14033 if (0.0==den && num) return 1;
14034 if (num/den > reltol) return 1;
14035
14036 if (abstol>0 || reltol>0) return 0;
14037 }
14038 }
14039
14040 /*
14041 * Otherwise do a normal exact comparison.
14042 */
14043 return a!=b;
14044 }
14045
14046 PUBLIC char *
DBGetDatatypeString(int dt)14047 DBGetDatatypeString(int dt)
14048 {
14049 return db_GetDatatypeString(dt);
14050 }
14051