1 /******************************************************************************
2 *
3 * NSSDC/CDF Toolbox of routines for CDF Toolkit (Miscellaneous).
4 *
5 * Version 1.6b, 3-Mar-97, Hughes STX.
6 *
7 * Modification history:
8 *
9 * V1.0 25-Jan-94, J Love Original version.
10 * V1.0a 6-Feb-94, J Love DEC Alpha/OpenVMS port.
11 * V1.1 10-Mar-94, J Love Modified `ParseOptionList' to make the
12 * enclosing parentheses optional (on any
13 * operating system).
14 * V1.2 13-Dec-94, J Love CDF V2.5.
15 * V1.2a 13-Jan-95, J Love Changed `IsCDF' to allow all possible
16 * extensions on Macintosh machines also.
17 * V1.2b 20-Jan-95, J Love IRIX 6.x (64-bit).
18 * V1.2c 3-Mar-95, J Love Moved `EncodeKeyDefinitions', etc. to
19 * `windoz.c'.
20 * V1.3 21-Mar-95, J Love POSIX.
21 * V1.3a 18-Apr-95, J Love More POSIX.
22 * V1.4 22-May-95, J Love `ASSIGNx', `EQx', etc. moved here (and some
23 * calling sequences changed).
24 * V1.5 14-Sep-95, J Love Added routines used by CDFexport. Hyper
25 * groups.
26 * V1.5a 19-Sep-95, J Love Macintosh event handling.
27 * V1.6 9-Sep-96, J Love CDF V2.6.
28 * V1.6a 21-Feb-97, J Love Removed RICE.
29 * V1.6b 3-Mar-97, J Love Windows NT for MS Visual C/C++ on an IBM PC.
30 * V1.6c 18-Dec-98, M Liu Add the missing cases for ALPHAVMSi in
31 * WhichEncoding and EncodingToken.
32 * V1.7 05-May-04, M Liu Changed function AllocateBuffers when the
33 * record count is 1 or more.
34 * V1.8 11-Jul-05, M Liu Added MingW port for PC.
35 * V1.9 13-Oct-06, M Liu Changed to allow upper and lower case CDF
36 * name to be used on win32.
37 * V2.0 21-Oct-08, M Liu Modified RemoveTrailingBlanks to end process
38 * when the first non-blank is found.
39 * V3.3 10-Jan-09, M Liu Validate a file before it is used.
40 *
41 ******************************************************************************/
42
43 #include "cdftools.h"
44
45 /******************************************************************************
46 * Macros.
47 ******************************************************************************/
48
49 #if defined(dos)
50 #define MAXnBYTESperALLOCATION 50000L /* Remember 64Kb limit. */
51 #else
52 #if defined(mac)
53 #define MAXnBYTESperALLOCATION 50000L
54 #else
55 #define MAXnBYTESperALLOCATION 500000L
56 #endif
57 #endif
58
59 /******************************************************************************
60 * Local function prototypes.
61 ******************************************************************************/
62
63 static Logical EqStringsIgLTws PROTOARGs((char *string1, char *string2));
64 static Logical DecodeInt32 PROTOARGs((char *, Int32 *));
65 static Logical DecodeInt32u PROTOARGs((char *, uInt32 *));
66 static char *strnchr PROTOARGs((char *string, int chr, int n));
67 static QOP *ParseSlashStyle PROTOARGs((
68 int argc, char *argv[], char *validQuals[], int optRequired[]
69 ));
70 static QOP *ParseHyphenStyle PROTOARGs((
71 int argc, char *argv[], char *validQuals[], int optRequired[]
72 ));
73 static void FreeArgvT PROTOARGs((int lastArgN, char *argvT[]));
74 static QOP *BuildQOP PROTOARGs((
75 int Nparms, char *parms[], char *validQuals[], int *qualEntered,
76 char *qualOpt[]
77 ));
78 static Logical AttemptAllocations PROTOARGs((
79 long nScalarValues, int nScalars, long nHyperValues, int nHypers,
80 Byte **handles[], size_t nValueBytes[]
81 ));
82
83 /******************************************************************************
84 * EncodeRecordJustify.
85 ******************************************************************************/
86
EncodeRecordJustify(string,recN,minWidth)87 void EncodeRecordJustify (string, recN, minWidth)
88 char *string;
89 long recN;
90 int minWidth; /* If zero, no minimum width. If positive, right justified.
91 If negative, left justified. */
92 {
93 sprintf (string, "%ld", recN + 1);
94 Justify (string, minWidth);
95 return;
96 }
97
98 /******************************************************************************
99 * EncodeIndicesJustify.
100 ******************************************************************************/
101
EncodeIndicesJustify(string,numDims,indices,minWidth)102 void EncodeIndicesJustify (string, numDims, indices, minWidth)
103 char *string;
104 long numDims;
105 long indices[];
106 int minWidth; /* If zero, no minimum width. If positive, right justified.
107 If negative, left justified. */
108 {
109 int n;
110 strcpyX (string, "[", 0);
111 for (n = 0; n < numDims; n++) {
112 if (n > 0) strcatX (string, ",", 0);
113 sprintf (EofS(string), "%ld", indices[n] + 1);
114 }
115 strcatX (string, "]", 0);
116 Justify (string, minWidth);
117 return;
118 }
119
120 /******************************************************************************
121 * EncodeRecordIndicesJustify.
122 ******************************************************************************/
123
EncodeRecordIndicesJustify(string,recN,numDims,indices,minWidth)124 void EncodeRecordIndicesJustify (string, recN, numDims, indices, minWidth)
125 char *string;
126 long recN;
127 long numDims;
128 long indices[];
129 int minWidth; /* If zero, no minimum width. If positive, right justified.
130 If negative, left justified. */
131 {
132 EncodeRecordJustify (string, recN, 0);
133 EncodeIndicesJustify (EofS(string), numDims, indices, 0);
134 Justify (string, minWidth);
135 return;
136 }
137
138 /******************************************************************************
139 * Justify.
140 ******************************************************************************/
141
Justify(string,minWidth)142 void Justify (string, minWidth)
143 char *string;
144 int minWidth; /* If zero, no minimum width. If positive, right justified.
145 If negative, left justified. */
146 {
147 if (minWidth < 0) {
148 int pad = -minWidth - strlen(string);
149 if (pad > 0) CatNcharacters (string, pad, (int) ' ');
150 }
151 else {
152 if (minWidth > 0) {
153 int i, stringL = strlen(string);
154 int shift = minWidth - stringL;
155 if (shift > 0) {
156 memmove (&(string[shift]), string, stringL + 1);
157 for (i = 0; i < shift; i++) string[i] = ' ';
158 }
159 }
160 }
161 return;
162 }
163
164 /******************************************************************************
165 * CatString.
166 ******************************************************************************/
167
CatToString(string,cat,length,justify,more)168 void CatToString (string, cat, length, justify, more)
169 char *string;
170 char *cat;
171 int length;
172 int justify;
173 char *more;
174 {
175 int catL = (int) strlen (cat);
176 int moreL = (int) strlen (more);
177 if (catL > length)
178 if (moreL >= length)
179 CatNcharacters (string, length, '*');
180 else {
181 strcatX (string, cat, strlen(string) + (length - moreL));
182 strcatX (string, more, 0);
183 }
184 else
185 switch (justify) {
186 case LEFT_JUSTIFY:
187 strcatX (string, cat, 0);
188 CatNcharacters (string, length - catL, ' ');
189 break;
190 case CENTER_JUSTIFY: {
191 int after = (length - catL) / 2;
192 int before = (length - catL) - after;
193 CatNcharacters (string, before, ' ');
194 strcatX (string, cat, 0);
195 CatNcharacters (string, after, ' ');
196 break;
197 }
198 case RIGHT_JUSTIFY:
199 CatNcharacters (string, length - catL, ' ');
200 strcatX (string, cat, 0);
201 break;
202 }
203 return;
204 }
205
206 /******************************************************************************
207 * RemoveLeadingBlanks.
208 ******************************************************************************/
209
RemoveLeadingBlanks(string)210 void RemoveLeadingBlanks (string)
211 char *string;
212 {
213 while (string[0] == ' ') memmove (string, &string[1], strlen(string));
214 return;
215 }
216
217 /******************************************************************************
218 * RemoveTrailingBlanks.
219 ******************************************************************************/
220
RemoveTrailingBlanks(string)221 void RemoveTrailingBlanks (string)
222 char *string;
223 {
224 int i;
225 for (i = strlen(string) - 1; i >= 0; i--) {
226 if (string[i] != ' ') return;
227 string[i] = NUL;
228 }
229 return;
230 }
231
232 /******************************************************************************
233 * RemoveWhiteSpace.
234 ******************************************************************************/
235
RemoveWhiteSpace(string)236 void RemoveWhiteSpace (string)
237 char *string;
238 {
239 char *c = string;
240 while (*c != NUL) {
241 if (Spacing(*c))
242 memmove (c, c + 1, strlen(c+1) + 1);
243 else
244 c++;
245 }
246 return;
247 }
248
249 /******************************************************************************
250 * CopyToField.
251 * Copies a string to a field and blank pads to the end of the field.
252 ******************************************************************************/
253
CopyToField(string,field,length)254 void CopyToField (string, field, length)
255 char *string;
256 char *field;
257 int length;
258 {
259 strcpyX (field, string, length);
260 BlankPadRight (field, length - strlen(string));
261 return;
262 }
263
264 /******************************************************************************
265 * CopyFromField.
266 * Copies from a field to a string and removes trailing blanks. It is
267 * assumed that the string is large enough.
268 ******************************************************************************/
269
CopyFromField(field,length,string)270 void CopyFromField (field, length, string)
271 char *field;
272 int length;
273 char *string;
274 {
275 strcpyX (string, field, length);
276 RemoveTrailingBlanks (string);
277 return;
278 }
279
280 /******************************************************************************
281 * SystemClock.
282 ******************************************************************************/
283
SystemClock()284 double SystemClock () {
285 return ((double) time(NULL));
286 }
287
288 /******************************************************************************
289 * ParsePath.
290 ******************************************************************************/
291
ParsePath(path,dir,name)292 void ParsePath (path, dir, name)
293 char *path;
294 char dir[DU_MAX_DIR_LEN+1];
295 char name[DU_MAX_NAME_LEN+1];
296 {
297 char *cp;
298 size_t len;
299 char dirT[DU_MAX_DIR_LEN+1];
300 char nameT[DU_MAX_NAME_LEN+1];
301 #if (defined(unix) && !defined(__CYGWIN__) && !defined(__MINGW32__)) || \
302 defined(posixSHELL)
303 if (IsDir(path)) {
304 strcpyX (dirT, path, DU_MAX_DIR_LEN);
305 nameT[0] = NUL;
306 }
307 else {
308 cp = strrchr (path, '/');
309 if (cp == NULL) {
310 dirT[0] = NUL;
311 strcpyX (nameT, path, DU_MAX_NAME_LEN);
312 }
313 else {
314 len = cp - path; /* No trailing '/'. */
315 strcpyX (dirT, path, MINIMUM(len,DU_MAX_DIR_LEN));
316 strcpyX (nameT, cp + 1, DU_MAX_NAME_LEN);
317 }
318 }
319 #endif
320 #if defined(dos) || defined(win32) || defined(__CYGWIN__) || \
321 defined(__MINGW32__)
322 if (IsDir(path)) {
323 strcpyX (dirT, path, DU_MAX_DIR_LEN);
324 nameT[0] = NUL;
325 }
326 else {
327 char *cp1 = strrchr (path, ':');
328 char *cp2 = strrchr (path, '\\');
329 cp = (cp1 > cp2 ? cp1 : cp2);
330 if (cp == NULL) {
331 dirT[0] = NUL;
332 strcpyX (nameT, path, DU_MAX_NAME_LEN);
333 }
334 else {
335 if (cp1 == NULL) {
336 len = (size_t) (cp2 - path); /* No trailing '\'. */
337 strcpyX (dirT, path, MINIMUM(len,DU_MAX_DIR_LEN));
338 }
339 else {
340 if (cp2 == NULL) {
341 len = (size_t) (cp1 - path + 1); /* Trailing ':'. */
342 strcpyX (dirT, path, MINIMUM(len,DU_MAX_DIR_LEN));
343 }
344 else {
345 if (cp1 + 1 == cp2)
346 len = (size_t) (cp2 - path + 1); /* Trailing ':'. */
347 else
348 len = (size_t) (cp2 - path); /* No trailing ':'. */
349 strcpyX (dirT, path, MINIMUM(len,DU_MAX_DIR_LEN));
350 }
351 }
352 strcpyX (nameT, cp + 1, DU_MAX_NAME_LEN);
353 }
354 }
355 #endif
356 #if defined(vms)
357 char *cp1 = strrchr (path, ':');
358 char *cp2 = strrchr (path, ']');
359 cp = (cp1 > cp2 ? cp1 : cp2);
360 if (cp == NULL) {
361 dirT[0] = NUL;
362 strcpyX (nameT, path, DU_MAX_NAME_LEN);
363 }
364 else {
365 len = cp - path + 1; /* Trailing ':' or ']' */
366 strcpyX (dirT, path, MINIMUM(len,DU_MAX_DIR_LEN));
367 strcpyX (nameT, cp + 1, DU_MAX_NAME_LEN);
368 }
369 #endif
370 #if defined(mac)
371 if (IsDir(path)) {
372 strcpyX (dirT, path, DU_MAX_DIR_LEN);
373 nameT[0] = NUL;
374 }
375 else {
376 cp = strrchr (path, ':');
377 if (cp == NULL) {
378 dirT[0] = NUL;
379 strcpyX (nameT, path, DU_MAX_NAME_LEN);
380 }
381 else {
382 len = cp - path + 1; /* Trailing ':'. */
383 strcpyX (dirT, path, MINIMUM(len,DU_MAX_DIR_LEN));
384 strcpyX (nameT, cp + 1, DU_MAX_NAME_LEN);
385 }
386 }
387 #endif
388 if (dir != NULL) strcpyX (dir, dirT, DU_MAX_DIR_LEN);
389 if (name != NULL) strcpyX (name, nameT, DU_MAX_NAME_LEN);
390 return;
391 }
392
393 /******************************************************************************
394 * IsDir (directory).
395 * `stat' on MS-DOS systems will indicate a directory if the pathname
396 * contains a wildcard character.
397 ******************************************************************************/
398
IsDir(path)399 Logical IsDir (path)
400 char *path;
401 {
402 char pathX[DU_MAX_PATH_LEN+1];
403 size_t len;
404 #if (!defined(unix) && !defined(posixSHELL)) || defined(__CYGWIN__) || \
405 defined(__MINGW32__)
406 int lastChar;
407 #endif
408 #if defined(unix) || defined(dos) || defined(posixSHELL) || defined(win32)
409 struct stat st;
410 #endif
411 ExpandPath (path, pathX);
412 len = strlen (pathX);
413 if (len == 0) return FALSE;
414 #if (!defined(unix) && !defined(posixSHELL)) || defined(__CYGWIN__) || \
415 defined(__MINGW32__)
416 lastChar = len - 1;
417 #endif
418 #if defined(unix) || defined(dos) || defined(posixSHELL) || defined(win32)
419 /****************************************************************************
420 * UNIX/POSIXshell, DOS, and Windows.
421 ****************************************************************************/
422 #if defined(dos) || defined(win32) || defined(__CYGWIN__) || \
423 defined(__MINGW32__)
424 /****************************************************************************
425 * DOS/Windows: Check for wildcard character in the pathname.
426 ****************************************************************************/
427 if (strchr(pathX,'*') != NULL) return FALSE;
428 if (strchr(pathX,'?') != NULL) return FALSE;
429 /****************************************************************************
430 * DOS/Windows: Strip trailing backslash (if present).
431 ****************************************************************************/
432 if (pathX[lastChar] == '\\') {
433 pathX[lastChar] = NUL; /* Strip trailing '\' */
434 len--;
435 }
436 /****************************************************************************
437 * DOS/Windows: Check for disk drive specification.
438 ****************************************************************************/
439 if (len == 2)
440 if (Alphabetic(pathX[0]) && pathX[1] == ':') return TRUE;
441 #endif
442 #if (defined(unix) && !defined(__CYGWIN__) && !defined(__MINGW32__)) || \
443 defined(posixSHELL)
444 /****************************************************************************
445 * UNIX: Check for wildcard character in the pathname.
446 ****************************************************************************/
447 if (strchr(pathX,'*') != NULL) return FALSE;
448 if (strchr(pathX,'?') != NULL) return FALSE;
449 #endif
450 /****************************************************************************
451 * Call `stat' to determine type of file.
452 ****************************************************************************/
453 if (stat(pathX, &st) == 0) {
454 #if defined(SALFORDC) /* Salford's `stat' is broken. */
455 return (st.st_size == 0);
456 #else
457 #if defined(S_ISDIR)
458 return S_ISDIR(st.st_mode);
459 #else
460 return (st.st_mode & S_IFDIR);
461 #endif
462 #endif
463 }
464 else
465 return FALSE;
466 #endif
467 #if defined(vms)
468 /****************************************************************************
469 * VMS.
470 ****************************************************************************/
471 /****************************************************************************
472 * Check for wildcard character in the pathname.
473 ****************************************************************************/
474 if (strchr(pathX,'*') != NULL) return FALSE;
475 if (strchr(pathX,'%') != NULL) return FALSE;
476 /****************************************************************************
477 * Check for possible logical name defined to be a full file specification
478 * (not just a directory).
479 ****************************************************************************/
480 if (IsReg(pathX))
481 return FALSE;
482 else
483 /**************************************************************************
484 * If not, check if the path ends with a ':' (logical name) or ']'
485 * (directory).
486 **************************************************************************/
487 if (pathX[lastChar] == ':' || pathX[lastChar] == ']')
488 return TRUE;
489 else
490 return FALSE;
491 #endif
492 #if defined(mac)
493 /****************************************************************************
494 * MAC: Check to see if specification ends with a `:' (and assume it to be a
495 * directory without actually checking). If specification doesn't end with
496 * a `:', check if it is a directory anyway.
497 ****************************************************************************/
498 if (pathX[lastChar] == ':')
499 return TRUE;
500 else {
501 return MacDirSpecified (pathX, NULL, NULL);
502 }
503 #endif
504 }
505
506 /******************************************************************************
507 * IsWild (Wildcard specification in name).
508 ******************************************************************************/
509
IsWild(path)510 Logical IsWild (path)
511 char *path;
512 {
513 char dir[DU_MAX_DIR_LEN+1];
514 char name[DU_MAX_NAME_LEN+1];
515 ParsePath (path, dir, name);
516 if (strchr(name,'*') != NULL) return TRUE;
517 #if defined(vms)
518 if (strchr(name,'%') != NULL) return TRUE;
519 #else
520 if (strchr(name,'?') != NULL) return TRUE;
521 #endif
522 return FALSE;
523 }
524
525 /******************************************************************************
526 * IsCDF.
527 * Determines if the specified pathname is that of a CDF. Because of
528 * inconsistent behavior of CD-ROM drivers on various UNIX/POSIXshell machines
529 * and the Macintosh, the following extensions are tried: `.cdf', `.CDF',
530 * `.cdf;1', and `.CDF;1'.
531 ******************************************************************************/
532
IsCDF(pathname)533 Logical IsCDF (pathname)
534 char *pathname;
535 {
536 char pathnameX[DU_MAX_PATH_LEN+1];
537 ExpandPath (pathname, pathnameX);
538 if (IsReg(pathnameX)) return TRUE;
539 strcatX (pathnameX, ".cdf", DU_MAX_PATH_LEN);
540 if (IsReg(pathnameX)) return TRUE;
541 #if defined(unix) || defined(mac) || defined(posixSHELL)
542 ExpandPath (pathname, pathnameX);
543 strcatX (pathnameX, ".cdf;1", DU_MAX_PATH_LEN);
544 if (IsReg(pathnameX)) return TRUE;
545 ExpandPath (pathname, pathnameX);
546 strcatX (pathnameX, ".CDF", DU_MAX_PATH_LEN);
547 if (IsReg(pathnameX)) return TRUE;
548 ExpandPath (pathname, pathnameX);
549 strcatX (pathnameX, ".CDF;1", DU_MAX_PATH_LEN);
550 if (IsReg(pathnameX)) return TRUE;
551 #endif
552 return FALSE;
553 }
554
555 /******************************************************************************
556 * Qop.
557 ******************************************************************************/
558
Qop(argc,argv,validQuals,optRequired)559 QOP *Qop (argc, argv, validQuals, optRequired)
560 int argc;
561 char *argv[];
562 char *validQuals[];
563 int optRequired[];
564 {
565 /****************************************************************************
566 * Check to see if a style definition has been specified. (A slash or hyphen
567 * as the first command line argument.)
568 ****************************************************************************/
569 if (argc > 1) {
570 if (!strcmp(argv[1],"/")) return ParseSlashStyle (argc - 1, &argv[1],
571 validQuals, optRequired);
572 if (!strcmp(argv[1],"-")) return ParseHyphenStyle (argc - 1, &argv[1],
573 validQuals,optRequired);
574 }
575 /****************************************************************************
576 * No style definition, parse according to default for operating system
577 * being used.
578 ****************************************************************************/
579 #if defined(vms)
580 return ParseSlashStyle (argc, argv, validQuals, optRequired);
581 #else
582 return ParseHyphenStyle (argc, argv, validQuals, optRequired);
583 #endif
584 }
585
586 /******************************************************************************
587 * ParseSlashStyle.
588 * Assume qualifiers begin with a slash (/).
589 ******************************************************************************/
590
ParseSlashStyle(argc,argv,validQuals,optRequired)591 static QOP *ParseSlashStyle (argc, argv, validQuals, optRequired)
592 int argc;
593 char *argv[];
594 char *validQuals[];
595 int optRequired[];
596 {
597 QOP *qop; /* Pointer to QOP structure. */
598 int argN, /* Argument number. */
599 qualNv, /* Qualifier number (from list of valid
600 qualifiers). */
601 qualNe, /* Qualifier number (from list of qualifiers
602 entered). */
603 Nparms = 0, /* Number of parameters entered. */
604 Nquals = 0, /* Number of qualifiers entered. */
605 matchQualNv, /* Matching qualifier number (from list of
606 valid qualifiers). */
607 qualEntered[QOP_MAX_QUALs];
608 /* TRUE if the corresponding qualifier was
609 entered. */
610 char *parms[QOP_MAX_PARMs], /* Pointers to the parameters entered. */
611 *qualOpt[QOP_MAX_QUALs], /* Pointers to the options of the qualifiers
612 entered (indexed to correspond to the list
613 of valid qualifiers). */
614 *argvT[QOP_MAX_ARGVs], /* Pointers to temporary `argv' strings. */
615 *quals[QOP_MAX_QUALs], /* Pointers to the qualifiers entered (in the
616 order they were entered). */
617 *opts[QOP_MAX_QUALs], /* Pointers to the options entered (in the
618 order they were entered). */
619 *ptr; /* Pointer into character string. */
620 enum modes { UNKNOWN_,
621 START_OF_PARM_,
622 FIND_PARM_END_,
623 START_OF_QUAL_,
624 FIND_QUAL_END_,
625 START_OF_OPT_,
626 FIND_OPT_END_ } mode; /* The current mode when scanning the
627 list of command line arguments. */
628 /****************************************************************************
629 * Determine parameters and qualifiers/options.
630 ****************************************************************************/
631 for (argN = 1; argN < argc; argN++) {
632 char nChars = strlen (argv[argN]);
633 argvT[argN] = (char *) cdf_AllocateMemory (nChars + 1, FatalError);
634 strcpyX (argvT[argN], argv[argN], nChars);
635 mode = UNKNOWN_;
636 for (ptr = argvT[argN]; *ptr != NUL;) {
637 switch (mode) {
638 case UNKNOWN_:
639 if (*ptr == '/') {
640 mode = START_OF_QUAL_;
641 ptr++;
642 }
643 else
644 mode = START_OF_PARM_;
645 break;
646 case START_OF_PARM_:
647 Nparms++;
648 if (Nparms <= QOP_MAX_PARMs)
649 parms[Nparms-1] = ptr;
650 else {
651 DisplayError ("Too many parameters.");
652 FreeArgvT (argN, argvT);
653 return NULL;
654 }
655 mode = FIND_PARM_END_;
656 ptr++;
657 break;
658 case FIND_PARM_END_:
659 if (*ptr == '/')
660 if (*(ptr+1) == '/')
661 memmove (ptr, ptr+1, strlen(ptr+1) + 1);
662 else {
663 *ptr = NUL;
664 mode = START_OF_QUAL_;
665 }
666 ptr++;
667 break;
668 case START_OF_QUAL_:
669 if (*ptr == '/')
670 mode = START_OF_PARM_;
671 else {
672 Nquals++;
673 if (Nquals <= QOP_MAX_QUALs)
674 quals[Nquals-1] = ptr;
675 else {
676 DisplayError ("Too many qualifiers.");
677 FreeArgvT (argN, argvT);
678 return NULL;
679 }
680 mode = FIND_QUAL_END_;
681 ptr++;
682 }
683 break;
684 case FIND_QUAL_END_:
685 switch (*ptr) {
686 case '/':
687 *ptr = NUL;
688 opts[Nquals-1] = NULL;
689 mode = START_OF_QUAL_;
690 break;
691 case '=':
692 *ptr = NUL;
693 mode = START_OF_OPT_;
694 break;
695 }
696 ptr++;
697 break;
698 case START_OF_OPT_:
699 if (*ptr == '/')
700 if (*(ptr+1) == '/') {
701 opts[Nquals-1] = ptr + 1;
702 ptr += 2;
703 mode = FIND_OPT_END_;
704 }
705 else {
706 char tempS[MAX_MESSAGE_TEXT_LEN+1];
707 sprintf (tempS, "Missing option for qualifier `/%s'.",
708 quals[Nquals-1]);
709 DisplayError (tempS);
710 FreeArgvT (argN, argvT);
711 return NULL;
712 }
713 else {
714 opts[Nquals-1] = ptr;
715 mode = FIND_OPT_END_;
716 ptr++;
717 }
718 break;
719 case FIND_OPT_END_:
720 if (*ptr == '/')
721 if (*(ptr+1) == '/')
722 memmove (ptr, ptr+1, strlen(ptr+1) + 1);
723 else {
724 *ptr = NUL;
725 mode = START_OF_QUAL_;
726 }
727 ptr++;
728 break;
729 }
730 }
731 switch (mode) {
732 case UNKNOWN_:
733 /* Logic error. */
734 break;
735 case START_OF_PARM_:
736 /* Logic error. */
737 break;
738 case START_OF_QUAL_:
739 DisplayError ("Missing qualifier body (/).");
740 FreeArgvT (argN, argvT);
741 return NULL;
742 case FIND_QUAL_END_:
743 /* Qualifier already NUL-terminated */
744 opts[Nquals-1] = NULL;
745 break;
746 case FIND_PARM_END_:
747 /* Parameter already NUL-terminated */
748 break;
749 case START_OF_OPT_: {
750 char tempS[MAX_MESSAGE_TEXT_LEN+1];
751 sprintf (tempS,"Missing option for qualifier `/%s'.",quals[Nquals-1]);
752 DisplayError (tempS);
753 FreeArgvT (argN, argvT);
754 return NULL;
755 }
756 case FIND_OPT_END_:
757 /* Option already NUL-terminated */
758 break;
759 }
760 }
761 /****************************************************************************
762 * Set up to scan command line arguments (while checking number of valid
763 * qualifiers).
764 ****************************************************************************/
765 for (qualNv = 0; validQuals[qualNv] != NULL; qualNv++) {
766 if (qualNv < QOP_MAX_QUALs) {
767 qualEntered[qualNv] = FALSE;
768 qualOpt[qualNv] = NULL;
769 }
770 else {
771 WriteOut (stdout, "Too many valid qualifiers.\n");
772 FreeArgvT (argc - 1, argvT);
773 return NULL;
774 }
775 }
776 /****************************************************************************
777 * Determine which qualifiers/options were entered.
778 ****************************************************************************/
779 for (qualNe = 0; qualNe < Nquals; qualNe++) {
780 matchQualNv = FindUniqueMatch (quals[qualNe], validQuals);
781 switch (matchQualNv) {
782 case NOMATCH: {
783 char tempS[MAX_MESSAGE_TEXT_LEN+1];
784 sprintf (tempS, "Unknown qualifier (/%s).", quals[qualNe]);
785 DisplayError (tempS);
786 FreeArgvT (argc - 1, argvT);
787 return NULL;
788 }
789 case MATCHES: {
790 char tempS[MAX_MESSAGE_TEXT_LEN+1];
791 sprintf (tempS, "Ambiguous qualifier (/%s).", quals[qualNe]);
792 DisplayError (tempS);
793 FreeArgvT (argc - 1, argvT);
794 return NULL;
795 }
796 default: {
797 if (optRequired[matchQualNv] && opts[qualNe] == NULL) {
798 char tempS[MAX_MESSAGE_TEXT_LEN+1];
799 sprintf (tempS, "Option missing for qualifier `/%s'.",
800 validQuals[matchQualNv]);
801 DisplayError (tempS);
802 FreeArgvT (argc - 1, argvT);
803 return NULL;
804 }
805 if (!optRequired[matchQualNv] && opts[qualNe] != NULL) {
806 char tempS[MAX_MESSAGE_TEXT_LEN+1];
807 sprintf (tempS, "Extraneous option for qualifier `/%s'.",
808 validQuals[matchQualNv]);
809 DisplayError (tempS);
810 FreeArgvT (argc - 1, argvT);
811 return NULL;
812 }
813 if (qualEntered[matchQualNv]) {
814 char tempS[MAX_MESSAGE_TEXT_LEN+1];
815 sprintf (tempS, "Redundant qualifier (/%s).",
816 validQuals[matchQualNv]);
817 DisplayError (tempS);
818 FreeArgvT (argc - 1, argvT);
819 return NULL;
820 }
821 qualEntered[matchQualNv] = TRUE;
822 qualOpt[matchQualNv] = opts[qualNe];
823 break;
824 }
825 }
826 }
827 /****************************************************************************
828 * Build QOP structure.
829 ****************************************************************************/
830 qop = BuildQOP (Nparms, parms, validQuals, qualEntered, qualOpt);
831 /****************************************************************************
832 * Free memory used and return QOP structure.
833 ****************************************************************************/
834 FreeArgvT (argc - 1, argvT);
835 return qop;
836 }
837
838 /******************************************************************************
839 * ParseHyphenStyle.
840 * Assume qualifiers begin with a hyphen (-).
841 ******************************************************************************/
842
ParseHyphenStyle(argc,argv,validQuals,optRequired)843 static QOP *ParseHyphenStyle (argc, argv, validQuals, optRequired)
844 int argc;
845 char *argv[];
846 char *validQuals[];
847 int optRequired[];
848 {
849 QOP *qop; /* Pointer to a QOP structure. */
850 int argN, /* Command line argument number. */
851 qualNv, /* Qualifier number from `valids' list. */
852 Nparms = 0, /* Number of parameters entered. */
853 matchQualNv, /* Matching qualifier number (from list of
854 valid qualifiers). */
855 qualEntered[QOP_MAX_QUALs];
856 /* TRUE if the corresponding qualifier was
857 entered. */
858 char *parms[QOP_MAX_PARMs], /* Pointers to the parameters entered. */
859 *qualOpt[QOP_MAX_QUALs]; /* Pointers to the options of the qualifiers
860 entered (indexed to correspond to the list
861 of valid qualifiers). */
862 /****************************************************************************
863 * Set up to scan command line arguments (while checking number of valid
864 * qualifiers).
865 ****************************************************************************/
866 for (qualNv = 0; validQuals[qualNv] != NULL; qualNv++) {
867 if (qualNv < QOP_MAX_QUALs) {
868 qualEntered[qualNv] = FALSE;
869 qualOpt[qualNv] = NULL;
870 }
871 else {
872 DisplayError ("Too many valid qualifiers.");
873 return NULL;
874 }
875 }
876 /****************************************************************************
877 * Determine which qualifiers were entered (the rest being parameters).
878 ****************************************************************************/
879 for (argN = 1; argN < argc; argN++) {
880 if (argv[argN][0] == '-' && argv[argN][1] != '-') {
881 matchQualNv = FindUniqueMatch (&argv[argN][1], validQuals);
882 switch (matchQualNv) {
883 case NOMATCH: {
884 char tempS[MAX_MESSAGE_TEXT_LEN+1];
885 sprintf (tempS, "Unknown qualifier (-%s).", &argv[argN][1]);
886 DisplayError (tempS);
887 return NULL;
888 }
889 case MATCHES: {
890 char tempS[MAX_MESSAGE_TEXT_LEN+1];
891 sprintf (tempS, "Ambiguous qualifier (-%s).", &argv[argN][1]);
892 DisplayError (tempS);
893 return NULL;
894 }
895 default: {
896 if (qualEntered[matchQualNv]) {
897 char tempS[MAX_MESSAGE_TEXT_LEN+1];
898 sprintf (tempS, "Redundant qualifier (-%s).",
899 validQuals[matchQualNv]);
900 DisplayError (tempS);
901 return NULL;
902 }
903 else
904 qualEntered[matchQualNv] = TRUE;
905 if (optRequired[matchQualNv]) {
906 if (argN+1 < argc) {
907 qualOpt[matchQualNv] = argv[argN+1];
908 argN++;
909 }
910 else {
911 char tempS[MAX_MESSAGE_TEXT_LEN+1];
912 sprintf (tempS, "Option missing for qualifier `-%s'.",
913 validQuals[matchQualNv]);
914 DisplayError (tempS);
915 return NULL;
916 }
917 }
918 }
919 }
920 }
921 else {
922 Nparms++;
923 if (Nparms <= QOP_MAX_PARMs)
924 parms[Nparms-1] = BOO(strncmp(argv[argN],"--",2),
925 argv[argN],argv[argN] + 1);
926 else {
927 DisplayError ("Too many parameters.");
928 return NULL;
929 }
930 }
931 }
932 /****************************************************************************
933 * Build QOP structure.
934 ****************************************************************************/
935 qop = BuildQOP (Nparms, parms, validQuals, qualEntered, qualOpt);
936 /****************************************************************************
937 * Return QOP structure.
938 ****************************************************************************/
939 return qop;
940 }
941
942 /******************************************************************************
943 * BuildQOP.
944 ******************************************************************************/
945
BuildQOP(Nparms,parms,validQuals,qualEntered,qualOpt)946 static QOP *BuildQOP (Nparms, parms, validQuals, qualEntered, qualOpt)
947 int Nparms;
948 char *parms[];
949 char *validQuals[];
950 int *qualEntered;
951 char *qualOpt[];
952 {
953 QOP *qop; /* Pointer to a QOP structure. */
954 int parmN, /* Parameter number. */
955 qualNv, /* Qualifier number (in list of valid qualifiers. */
956 strCount = 0; /* Number of characters in the strings to be contained
957 in the QOP structure. */
958 char *strOffset; /* Offset into the QOP structure of a string
959 (parameter/option). */
960 for (parmN = 0; parmN < Nparms; parmN++)
961 strCount += strlen(parms[parmN]) + 1;
962 for (qualNv = 0; validQuals[qualNv] != NULL; qualNv++)
963 if (qualEntered[qualNv])
964 if (qualOpt[qualNv] != NULL) strCount += strlen(qualOpt[qualNv]) + 1;
965 qop = (QOP *) cdf_AllocateMemory (sizeof(QOP) + strCount,
966 FatalError);
967 strOffset = (char *) qop + sizeof(QOP);
968 qop->Nparms = Nparms;
969 for (parmN = 0; parmN < Nparms; parmN++) {
970 qop->parms[parmN] = strOffset;
971 strOffset += strlen(parms[parmN]) + 1;
972 strcpyX (qop->parms[parmN], parms[parmN], 0);
973 }
974 for (qualNv = 0; validQuals[qualNv] != NULL; qualNv++) {
975 qop->qualEntered[qualNv] = qualEntered[qualNv];
976 if (qualEntered[qualNv]) {
977 if (qualOpt[qualNv] != NULL) {
978 qop->qualOpt[qualNv] = strOffset;
979 strOffset += strlen(qualOpt[qualNv]) + 1;
980 strcpyX (qop->qualOpt[qualNv], qualOpt[qualNv], 0);
981 }
982 else
983 qop->qualOpt[qualNv] = NULL;
984 }
985 }
986 return qop;
987 }
988
989 /******************************************************************************
990 * FreeArgvT.
991 ******************************************************************************/
992
FreeArgvT(lastArgN,argvT)993 static void FreeArgvT (lastArgN, argvT)
994 int lastArgN;
995 char *argvT[];
996 {
997 int argN;
998 for (argN = 1; argN <= lastArgN; argN++) cdf_FreeMemory (argvT[argN],
999 FatalError);
1000 return;
1001 }
1002
1003 /******************************************************************************
1004 * ASSIGNx.
1005 ******************************************************************************/
1006
ASSIGNx(dst,src,dataType,numElems)1007 void ASSIGNx (dst, src, dataType, numElems)
1008 void *dst;
1009 void *src;
1010 long dataType;
1011 long numElems;
1012 {
1013 memmove (dst, src, (size_t) (CDFelemSize(dataType) * numElems));
1014 return;
1015 }
1016
1017 /******************************************************************************
1018 * EQx.
1019 ******************************************************************************/
1020
EQx(a,b,dataType,numElems)1021 Logical EQx (a, b, dataType, numElems)
1022 void *a;
1023 void *b;
1024 long dataType;
1025 long numElems;
1026 {
1027 if (dataType != CDF_EPOCH16)
1028 return BOO(memcmp(a,b,(size_t)(CDFelemSize(dataType)*numElems)),FALSE,TRUE);
1029 else {
1030 double epoch16_a[2], epoch16_b[2];
1031 epoch16_a[0] = *((double *) a);
1032 epoch16_a[1] = *(((double *) a)+1);
1033 epoch16_b[0] = *((double *) b);
1034 epoch16_b[1] = *(((double *) b)+1);
1035 if (epoch16_a[0] == epoch16_b[0] && epoch16_a[1] == epoch16_b[1])
1036 return TRUE;
1037 return FALSE;
1038 }
1039 }
1040
1041 /******************************************************************************
1042 * NEx.
1043 ******************************************************************************/
1044
NEx(a,b,dataType,numElems)1045 Logical NEx (a, b, dataType, numElems)
1046 void *a;
1047 void *b;
1048 long dataType;
1049 long numElems;
1050 {
1051 if (dataType != CDF_EPOCH16)
1052 return BOO(memcmp(a,b,(size_t)(CDFelemSize(dataType)*numElems)),TRUE,FALSE);
1053 else {
1054 double epoch16_a[2], epoch16_b[2];
1055 epoch16_a[0] = *((double *) a);
1056 epoch16_a[1] = *(((double *) a)+1);
1057 epoch16_b[0] = *((double *) b);
1058 epoch16_b[1] = *(((double *) b)+1);
1059 if (epoch16_a[0] == epoch16_b[0] && epoch16_a[1] == epoch16_b[1])
1060 return FALSE;
1061 return TRUE;
1062 }
1063 }
1064
1065 /******************************************************************************
1066 * LEx.
1067 ******************************************************************************/
1068
LEx(a,b,dataType,numElems)1069 Logical LEx (a, b, dataType, numElems)
1070 void *a;
1071 void *b;
1072 long dataType;
1073 long numElems;
1074 {
1075 switch (dataType) {
1076 case CDF_BYTE:
1077 case CDF_INT1:
1078 return (*((sChar *) a) <= *((sChar *) b));
1079 case CDF_UINT1:
1080 return (*((uChar *) a) <= *((uChar *) b));
1081 case CDF_INT2:
1082 return (*((Int16 *) a) <= *((Int16 *) b));
1083 case CDF_UINT2:
1084 return (*((uInt16 *) a) <= *((uInt16 *) b));
1085 case CDF_INT4:
1086 return (*((Int32 *) a) <= *((Int32 *) b));
1087 case CDF_UINT4:
1088 return (*((uInt32 *) a) <= *((uInt32 *) b));
1089 case CDF_REAL4:
1090 case CDF_FLOAT:
1091 return (*((float *) a) <= *((float *) b));
1092 case CDF_REAL8:
1093 case CDF_DOUBLE:
1094 case CDF_EPOCH:
1095 return (*((double *) a) <= *((double *) b));
1096 case CDF_EPOCH16: {
1097 double epoch16_a[2], epoch16_b[2];
1098 epoch16_a[0] = *((double *) a);
1099 epoch16_a[1] = *(((double *) a)+1);
1100 epoch16_b[0] = *((double *) b);
1101 epoch16_b[1] = *(((double *) b)+1);
1102 if (epoch16_a[0] > epoch16_b[0]) return FALSE;
1103 if (epoch16_a[0] == epoch16_b[0] && epoch16_a[1] > epoch16_b[1])
1104 return FALSE;
1105 return TRUE;
1106 }
1107 case CDF_CHAR:
1108 case CDF_UCHAR:
1109 return BOO(memcmp(a,b,(size_t)numElems) <= 0,TRUE,FALSE);
1110 }
1111 return FALSE;
1112 }
1113
1114 /******************************************************************************
1115 * LTx.
1116 ******************************************************************************/
1117
LTx(a,b,dataType,numElems)1118 Logical LTx (a, b, dataType, numElems)
1119 void *a;
1120 void *b;
1121 long dataType;
1122 long numElems;
1123 {
1124 switch (dataType) {
1125 case CDF_BYTE:
1126 case CDF_INT1:
1127 return (*((sChar *) a) < *((sChar *) b));
1128 case CDF_UINT1:
1129 return (*((uChar *) a) < *((uChar *) b));
1130 case CDF_INT2:
1131 return (*((Int16 *) a) < *((Int16 *) b));
1132 case CDF_UINT2:
1133 return (*((uInt16 *) a) < *((uInt16 *) b));
1134 case CDF_INT4:
1135 return (*((Int32 *) a) < *((Int32 *) b));
1136 case CDF_UINT4:
1137 return (*((uInt32 *) a) < *((uInt32 *) b));
1138 case CDF_REAL4:
1139 case CDF_FLOAT:
1140 return (*((float *) a) < *((float *) b));
1141 case CDF_REAL8:
1142 case CDF_DOUBLE:
1143 case CDF_EPOCH:
1144 return (*((double *) a) < *((double *) b));
1145 case CDF_EPOCH16: {
1146 double epoch16_a[2], epoch16_b[2];
1147 epoch16_a[0] = *((double *) a);
1148 epoch16_a[1] = *(((double *) a)+1);
1149 epoch16_b[0] = *((double *) b);
1150 epoch16_b[1] = *(((double *) b)+1);
1151 if (epoch16_a[0] > epoch16_b[0]) return FALSE;
1152 if (epoch16_a[0] == epoch16_b[0] && epoch16_a[1] >= epoch16_b[1])
1153 return FALSE;
1154 return TRUE;
1155 }
1156 case CDF_CHAR:
1157 case CDF_UCHAR:
1158 return BOO(memcmp(a,b,(size_t)numElems) < 0,TRUE,FALSE);
1159 }
1160 return FALSE;
1161 }
1162
1163 /******************************************************************************
1164 * GEx.
1165 ******************************************************************************/
1166
GEx(a,b,dataType,numElems)1167 Logical GEx (a, b, dataType, numElems)
1168 void *a;
1169 void *b;
1170 long dataType;
1171 long numElems;
1172 {
1173 switch (dataType) {
1174 case CDF_BYTE:
1175 case CDF_INT1:
1176 return (*((sChar *) a) >= *((sChar *) b));
1177 case CDF_UINT1:
1178 return (*((uChar *) a) >= *((uChar *) b));
1179 case CDF_INT2:
1180 return (*((Int16 *) a) >= *((Int16 *) b));
1181 case CDF_UINT2:
1182 return (*((uInt16 *) a) >= *((uInt16 *) b));
1183 case CDF_INT4:
1184 return (*((Int32 *) a) >= *((Int32 *) b));
1185 case CDF_UINT4:
1186 return (*((uInt32 *) a) >= *((uInt32 *) b));
1187 case CDF_REAL4:
1188 case CDF_FLOAT:
1189 return (*((float *) a) >= *((float *) b));
1190 case CDF_REAL8:
1191 case CDF_DOUBLE:
1192 case CDF_EPOCH:
1193 return (*((double *) a) >= *((double *) b));
1194 case CDF_EPOCH16: {
1195 double epoch16_a[2], epoch16_b[2];
1196 epoch16_a[0] = *((double *) a);
1197 epoch16_a[1] = *(((double *) a)+1);
1198 epoch16_b[0] = *((double *) b);
1199 epoch16_b[1] = *(((double *) b)+1);
1200 if (epoch16_a[0] < epoch16_b[0]) return FALSE;
1201 if (epoch16_a[0] == epoch16_b[0] && epoch16_a[1] < epoch16_b[1])
1202 return FALSE;
1203 return TRUE;
1204 }
1205 case CDF_CHAR:
1206 case CDF_UCHAR:
1207 return BOO(memcmp(a,b,(size_t)numElems) >= 0,TRUE,FALSE);
1208 }
1209 return FALSE;
1210 }
1211
1212 /******************************************************************************
1213 * GTx.
1214 ******************************************************************************/
1215
GTx(a,b,dataType,numElems)1216 Logical GTx (a, b, dataType, numElems)
1217 void *a;
1218 void *b;
1219 long dataType;
1220 long numElems;
1221 {
1222 switch (dataType) {
1223 case CDF_BYTE:
1224 case CDF_INT1:
1225 return (*((sChar *) a) > *((sChar *) b));
1226 case CDF_UINT1:
1227 return (*((uChar *) a) > *((uChar *) b));
1228 case CDF_INT2:
1229 return (*((Int16 *) a) > *((Int16 *) b));
1230 case CDF_UINT2:
1231 return (*((uInt16 *) a) > *((uInt16 *) b));
1232 case CDF_INT4:
1233 return (*((Int32 *) a) > *((Int32 *) b));
1234 case CDF_UINT4:
1235 return (*((uInt32 *) a) > *((uInt32 *) b));
1236 case CDF_REAL4:
1237 case CDF_FLOAT:
1238 return (*((float *) a) > *((float *) b));
1239 case CDF_REAL8:
1240 case CDF_DOUBLE:
1241 case CDF_EPOCH:
1242 return (*((double *) a) > *((double *) b));
1243 case CDF_EPOCH16: {
1244 double epoch16_a[2], epoch16_b[2];
1245 epoch16_a[0] = *((double *) a);
1246 epoch16_a[1] = *(((double *) a)+1);
1247 epoch16_b[0] = *((double *) b);
1248 epoch16_b[1] = *(((double *) b)+1);
1249 if (epoch16_a[0] < epoch16_b[0]) return FALSE;
1250 if (epoch16_a[0] == epoch16_b[0] && epoch16_a[1] <= epoch16_b[1])
1251 return FALSE;
1252 return TRUE;
1253 }
1254 case CDF_CHAR:
1255 case CDF_UCHAR:
1256 return BOO(memcmp(a,b,(size_t)numElems) > 0,TRUE,FALSE);
1257 }
1258 return FALSE;
1259 }
1260
1261 /******************************************************************************
1262 * IncrRecordIndicesFirstLast.
1263 * Rolls over to `first' indices if at `last' indices (and increments record).
1264 ******************************************************************************/
1265
IncrRecordIndicesFirstLast(rowMajor,recordN,numDims,first,last,indices)1266 void IncrRecordIndicesFirstLast (rowMajor, recordN, numDims, first, last,
1267 indices)
1268 Logical rowMajor;
1269 long *recordN;
1270 long numDims;
1271 long first[];
1272 long last[];
1273 long indices[];
1274 {
1275 if (numDims > 0) {
1276 int firstDim = BOO(rowMajor,(int)(numDims - 1),0);
1277 int lastDim = BOO(rowMajor,0,(int)(numDims - 1));
1278 int dimIncr = BOO(rowMajor,-1,1);
1279 int doneDim = lastDim + dimIncr, dimN;
1280 for (dimN = firstDim; dimN != doneDim; dimN += dimIncr) {
1281 if (indices[dimN] == last[dimN]) {
1282 indices[dimN] = first[dimN];
1283 if (dimN == lastDim) (*recordN)++;
1284 }
1285 else {
1286 indices[dimN]++;
1287 break;
1288 }
1289 }
1290 }
1291 else
1292 (*recordN)++;
1293 return;
1294 }
1295
1296 /******************************************************************************
1297 * IncrIndicesFirstLastRow.
1298 * Rolls over to `first' indices if at `last' indices.
1299 ******************************************************************************/
1300
IncrIndicesFirstLastRow(numDims,first,last,indices)1301 void IncrIndicesFirstLastRow (numDims, first, last, indices)
1302 long numDims;
1303 long first[];
1304 long last[];
1305 long indices[];
1306 {
1307 int dimN;
1308 for (dimN = (int) (numDims - 1); dimN >= 0; dimN--) {
1309 if (indices[dimN] == last[dimN])
1310 indices[dimN] = first[dimN];
1311 else {
1312 indices[dimN]++;
1313 break;
1314 }
1315 }
1316 return;
1317 }
1318
1319 /******************************************************************************
1320 * IncrIndicesFirstLastCol.
1321 * Rolls over to `first' indices if at `last' indices.
1322 ******************************************************************************/
1323
IncrIndicesFirstLastCol(numDims,first,last,indices)1324 void IncrIndicesFirstLastCol (numDims, first, last, indices)
1325 long numDims;
1326 long first[];
1327 long last[];
1328 long indices[];
1329 {
1330 int dimN;
1331 for (dimN = 0; dimN < numDims; dimN++) {
1332 if (indices[dimN] == last[dimN])
1333 indices[dimN] = first[dimN];
1334 else {
1335 indices[dimN]++;
1336 break;
1337 }
1338 }
1339 return;
1340 }
1341
1342 /******************************************************************************
1343 * AllocateBuffers.
1344 ******************************************************************************/
1345
AllocateBuffers(nRecords,numDims,dimSizes,groups,nScalarBuffers,nHyperBuffers,handles,nValueBytes,rowMajor,minNofHypers,fatalFnc)1346 Logical AllocateBuffers (nRecords, numDims, dimSizes, groups, nScalarBuffers,
1347 nHyperBuffers, handles, nValueBytes, rowMajor,
1348 minNofHypers, fatalFnc)
1349 long nRecords;
1350 long numDims;
1351 long dimSizes[];
1352 struct GroupStruct *groups;
1353 int nScalarBuffers;
1354 int nHyperBuffers;
1355 Byte **handles[];
1356 size_t nValueBytes[];
1357 Logical rowMajor;
1358 int minNofHypers;
1359 void (*fatalFnc) PROTOARGs((char *msg));
1360 {
1361 int lsDimN; /* Least significant dimension number. */
1362 int msDimN; /* Most significant dimension number. */
1363 int dimStep; /* How to increment dimension number from most
1364 significant to least significant. */
1365 int dimN, dN;
1366 long nValuesPerRec, nValuesPerDim[CDF_MAX_DIMS], count, nHypersSoFar;
1367 /****************************************************************************
1368 * Setup for majority.
1369 ****************************************************************************/
1370 lsDimN = BOO(rowMajor,(int)(numDims-1),0);
1371 msDimN = BOO(rowMajor,0,(int)(numDims-1));
1372 dimStep = BOO(rowMajor,1,-1);
1373 /****************************************************************************
1374 * Calculate number of values per record/dimension.
1375 ****************************************************************************/
1376 if (numDims > 0) {
1377 nValuesPerDim[lsDimN] = 1;
1378 for (dimN = lsDimN - dimStep; dimN != msDimN - dimStep; dimN -= dimStep) {
1379 nValuesPerDim[dimN] = dimSizes[dimN+dimStep] *
1380 nValuesPerDim[dimN+dimStep];
1381 }
1382 nValuesPerRec = dimSizes[msDimN] * nValuesPerDim[msDimN];
1383 }
1384 else
1385 nValuesPerRec = 1;
1386 /****************************************************************************
1387 * Check if full records can be allocated.
1388 ****************************************************************************/
1389 count = nRecords;
1390 while (count >= 1 ) {
1391 long nRecGroups = nRecords/count + BOO(nRecords % count == 0,0,1);
1392 if (nRecGroups >= minNofHypers || count == 1) {
1393 if (AttemptAllocations(count,nScalarBuffers,count*nValuesPerRec,
1394 nHyperBuffers,handles,nValueBytes)) {
1395 groups->nRecGroups = nRecGroups;
1396 groups->firstRecCount = count;
1397 groups->lastRecCount = BOO(nRecords % count == 0,
1398 count,nRecords % count);
1399 groups->recGroupN = 1;
1400 for (dimN = msDimN; dimN != lsDimN + dimStep; dimN += dimStep) {
1401 groups->nDimGroups[dimN] = 1;
1402 groups->firstDimCount[dimN] = dimSizes[dimN];
1403 groups->lastDimCount[dimN] = dimSizes[dimN];
1404 groups->dimGroupN[dimN] = 1;
1405 }
1406 return TRUE;
1407 }
1408 }
1409 if (count == 1) break;
1410 count = (count + BOO(count % 2 == 0,0,1)) / 2;
1411 }
1412 groups->nRecGroups = nRecords;
1413 groups->firstRecCount = 1;
1414 groups->lastRecCount = 1;
1415 groups->recGroupN = 1;
1416 nHypersSoFar = nRecords;
1417 /****************************************************************************
1418 * Check how much of each dimension can be allocated.
1419 ****************************************************************************/
1420 for (dimN = msDimN; dimN != lsDimN + dimStep; dimN += dimStep) {
1421 count = dimSizes[dimN];
1422 while (count > 1) {
1423 long nDimGroups = (dimSizes[dimN] / count) +
1424 BOO(dimSizes[dimN] % count == 0,0,1);
1425 if (nHypersSoFar * nDimGroups >= minNofHypers) {
1426 if (AttemptAllocations(1L,nScalarBuffers,count*nValuesPerDim[dimN],
1427 nHyperBuffers,handles,nValueBytes)) {
1428 groups->nDimGroups[dimN] = nDimGroups;
1429 groups->firstDimCount[dimN] = count;
1430 groups->lastDimCount[dimN] = BOO(dimSizes[dimN] % count == 0,
1431 count,dimSizes[dimN] % count);
1432 groups->dimGroupN[dimN] = 1;
1433 for (dN = dimN + dimStep; dN != lsDimN + dimStep; dN += dimStep) {
1434 groups->nDimGroups[dN] = 1;
1435 groups->firstDimCount[dN] = dimSizes[dN];
1436 groups->lastDimCount[dN] = dimSizes[dN];
1437 groups->dimGroupN[dN] = 1;
1438 }
1439 return TRUE;
1440 }
1441 }
1442 count = (count + 1) / 2;
1443 }
1444 groups->nDimGroups[dimN] = dimSizes[dimN];
1445 groups->firstDimCount[dimN] = 1;
1446 groups->lastDimCount[dimN] = 1;
1447 groups->dimGroupN[dimN] = 1;
1448 nHypersSoFar *= dimSizes[dimN];
1449 }
1450 if (AttemptAllocations(1L,nScalarBuffers,1L,nHyperBuffers,
1451 handles,nValueBytes)) return TRUE;
1452 /****************************************************************************
1453 * Not all of the buffers can be allocated even at only one value per buffer.
1454 ****************************************************************************/
1455 if (fatalFnc != NULL) (*fatalFnc)("Unable to allocate memory buffers.");
1456 return FALSE;
1457 }
1458
1459 /******************************************************************************
1460 * AttemptAllocations.
1461 ******************************************************************************/
1462
AttemptAllocations(nScalarValues,nScalarBuffers,nHyperValues,nHyperBuffers,handles,nValueBytes)1463 static Logical AttemptAllocations (nScalarValues, nScalarBuffers, nHyperValues,
1464 nHyperBuffers, handles, nValueBytes)
1465 long nScalarValues;
1466 int nScalarBuffers;
1467 long nHyperValues;
1468 int nHyperBuffers;
1469 Byte **handles[];
1470 size_t nValueBytes[];
1471 {
1472 int bN, bNt; uLong maxBytes = 1, nBytes;
1473 #if defined(mac) || defined(dos)
1474 void *ptr;
1475 #endif
1476 /****************************************************************************
1477 * First allocate scalar buffers.
1478 ****************************************************************************/
1479 for (bN = 0; bN < nScalarBuffers; bN++) {
1480 nBytes = nScalarValues * nValueBytes[bN];
1481 if (nBytes > MAXnBYTESperALLOCATION)
1482 *handles[bN] = NULL;
1483 else
1484 *handles[bN] = cdf_AllocateMemory ((size_t) nBytes, NULL);
1485 if (*handles[bN] == NULL) {
1486 for (bNt = bN - 1; bNt >= 0; bNt--) cdf_FreeMemory (*handles[bNt],
1487 NULL);
1488 return FALSE;
1489 }
1490 maxBytes = MAXIMUM(maxBytes,nBytes);
1491 }
1492 /****************************************************************************
1493 * Then allocate hyper buffers.
1494 ****************************************************************************/
1495 for (bN = nScalarBuffers; bN < nScalarBuffers + nHyperBuffers; bN++) {
1496 nBytes = nHyperValues * nValueBytes[bN];
1497 if (nBytes > MAXnBYTESperALLOCATION)
1498 *handles[bN] = NULL;
1499 else
1500 *handles[bN] = cdf_AllocateMemory ((size_t) nBytes, NULL);
1501 if (*handles[bN] == NULL) {
1502 for (bNt = bN - 1; bNt >= 0; bNt--) cdf_FreeMemory (*handles[bNt],
1503 NULL);
1504 return FALSE;
1505 }
1506 maxBytes = MAXIMUM(maxBytes,nBytes);
1507 }
1508 /****************************************************************************
1509 * Allocate and then free a buffer twice the size of the largest buffer
1510 * allocated. This will save some space on the heap for other uses.
1511 ****************************************************************************/
1512 #if defined(mac) || defined(dos)
1513 ptr = cdf_AllocateMemory ((size_t) (2 * maxBytes), NULL);
1514 if (ptr == NULL) {
1515 for (bNt = nScalarBuffers + nHyperBuffers - 1; bNt >= 0; bNt--) {
1516 cdf_FreeMemory (*handles[bNt], NULL);
1517 }
1518 return FALSE;
1519 }
1520 cdf_FreeMemory (ptr, NULL);
1521 #endif
1522 /****************************************************************************
1523 * All allocations succeeded, return TRUE.
1524 ****************************************************************************/
1525 return TRUE;
1526 }
1527
1528 /******************************************************************************
1529 * HyperFullRecord.
1530 ******************************************************************************/
1531
HyperFullRecord(groups,numDims)1532 Logical HyperFullRecord (groups, numDims)
1533 struct GroupStruct *groups;
1534 long numDims;
1535 {
1536 int dimN;
1537 for (dimN = 0; dimN < numDims; dimN++) {
1538 if (groups->nDimGroups[dimN] > 1) return FALSE;
1539 }
1540 return TRUE;
1541 }
1542
1543 /******************************************************************************
1544 * HypersPerRecord.
1545 ******************************************************************************/
1546
HypersPerRecord(groups,numDims)1547 long HypersPerRecord (groups, numDims)
1548 struct GroupStruct *groups;
1549 long numDims;
1550 {
1551 int dimN; long nHypers = 1;
1552 for (dimN = 0; dimN < numDims; dimN++) {
1553 nHypers *= groups->nDimGroups[dimN];
1554 }
1555 return nHypers;
1556 }
1557
1558 /******************************************************************************
1559 * HyperStartRecord.
1560 ******************************************************************************/
1561
HyperStartOfRecord(hyper,numDims)1562 Logical HyperStartOfRecord (hyper, numDims)
1563 struct HyperStruct *hyper;
1564 long numDims;
1565 {
1566 int dimN;
1567 for (dimN = 0; dimN < numDims; dimN++) {
1568 if (hyper->dimIndices[dimN] > 0) return FALSE;
1569 }
1570 return TRUE;
1571 }
1572
1573 /******************************************************************************
1574 * InitHyperParms.
1575 ******************************************************************************/
1576
InitHyperParms(hyper,groups,numDims,nHypers,nValues)1577 void InitHyperParms (hyper, groups, numDims, nHypers, nValues)
1578 struct HyperStruct *hyper;
1579 struct GroupStruct *groups;
1580 long numDims;
1581 long *nHypers;
1582 long *nValues;
1583 {
1584 int dimN;
1585 *nHypers = groups->nRecGroups;
1586 for (dimN = 0; dimN < numDims; dimN++) *nHypers *= groups->nDimGroups[dimN];
1587 hyper->recNumber = 0;
1588 hyper->recCount = groups->firstRecCount;
1589 hyper->recInterval = 1;
1590 for (dimN = 0; dimN < numDims; dimN++) {
1591 hyper->dimIndices[dimN] = 0;
1592 hyper->dimCounts[dimN] = groups->firstDimCount[dimN];
1593 hyper->dimIntervals[dimN] = 1;
1594 }
1595 *nValues = hyper->recCount;
1596 for (dimN = 0; dimN < numDims; dimN++) *nValues *= hyper->dimCounts[dimN];
1597 return;
1598 }
1599
1600 /******************************************************************************
1601 * IncrHyperParms.
1602 ******************************************************************************/
1603
IncrHyperParms(hyper,groups,numDims,rowMajor,nValues)1604 void IncrHyperParms (hyper, groups, numDims, rowMajor, nValues)
1605 struct HyperStruct *hyper;
1606 struct GroupStruct *groups;
1607 long numDims;
1608 Logical rowMajor;
1609 long *nValues;
1610 {
1611 int lsDimN; /* Least significant dimension number. */
1612 int msDimN; /* Most significant dimension number. */
1613 int dimStep; /* How to increment dimension number from most
1614 significant to least significant. */
1615 int dimN;
1616 /****************************************************************************
1617 * Setup for majority.
1618 ****************************************************************************/
1619 lsDimN = BOO(rowMajor,(int)(numDims-1),0);
1620 msDimN = BOO(rowMajor,0,(int)(numDims-1));
1621 dimStep = BOO(rowMajor,1,-1);
1622 /****************************************************************************
1623 * Increment indices.
1624 ****************************************************************************/
1625 for (dimN = lsDimN; dimN != msDimN - dimStep; dimN -= dimStep) {
1626 if (groups->dimGroupN[dimN] < groups->nDimGroups[dimN]) {
1627 groups->dimGroupN[dimN]++;
1628 if (groups->dimGroupN[dimN] < groups->nDimGroups[dimN]) {
1629 hyper->dimIndices[dimN] += groups->firstDimCount[dimN];
1630 hyper->dimCounts[dimN] = groups->firstDimCount[dimN];
1631 }
1632 else {
1633 hyper->dimIndices[dimN] += groups->firstDimCount[dimN];
1634 hyper->dimCounts[dimN] = groups->lastDimCount[dimN];
1635 }
1636 *nValues = hyper->recCount;
1637 for (dimN = 0; dimN < numDims; dimN++) {
1638 *nValues *= hyper->dimCounts[dimN];
1639 }
1640 return;
1641 }
1642 else {
1643 groups->dimGroupN[dimN] = 1;
1644 hyper->dimIndices[dimN] = 0;
1645 hyper->dimCounts[dimN] = groups->firstDimCount[dimN];
1646 }
1647 }
1648 /****************************************************************************
1649 * Increment record.
1650 ****************************************************************************/
1651 groups->recGroupN++;
1652 hyper->recNumber += groups->firstRecCount;
1653 hyper->recCount = BOO(groups->recGroupN < groups->nRecGroups,
1654 groups->firstRecCount,groups->lastRecCount);
1655 *nValues = hyper->recCount;
1656 for (dimN = 0; dimN < numDims; dimN++) *nValues *= hyper->dimCounts[dimN];
1657 return;
1658 }
1659
1660 /******************************************************************************
1661 * WriteOutPct.
1662 ******************************************************************************/
1663
WriteOutPct(pct)1664 void WriteOutPct (pct)
1665 int pct;
1666 {
1667 char text[8+1];
1668 strcpyX (text, "\b\b\b\b", 8);
1669 if (pct < 10) strcatX (text, ".", 8);
1670 if (pct < 100) strcatX (text, ".", 8);
1671 sprintf (EofS(text), "%d", pct);
1672 strcatX (text, "%", 8);
1673 WriteOut (stdout, text);
1674 return;
1675 }
1676
1677 /******************************************************************************
1678 * SwitchMajority.
1679 ******************************************************************************/
1680
SwitchMajority(buffer,rowMajor,numDims,dimSizes,recCount,nValueBytes)1681 Logical SwitchMajority (buffer, rowMajor, numDims, dimSizes, recCount,
1682 nValueBytes)
1683 Byte *buffer;
1684 Logical rowMajor;
1685 long numDims;
1686 long dimSizes[];
1687 long recCount;
1688 size_t nValueBytes;
1689 {
1690 int dimN; long nRecordBytes, recX; Byte *offset; void *tBuffer;
1691 /****************************************************************************
1692 * If less than two dimensions no switching needs to be done.
1693 ****************************************************************************/
1694 if (numDims < 2) return TRUE;
1695 /****************************************************************************
1696 * Calculate number of bytes per record.
1697 ****************************************************************************/
1698 nRecordBytes = nValueBytes;
1699 for (dimN = 0; dimN < numDims; dimN++) nRecordBytes *= dimSizes[dimN];
1700 /****************************************************************************
1701 * Attempt to allocate a temporary buffer for one record.
1702 ****************************************************************************/
1703 #if defined(dos)
1704 if (TOObigIBMpc(nRecordBytes))
1705 tBuffer = NULL;
1706 else
1707 #endif
1708 tBuffer = cdf_AllocateMemory ((size_t) nRecordBytes, NULL);
1709 if (tBuffer == NULL) return FALSE;
1710 /****************************************************************************
1711 * Switch majority.
1712 ****************************************************************************/
1713 for (recX = 0, offset = buffer; recX < recCount;
1714 recX++, offset += (size_t) nRecordBytes) {
1715 if (rowMajor)
1716 ROWtoCOL (offset, tBuffer, numDims, dimSizes, (long) nValueBytes);
1717 else
1718 COLtoROW (offset, tBuffer, numDims, dimSizes, (long) nValueBytes);
1719 memmove (offset, tBuffer, (size_t) nRecordBytes);
1720 }
1721 /****************************************************************************
1722 * Free temporary buffer and return success.
1723 ****************************************************************************/
1724 cdf_FreeMemory (tBuffer, FatalError);
1725 return TRUE;
1726 }
1727
1728 /******************************************************************************
1729 * CompressedCDF.
1730 ******************************************************************************/
1731
CompressedCDF(CDFpath)1732 Logical CompressedCDF (CDFpath)
1733 char *CDFpath;
1734 {
1735 CDFstatus status; long cType, cParms[CDF_MAX_PARMS];
1736 OFF_T cFileSize, uFileSize;
1737 status = CDFlib (GET_, CDF_INFO_, CDFpath, &cType, cParms,
1738 &cFileSize, &uFileSize,
1739 NULL_);
1740 if (StatusBAD(status)) return FALSE;
1741 return ((Logical) (cType != NO_COMPRESSION));
1742 }
1743
1744 /******************************************************************************
1745 * SameCompressions.
1746 ******************************************************************************/
1747
SameCompressions(cType1,cParms1,cType2,cParms2)1748 Logical SameCompressions (cType1, cParms1, cType2, cParms2)
1749 long cType1;
1750 long cParms1[CDF_MAX_PARMS];
1751 long cType2;
1752 long cParms2[CDF_MAX_PARMS];
1753 {
1754 int parmN, pCount;
1755 /****************************************************************************
1756 * Compare compression types.
1757 ****************************************************************************/
1758 if (cType1 != cType2) return FALSE;
1759 /****************************************************************************
1760 * If same types, compare compression parameters (if any).
1761 ****************************************************************************/
1762 pCount = CompressionParmsCount(cType1);
1763 for (parmN = 0; parmN < pCount; parmN++) {
1764 if (cParms1[parmN] != cParms2[parmN]) return FALSE;
1765 }
1766 /****************************************************************************
1767 * Compressions must be the same.
1768 ****************************************************************************/
1769 return TRUE;
1770 }
1771
1772 /******************************************************************************
1773 * SameSparsenesses.
1774 ******************************************************************************/
1775
SameSparsenesses(sRecordsType1,sArraysType1,sArraysParms1,sRecordsType2,sArraysType2,sArraysParms2)1776 Logical SameSparsenesses (sRecordsType1, sArraysType1, sArraysParms1,
1777 sRecordsType2, sArraysType2, sArraysParms2)
1778 long sRecordsType1;
1779 long sArraysType1;
1780 long sArraysParms1[CDF_MAX_PARMS];
1781 long sRecordsType2;
1782 long sArraysType2;
1783 long sArraysParms2[CDF_MAX_PARMS];
1784 {
1785 int parmN, pCount;
1786 /****************************************************************************
1787 * Compare sparse records.
1788 ****************************************************************************/
1789 if (sRecordsType1 != sRecordsType2) return FALSE;
1790 /****************************************************************************
1791 * Compare sparse array types.
1792 ****************************************************************************/
1793 if (sArraysType1 != sArraysType2) return FALSE;
1794 /****************************************************************************
1795 * If same types, compare sparse array parameters (if any).
1796 ****************************************************************************/
1797 pCount = SparsenessParmsCount(sArraysType1);
1798 for (parmN = 0; parmN < pCount; parmN++) {
1799 if (sArraysParms1[parmN] != sArraysParms2[parmN]) return FALSE;
1800 }
1801 /****************************************************************************
1802 * Sparsenesses must be the same.
1803 ****************************************************************************/
1804 return TRUE;
1805 }
1806
1807 /******************************************************************************
1808 * WhichFormat.
1809 ******************************************************************************/
1810
WhichFormat(token)1811 long WhichFormat (token)
1812 char *token;
1813 {
1814 if (strncmpIgCase(token,"SINGLE",6) != 0) return SINGLE_FILE;
1815 if (strncmpIgCase(token,"MULTI",5) != 0) return MULTI_FILE;
1816 return -1;
1817 }
1818
1819 /******************************************************************************
1820 * WhichMajority.
1821 ******************************************************************************/
1822
WhichMajority(token)1823 long WhichMajority (token)
1824 char *token;
1825 {
1826 if (strncmpIgCase(token,"ROW",3) != 0) return ROW_MAJOR;
1827 if ((strncmpIgCase(token,"COL",3) != 0) ||
1828 (strncmpIgCase(token,"COLUMN",6) != 0)) return COLUMN_MAJOR;
1829 return -1;
1830 }
1831
1832 /******************************************************************************
1833 * WhichRecSparseness.
1834 ******************************************************************************/
1835
WhichRecSparseness(token)1836 long WhichRecSparseness (token)
1837 char *token;
1838 {
1839 if (strncmpIgCase(token,"None",4) != 0) return NO_SPARSERECORDS;
1840 if (strncmpIgCase(token,"sRecords.PAD",12) != 0) return PAD_SPARSERECORDS;
1841 if (strncmpIgCase(token,"sRecords.PREV",13) != 0) return PREV_SPARSERECORDS;
1842 return -1;
1843 }
1844
1845 /******************************************************************************
1846 * WhichCompression
1847 ******************************************************************************/
1848
WhichCompression(token,compression,cParms)1849 long WhichCompression (token, compression, cParms)
1850 char *token;
1851 long *compression;
1852 long cParms[CDF_MAX_PARMS];
1853 {
1854 *compression = -1;
1855 cParms[0] = 0;
1856 if (strncmpIgCase(token,"No",2) != 0) *compression = NO_COMPRESSION;
1857 else if (strncmpIgCase(token,"RLE",3) != 0) *compression = RLE_COMPRESSION;
1858 else if (strncmpIgCase(token,"HUFF",4) != 0) *compression = HUFF_COMPRESSION;
1859 else if (strncmpIgCase(token,"AHUFF",5) != 0) *compression = AHUFF_COMPRESSION;
1860 else if (strncmpIgCase(token,"GZIP",4) != 0) {
1861 #if defined(__osf__)
1862 int clevel;
1863 if (sscanf(token,"GZIP.%d",&clevel) == 1)
1864 #else
1865 long clevel;
1866 if (sscanf(token,"GZIP.%1d",&clevel) == 1)
1867 #endif
1868 if (INCLUSIVE(1,clevel,9)) {
1869 *compression = GZIP_COMPRESSION;
1870 cParms[0] = (long) clevel;
1871 }
1872 }
1873 /* if (strncmpIgCase(token,"ZLIB",4)) *compression = ZLIB_COMPRESSION; */
1874 return (long) *compression;
1875 }
1876
1877 /******************************************************************************
1878 * WhichEncoding. `MIPSEL' (DECstation) and `MIPSEB' (SGi) are valid synonyms
1879 * in order to remain compatible with previous releases of CDF.
1880 ******************************************************************************/
1881
WhichEncoding(token)1882 long WhichEncoding (token)
1883 char *token;
1884 {
1885 if (strncmpIgCase(token,"HOST",4) != 0) return HOST_ENCODING;
1886 if (strncmpIgCase(token,"NETWORK",6) != 0) return NETWORK_ENCODING;
1887 if (strncmpIgCase(token,"IBMPC",5) != 0) return IBMPC_ENCODING;
1888 if ((strncmpIgCase(token,"PPC",3) != 0) ||
1889 (strncmpIgCase(token,"MAC",3) != 0)) return PPC_ENCODING;
1890 if (strncmpIgCase(token,"SUN",3) != 0) return SUN_ENCODING;
1891 if (strncmpIgCase(token,"VAX",3) != 0) return VAX_ENCODING;
1892 if ((strncmpIgCase(token,"SGi",3) != 0) ||
1893 (strncmpIgCase(token,"MIPSEB",6) != 0)) return SGi_ENCODING;
1894 if ((strncmpIgCase(token,"DECSTATION",10) != 0) ||
1895 (strncmpIgCase(token,"MIPSEL",6) != 0)) return DECSTATION_ENCODING;
1896 if (strncmpIgCase(token,"IBMRS",5) != 0) return IBMRS_ENCODING;
1897 if (strncmpIgCase(token,"HP",2) != 0) return HP_ENCODING;
1898 if (strncmpIgCase(token,"NeXT",4) != 0) return NeXT_ENCODING;
1899 if (strncmpIgCase(token,"ALPHAOSF1",9) != 0) return ALPHAOSF1_ENCODING;
1900 if (strncmpIgCase(token,"ALPHAVMSd",9) != 0) return ALPHAVMSd_ENCODING;
1901 if (strncmpIgCase(token,"ALPHAVMSg",9) != 0) return ALPHAVMSg_ENCODING;
1902 if (strncmpIgCase(token,"ALPHAVMSi",9) != 0) return ALPHAVMSi_ENCODING;
1903 return -1;
1904 }
1905
1906 /******************************************************************************
1907 * WhichDataType.
1908 ******************************************************************************/
1909
WhichDataType(token)1910 long WhichDataType (token)
1911 char *token;
1912 {
1913 if (strncmpIgCase(token,"BYTE",4) != 0) return CDF_BYTE;
1914 if (strncmpIgCase(token,"INT1",4) != 0) return CDF_INT1;
1915 if (strncmpIgCase(token,"UINT1",5) != 0) return CDF_UINT1;
1916 if (strncmpIgCase(token,"INT2",4) != 0) return CDF_INT2;
1917 if (strncmpIgCase(token,"UINT2",5) != 0) return CDF_UINT2;
1918 if (strncmpIgCase(token,"INT4",4) != 0) return CDF_INT4;
1919 if (strncmpIgCase(token,"UINT4",5) != 0) return CDF_UINT4;
1920 if (strncmpIgCase(token,"REAL4",5) != 0) return CDF_REAL4;
1921 if (strncmpIgCase(token,"FLOAT",5) != 0) return CDF_FLOAT;
1922 if (strncmpIgCase(token,"REAL8",5) != 0) return CDF_REAL8;
1923 if (strncmpIgCase(token,"DOUBLE",6) != 0) return CDF_DOUBLE;
1924 if (strncmpIgCase(token,"CHAR",4) != 0) return CDF_CHAR;
1925 if (strncmpIgCase(token,"UCHAR",5) != 0) return CDF_UCHAR;
1926 if (strncmpIgCase(token,"EPOCH",5) != 0) return CDF_EPOCH;
1927 if (strncmpIgCase(token,"EPOCH16",7) != 0) return CDF_EPOCH16;
1928 if (strncmpIgCase(token,"CDF_BYTE",8) != 0) return CDF_BYTE;
1929 if (strncmpIgCase(token,"CDF_INT1",8) != 0) return CDF_INT1;
1930 if (strncmpIgCase(token,"CDF_UINT1",9) != 0) return CDF_UINT1;
1931 if (strncmpIgCase(token,"CDF_INT2",8) != 0) return CDF_INT2;
1932 if (strncmpIgCase(token,"CDF_UINT2",9) != 0) return CDF_UINT2;
1933 if (strncmpIgCase(token,"CDF_INT4",8) != 0) return CDF_INT4;
1934 if (strncmpIgCase(token,"CDF_UINT4",9) != 0) return CDF_UINT4;
1935 if (strncmpIgCase(token,"CDF_REAL4",9) != 0) return CDF_REAL4;
1936 if (strncmpIgCase(token,"CDF_FLOAT",9) != 0) return CDF_FLOAT;
1937 if (strncmpIgCase(token,"CDF_REAL8",9) != 0) return CDF_REAL8;
1938 if (strncmpIgCase(token,"CDF_DOUBLE",10) != 0) return CDF_DOUBLE;
1939 if (strncmpIgCase(token,"CDF_CHAR",8) != 0) return CDF_CHAR;
1940 if (strncmpIgCase(token,"CDF_UCHAR",9) != 0) return CDF_UCHAR;
1941 if (strncmpIgCase(token,"CDF_EPOCH",9) != 0) return CDF_EPOCH;
1942 if (strncmpIgCase(token,"CDF_EPOCH16",11) != 0) return CDF_EPOCH16;
1943 return -1;
1944 }
1945
1946 /******************************************************************************
1947 * WhichChecksum.
1948 ******************************************************************************/
1949
WhichChecksum(token)1950 long WhichChecksum (token)
1951 char *token;
1952 {
1953 if ((strncmpIgCase(token,"NO",2) != 0) ||
1954 (strncmpIgCase(token,"NONE",4) != 0)) return NO_CHECKSUM;
1955 if (strncmpIgCase(token,"MD5",3) != 0) return MD5_CHECKSUM;
1956 if (strncmpIgCase(token,"OTHER",5) != 0) return OTHER_CHECKSUM;
1957 return -1;
1958 }
1959
1960 /******************************************************************************
1961 * EncodingToken.
1962 * Returns address of character string for encoding.
1963 ******************************************************************************/
1964
EncodingToken(encoding)1965 char *EncodingToken (encoding)
1966 long encoding;
1967 {
1968 switch (encoding) {
1969 case NETWORK_ENCODING: return "NETWORK";
1970 case VAX_ENCODING: return "VAX";
1971 case SUN_ENCODING: return "SUN";
1972 case DECSTATION_ENCODING: return "DECSTATION";
1973 case SGi_ENCODING: return "SGi";
1974 case IBMRS_ENCODING: return "IBMRS";
1975 case IBMPC_ENCODING: return "IBMPC";
1976 case HP_ENCODING: return "HP";
1977 case NeXT_ENCODING: return "NeXT";
1978 case ALPHAOSF1_ENCODING: return "ALPHAOSF1";
1979 case ALPHAVMSd_ENCODING: return "ALPHAVMSd";
1980 case ALPHAVMSg_ENCODING: return "ALPHAVMSg";
1981 case ALPHAVMSi_ENCODING: return "ALPHAVMSi";
1982 case PPC_ENCODING: return "PPC";
1983 default: return "?";
1984 }
1985 }
1986
1987 /******************************************************************************
1988 * MajorityToken.
1989 * Returns address of character string for majority.
1990 ******************************************************************************/
1991
MajorityToken(majority)1992 char *MajorityToken (majority)
1993 long majority;
1994 {
1995 switch (majority) {
1996 case ROW_MAJOR: return "ROW";
1997 case COLUMN_MAJOR: return "COLUMN";
1998 default: return "?";
1999 }
2000 }
2001
2002 /******************************************************************************
2003 * FormatToken.
2004 * Returns address of character string for format.
2005 ******************************************************************************/
2006
FormatToken(format)2007 char *FormatToken (format)
2008 long format;
2009 {
2010 switch (format) {
2011 case SINGLE_FILE: return "SINGLE";
2012 case MULTI_FILE: return "MULTI";
2013 default: return "?";
2014 }
2015 }
2016
2017 /******************************************************************************
2018 * ChecksumToken.
2019 * Returns address of character string for checksum.
2020 ******************************************************************************/
2021
ChecksumToken(checksum)2022 char *ChecksumToken (checksum)
2023 long checksum;
2024 {
2025 switch (checksum) {
2026 case NO_CHECKSUM: return "None";
2027 case MD5_CHECKSUM: return "MD5";
2028 case OTHER_CHECKSUM: return "Other";
2029 default: return "?";
2030 }
2031 }
2032
2033 /******************************************************************************
2034 * ScopeToken.
2035 * Returns address of character string for scope.
2036 ******************************************************************************/
2037
ScopeToken(scope)2038 char *ScopeToken (scope)
2039 long scope;
2040 {
2041 switch (scope) {
2042 case GLOBAL_SCOPE: return "GLOBAL";
2043 case VARIABLE_SCOPE: return "VARIABLE";
2044 default: return "?";
2045 }
2046 }
2047
2048 /******************************************************************************
2049 * VarianceToken.
2050 * Returns address of character string for variance.
2051 ******************************************************************************/
2052
VarianceToken(variance)2053 char *VarianceToken (variance)
2054 long variance;
2055 {
2056 switch (variance) {
2057 case VARY: return "VARY";
2058 case NOVARY: return "NOVARY";
2059 default: return "?";
2060 }
2061 }
2062
2063 /******************************************************************************
2064 * TFvarianceToken.
2065 * Returns address of character string for variance (T/F).
2066 ******************************************************************************/
2067
TFvarianceToken(variance)2068 char *TFvarianceToken (variance)
2069 long variance;
2070 {
2071 switch (variance) {
2072 case VARY: return "T";
2073 case NOVARY: return "F";
2074 default: return "?";
2075 }
2076 }
2077
2078 /******************************************************************************
2079 * DataTypeToken.
2080 * Returns address of character string for data type.
2081 ******************************************************************************/
2082
DataTypeToken(dataType)2083 char *DataTypeToken (dataType)
2084 long dataType;
2085 {
2086 switch (dataType) {
2087 case CDF_BYTE: return "BYTE";
2088 case CDF_INT1: return "INT1";
2089 case CDF_INT2: return "INT2";
2090 case CDF_INT4: return "INT4";
2091 case CDF_UINT1: return "UINT1";
2092 case CDF_UINT2: return "UINT2";
2093 case CDF_UINT4: return "UINT4";
2094 case CDF_REAL4: return "REAL4";
2095 case CDF_REAL8: return "REAL8";
2096 case CDF_FLOAT: return "FLOAT";
2097 case CDF_DOUBLE: return "DOUBLE";
2098 case CDF_EPOCH: return "EPOCH";
2099 case CDF_EPOCH16: return "EPOCH16";
2100 case CDF_CHAR: return "CHAR";
2101 case CDF_UCHAR: return "UCHAR";
2102 default: return "?";
2103 }
2104 }
2105
2106 /******************************************************************************
2107 * CompressionToken.
2108 * Returns address of character string for compression type/parameters.
2109 ******************************************************************************/
2110
CompressionToken(cType,cParms)2111 char *CompressionToken (cType, cParms)
2112 long cType;
2113 long cParms[CDF_MAX_PARMS];
2114 {
2115 switch (cType) {
2116 case NO_COMPRESSION:
2117 return "None";
2118 case RLE_COMPRESSION:
2119 switch (cParms[0]) {
2120 case RLE_OF_ZEROs: return "RLE.0";
2121 default: return "RLE.?";
2122 }
2123 case HUFF_COMPRESSION:
2124 switch (cParms[0]) {
2125 case OPTIMAL_ENCODING_TREES: return "HUFF.0";
2126 default: return "HUFF.?";
2127 }
2128 case AHUFF_COMPRESSION:
2129 switch (cParms[0]) {
2130 case OPTIMAL_ENCODING_TREES: return "AHUFF.0";
2131 default: return "AHUFF.?";
2132 }
2133 case GZIP_COMPRESSION: {
2134 static char token[MAX_GZIP_TOKEN_LEN+1];
2135 sprintf (token, "GZIP.%d", (int) cParms[0]);
2136 return token;
2137 }
2138 /*
2139 case ZLIB_COMPRESSION:
2140 switch (cParms[0]) {
2141 case RLE_OF_ZEROs: return "ZLIB.0";
2142 default: return "ZLIB.?";
2143 }
2144 */
2145 default: return "?";
2146 }
2147 }
2148
2149 /******************************************************************************
2150 * SparsenessToken.
2151 * Returns address of character string for sparseness types/parameters.
2152 * Both record and array sparseness is encoded in the same string.
2153 ******************************************************************************/
2154
SparsenessToken(sRecordsType,sArraysType,sArraysParms)2155 char *SparsenessToken (sRecordsType, sArraysType, sArraysParms)
2156 long sRecordsType;
2157 long sArraysType;
2158 long sArraysParms[CDF_MAX_PARMS];
2159 {
2160 if (sArraysParms[0] == 0) { }; /* Quiets some compilers. */
2161 switch (sRecordsType) {
2162 case NO_SPARSERECORDS:
2163 switch (sArraysType) {
2164 case NO_SPARSEARRAYS:
2165 return "None";
2166 default:
2167 return "?";
2168 }
2169 case PAD_SPARSERECORDS:
2170 switch (sArraysType) {
2171 case NO_SPARSEARRAYS:
2172 return "sRecords.PAD";
2173 default:
2174 return "?";
2175 }
2176 case PREV_SPARSERECORDS:
2177 switch (sArraysType) {
2178 case NO_SPARSEARRAYS:
2179 return "sRecords.PREV";
2180 default:
2181 return "?";
2182 }
2183 default:
2184 return "?";
2185 }
2186 }
2187
2188 /******************************************************************************
2189 * PickDelimiter.
2190 * Exclamation mark (`!') isn't used because it starts a comment in a
2191 * skeleton table. Period (`.') isn't used because it ends a list of
2192 * attribute entries (in a skeleton table). Left bracket (`[') isn't used
2193 * because it starts a set of NRV indices (in a skeleton table).
2194 ******************************************************************************/
2195
PickDelimiter(string,N)2196 char PickDelimiter (string, N)
2197 char *string;
2198 size_t N;
2199 {
2200 static char choices[] = "\"'`^~:-,;|+=@#$%&*()/?<>{}]\\";
2201 int i;
2202 for (i = 0; choices[i] != NUL; i++) {
2203 if (strnchr(string,choices[i],N) == NULL) return choices[i];
2204 }
2205 return NUL; /* Very bad, use character stuffing if this is a problem. */
2206 }
2207
2208 /******************************************************************************
2209 * strnchr.
2210 ******************************************************************************/
2211
strnchr(string,chr,n)2212 static char *strnchr (string, chr, n)
2213 char *string;
2214 int chr;
2215 int n;
2216 {
2217 int i;
2218 for (i = 0; i < n; i++) if (string[i] == chr) return &string[i];
2219 return NULL;
2220 }
2221
2222 /******************************************************************************
2223 * sleep. Only for Microsoft C.
2224 ******************************************************************************/
2225
2226 #if defined(MICROSOFTC)
sleep(seconds)2227 void sleep (seconds)
2228 uInt seconds;
2229 {
2230 time_t start_time;
2231 time_t current_time;
2232
2233 time (&start_time);
2234 time (¤t_time);
2235
2236 while (current_time - start_time < seconds) time (¤t_time);
2237
2238 return;
2239 }
2240 #endif
2241
2242 /******************************************************************************
2243 * strstrIgCase.
2244 ******************************************************************************/
2245
strstrIgCase(string,substring)2246 char *strstrIgCase (string, substring)
2247 char *string;
2248 char *substring;
2249 {
2250 int stringL = strlen(string);
2251 int substringL = strlen(substring);
2252 int i, j;
2253 if (stringL == 0 || substringL == 0) return NULL;
2254 if (stringL < substringL) return NULL;
2255 for (i = 0; i < stringL; i++) {
2256 for (j = 0; j < substringL; j++) {
2257 if (MakeLower(substring[j]) != MakeLower(string[i+j])) break;
2258 }
2259 if (j == substringL) return &string[i];
2260 }
2261 return NULL;
2262 }
2263
2264 /******************************************************************************
2265 * strcmpIgCase.
2266 * It returns 1 if compared strings are identical with the same length
2267 * 0 if compared (sub)strings are not same
2268 ******************************************************************************/
2269
strcmpIgCase(string1,string2)2270 int strcmpIgCase (string1, string2)
2271 char *string1;
2272 char *string2;
2273 {
2274 int string1L = strlen(string1);
2275 int string2L = strlen(string2);
2276 int i;
2277 if (string1L != string2L) return 0;
2278 for (i = 0; i < string1L; i++) {
2279 if (MakeLower(string1[i]) != MakeLower(string2[i]))
2280 return 0;
2281 }
2282 return 1;
2283 }
2284
2285 /******************************************************************************
2286 * strncmpIgCase... Assuming count is the length from one of passed strings.
2287 * It compares characters upto the passed count.
2288 * It returns 1 if compared strings are identical with same length
2289 * 0 if compared (sub)strings are not same
2290 ******************************************************************************/
2291
strncmpIgCase(string1,string2,count)2292 int strncmpIgCase (string1, string2, count)
2293 char *string1;
2294 char *string2;
2295 size_t count;
2296 {
2297 int string1L = (int) strlen(string1);
2298 int string2L = (int) strlen(string2);
2299 int maxL, i;
2300 maxL = MAXIMUM(string1L,string2L);
2301 maxL = MINIMUM(maxL,(int)count);
2302 for (i = 0; i < maxL; i++) {
2303 if (i == string1L || i == string2L) break;
2304 if (MakeLower(string1[i]) != MakeLower(string2[i])) {
2305 return 0;
2306 }
2307 }
2308 if (string1L == string2L) return 1;
2309 else return 0;
2310 }
2311
2312 /******************************************************************************
2313 * strncmpIgCasePattern.
2314 * It returns 0 if compared strings are the same for the specified length
2315 * <>0 if compared (sub)strings do not have the same pattern
2316 ******************************************************************************/
2317
strncmpIgCasePattern(string1,string2,count)2318 int strncmpIgCasePattern (string1, string2, count)
2319 char *string1;
2320 char *string2;
2321 size_t count;
2322 {
2323 int string1L = (int) strlen(string1);
2324 int string2L = (int) strlen(string2);
2325 int maxL, i;
2326 maxL = MAXIMUM(string1L,string2L);
2327 maxL = MINIMUM(maxL,(int)count);
2328 for (i = 0; i < maxL; i++) {
2329 if (MakeLower(string1[i]) != MakeLower(string2[i])) {
2330 return ((int) (string1[i] - string2[i]));
2331 }
2332 }
2333 return 0;
2334 }
2335
2336 /******************************************************************************
2337 * strchrIgCase.
2338 ******************************************************************************/
2339
strchrIgCase(str,chr)2340 char *strchrIgCase (str, chr)
2341 char *str;
2342 int chr;
2343 {
2344 int strL = strlen(str);
2345 int i;
2346 if (strL == 0) return NULL;
2347 for (i = 0; i < strL; i++) {
2348 if (MakeLower(chr) == MakeLower(str[i])) return &str[i];
2349 }
2350 return NULL;
2351 }
2352
2353 /******************************************************************************
2354 * WriteEntryValue.
2355 ******************************************************************************/
2356
WriteEntryValue(fp,dataType,numElements,value,ccc,MaXcc)2357 void WriteEntryValue (fp, dataType, numElements, value, ccc, MaXcc)
2358 FILE *fp;
2359 long dataType;
2360 long numElements;
2361 void *value;
2362 int ccc; /* Current Cursor Column (at start). */
2363 int MaXcc; /* Maximum Cursor Column at which to output. */
2364 {
2365 if (STRINGdataType(dataType))
2366 WriteStringValue (fp, numElements, value, ccc, MaXcc);
2367 else {
2368 int i, elemN, n, cccBase = ccc;
2369 char evalue[80+1];
2370 Logical newLine = TRUE;
2371 for (elemN = 0; elemN < numElements; elemN++) {
2372 n = EncodeValue (dataType, (Byte *) value + elemN*CDFelemSize(dataType),
2373 evalue, EPOCH0_STYLE);
2374 if (ccc + (newLine ? 0 : 1) + n +
2375 (elemN != numElements - 1 ? 1 : 0) > MaXcc) {
2376 WriteOut (fp, "\n");
2377 for (i = 0; i < cccBase; i++) WriteOut (fp, " ");
2378 ccc = cccBase;
2379 newLine = TRUE;
2380 }
2381 if (!newLine) ccc += WriteOut (fp, " ");
2382 ccc += WriteOut (fp, evalue);
2383 if (elemN != numElements - 1) ccc += WriteOut (fp, ",");
2384 newLine = FALSE;
2385 }
2386 }
2387 return;
2388 }
2389
2390 /******************************************************************************
2391 * WriteStringValue.
2392 * Note that control characters may exist in the string being written (even
2393 * a NUL character). Control characters are to be replaced with `.'. For this
2394 * reason `memmove' is used to move around strings/substrings.
2395 ******************************************************************************/
2396
WriteStringValue(fp,numChars,value,ccc,MaXcc)2397 void WriteStringValue (fp, numChars, value, ccc, MaXcc)
2398 FILE *fp;
2399 long numChars;
2400 void *value;
2401 int ccc; /* Current Cursor Column (at start). */
2402 int MaXcc; /* Maximum Cursor Column at which to output. */
2403 {
2404 int cccBase = ccc, i;
2405 char *string = (char *) value;
2406 char delim;
2407 size_t textL = MaXcc + 1; /* MaXcc + 1. */
2408 char *text = (char *) cdf_AllocateMemory ((size_t) (textL + 1),
2409 FatalError);
2410
2411 if (ccc + 1 + numChars + 1 - 1 <= MaXcc) {
2412 delim = PickDelimiter (string, (size_t) numChars);
2413 text[0] = delim;
2414 memmove (&text[1], string, (size_t) numChars);
2415 text[(int)numChars+1] = delim;
2416 text[(int)numChars+2] = NUL;
2417 for (i = 1; i <= numChars; i++) {
2418 if (!Printable(text[i])) text[i] = '.';
2419 }
2420 WriteOut (fp, text);
2421 }
2422 else {
2423 int sss = MaXcc - ccc - 4 + 1; /* 4 for starting `"' and ending `" -'
2424 (assuming `"' is the delimeter). */
2425 char *substring = (char *) cdf_AllocateMemory ((size_t) (sss + 1),
2426 FatalError);
2427 int x = 0, len;
2428 while (x + sss < numChars) {
2429 if (string[x+sss] == ' ') /* First character next line will be a blank.*/
2430 len = sss;
2431 else {
2432 if (string[x+sss-1] == ' ') /* Last character on line is a blank. */
2433 len = sss;
2434 else { /* Look for a blank at which to break line. */
2435 for (i = x + sss - 2; i > x; i--) if (string[i] == ' ') break;
2436 if (i > x)
2437 len = i - x + 1;
2438 else
2439 len = sss;
2440 }
2441 }
2442 memmove (substring, &string[x], len);
2443 substring[len] = NUL;
2444 for (i = 0; i < len; i++) {
2445 if (!Printable(substring[i])) substring[i] = '.';
2446 }
2447 delim = PickDelimiter (substring, strlen(substring));
2448 sprintf (text, "%c%s%c -", delim, substring, delim);
2449 WriteOut (fp, text);
2450 WriteOut (fp, "\n");
2451 for (i = 0; i < cccBase; i++) WriteOut (fp, " ");
2452 x += len;
2453 }
2454 len = (size_t) (numChars - x);
2455 memmove (substring, &string[x], len);
2456 substring[len] = NUL;
2457 for (i = 0; i < len; i++) {
2458 if (!Printable(substring[i])) substring[i] = '.';
2459 }
2460 delim = PickDelimiter (substring, strlen(substring));
2461 sprintf (text, "%c%s%c", delim, substring, delim);
2462 WriteOut (fp, text);
2463 cdf_FreeMemory (substring, FatalError);
2464 }
2465 cdf_FreeMemory (text, FatalError);
2466 return;
2467 }
2468
2469 /******************************************************************************
2470 * ConvertDataType.
2471 ******************************************************************************/
2472
ConvertDataType(fromDataType,fromNumElems,fromPtr,toDataType,toNumElems,toPtr)2473 void ConvertDataType (fromDataType, fromNumElems, fromPtr, toDataType,
2474 toNumElems, toPtr)
2475 long fromDataType;
2476 long fromNumElems; /* Only used if character data type. */
2477 void *fromPtr;
2478 long toDataType;
2479 long toNumElems; /* Only used if character data type. */
2480 void *toPtr;
2481 {
2482 switch (fromDataType) {
2483 /**************************************************************************
2484 * 1-byte signed integer to...
2485 **************************************************************************/
2486 case CDF_BYTE:
2487 case CDF_INT1:
2488 switch (toDataType) {
2489 case CDF_BYTE:
2490 case CDF_INT1:
2491 *((sChar *) toPtr) = (sChar) *((sChar *) fromPtr);
2492 break;
2493 case CDF_UINT1:
2494 *((uChar *) toPtr) = (uChar) *((sChar *) fromPtr);
2495 break;
2496 case CDF_INT2:
2497 *((Int16 *) toPtr) = (Int16) *((sChar *) fromPtr);
2498 break;
2499 case CDF_UINT2:
2500 *((uInt16 *) toPtr) = (uInt16) *((sChar *) fromPtr);
2501 break;
2502 case CDF_INT4:
2503 *((Int32 *) toPtr) = (Int32) *((sChar *) fromPtr);
2504 break;
2505 case CDF_UINT4:
2506 *((uInt32 *) toPtr) = (uInt32) *((sChar *) fromPtr);
2507 break;
2508 case CDF_FLOAT:
2509 case CDF_REAL4:
2510 *((float *) toPtr) = (float) *((sChar *) fromPtr);
2511 break;
2512 case CDF_EPOCH:
2513 case CDF_DOUBLE:
2514 case CDF_REAL8:
2515 *((double *) toPtr) = (double) *((sChar *) fromPtr);
2516 break;
2517 case CDF_EPOCH16:
2518 *((double *) toPtr) = (double) *((sChar *) fromPtr);
2519 *(((double *) toPtr) + 1) = (double) *(((sChar *) fromPtr) + 1);
2520 break;
2521 case CDF_CHAR:
2522 case CDF_UCHAR: {
2523 int i, len;
2524 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2525 sprintf (tmp, "%d", *((sChar *) fromPtr));
2526 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2527 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2528 }
2529 break;
2530 }
2531 }
2532 break;
2533 /**************************************************************************
2534 * 1-byte unsigned integer to...
2535 **************************************************************************/
2536 case CDF_UINT1:
2537 switch (toDataType) {
2538 case CDF_BYTE:
2539 case CDF_INT1:
2540 *((sChar *) toPtr) = (sChar) *((uChar *) fromPtr);
2541 break;
2542 case CDF_UINT1:
2543 *((uChar *) toPtr) = (uChar) *((uChar *) fromPtr);
2544 break;
2545 case CDF_INT2:
2546 *((Int16 *) toPtr) = (Int16) *((uChar *) fromPtr);
2547 break;
2548 case CDF_UINT2:
2549 *((uInt16 *) toPtr) = (uInt16) *((uChar *) fromPtr);
2550 break;
2551 case CDF_INT4:
2552 *((Int32 *) toPtr) = (Int32) *((uChar *) fromPtr);
2553 break;
2554 case CDF_UINT4:
2555 *((uInt32 *) toPtr) = (uInt32) *((uChar *) fromPtr);
2556 break;
2557 case CDF_FLOAT:
2558 case CDF_REAL4:
2559 *((float *) toPtr) = (float) *((uChar *) fromPtr);
2560 break;
2561 case CDF_EPOCH:
2562 case CDF_DOUBLE:
2563 case CDF_REAL8:
2564 *((double *) toPtr) = (double) *((uChar *) fromPtr);
2565 break;
2566 case CDF_EPOCH16:
2567 *((double *) toPtr) = (double) *((uChar *) fromPtr);
2568 *(((double *) toPtr) + 1) = (double) *(((uChar *) fromPtr) + 1);
2569 break;
2570 case CDF_CHAR:
2571 case CDF_UCHAR: {
2572 int i, len;
2573 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2574 sprintf (tmp, "%u", *((uChar *) fromPtr));
2575 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2576 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2577 }
2578 break;
2579 }
2580 }
2581 break;
2582 /**************************************************************************
2583 * 2-byte signed integer to...
2584 **************************************************************************/
2585 case CDF_INT2:
2586 switch (toDataType) {
2587 case CDF_BYTE:
2588 case CDF_INT1:
2589 *((sChar *) toPtr) = (sChar) *((Int16 *) fromPtr);
2590 break;
2591 case CDF_UINT1:
2592 *((uChar *) toPtr) = (uChar) *((Int16 *) fromPtr);
2593 break;
2594 case CDF_INT2:
2595 *((Int16 *) toPtr) = (Int16) *((Int16 *) fromPtr);
2596 break;
2597 case CDF_UINT2:
2598 *((uInt16 *) toPtr) = (uInt16) *((Int16 *) fromPtr);
2599 break;
2600 case CDF_INT4:
2601 *((Int32 *) toPtr) = (Int32) *((Int16 *) fromPtr);
2602 break;
2603 case CDF_UINT4:
2604 *((uInt32 *) toPtr) = (uInt32) *((Int16 *) fromPtr);
2605 break;
2606 case CDF_FLOAT:
2607 case CDF_REAL4:
2608 *((float *) toPtr) = (float) *((Int16 *) fromPtr);
2609 break;
2610 case CDF_EPOCH:
2611 case CDF_DOUBLE:
2612 case CDF_REAL8:
2613 *((double *) toPtr) = (double) *((Int16 *) fromPtr);
2614 break;
2615 case CDF_EPOCH16:
2616 *((double *) toPtr) = (double) *((Int16 *) fromPtr);
2617 *(((double *) toPtr) + 1) = (double) *(((Int16 *) fromPtr) + 1);
2618 break;
2619 case CDF_CHAR:
2620 case CDF_UCHAR: {
2621 int i, len;
2622 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2623 sprintf (tmp, "%d", (int) *((Int16 *) fromPtr));
2624 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2625 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2626 }
2627 break;
2628 }
2629 }
2630 break;
2631 /**************************************************************************
2632 * 2-byte unsigned integer to...
2633 **************************************************************************/
2634 case CDF_UINT2:
2635 switch (toDataType) {
2636 case CDF_BYTE:
2637 case CDF_INT1:
2638 *((sChar *) toPtr) = (sChar) *((uInt16 *) fromPtr);
2639 break;
2640 case CDF_UINT1:
2641 *((uChar *) toPtr) = (uChar) *((uInt16 *) fromPtr);
2642 break;
2643 case CDF_INT2:
2644 *((Int16 *) toPtr) = (Int16) *((uInt16 *) fromPtr);
2645 break;
2646 case CDF_UINT2:
2647 *((uInt16 *) toPtr) = (uInt16) *((uInt16 *) fromPtr);
2648 break;
2649 case CDF_INT4:
2650 *((Int32 *) toPtr) = (Int32) *((uInt16 *) fromPtr);
2651 break;
2652 case CDF_UINT4:
2653 *((uInt32 *) toPtr) = (uInt32) *((uInt16 *) fromPtr);
2654 break;
2655 case CDF_FLOAT:
2656 case CDF_REAL4:
2657 *((float *) toPtr) = (float) *((uInt16 *) fromPtr);
2658 break;
2659 case CDF_EPOCH:
2660 case CDF_DOUBLE:
2661 case CDF_REAL8:
2662 *((double *) toPtr) = (double) *((uInt16 *) fromPtr);
2663 break;
2664 case CDF_EPOCH16:
2665 *((double *) toPtr) = (double) *((uInt16 *) fromPtr);
2666 *(((double *) toPtr) + 1) = (double) *(((uInt16 *) fromPtr) + 1);
2667 break;
2668 case CDF_CHAR:
2669 case CDF_UCHAR: {
2670 int i, len;
2671 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2672 sprintf (tmp, "%u", (int) *((uInt16 *) fromPtr));
2673 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2674 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2675 }
2676 break;
2677 }
2678 }
2679 break;
2680 /**************************************************************************
2681 * 4-byte signed integer to...
2682 **************************************************************************/
2683 case CDF_INT4:
2684 switch (toDataType) {
2685 case CDF_BYTE:
2686 case CDF_INT1:
2687 *((sChar *) toPtr) = (sChar) *((Int32 *) fromPtr);
2688 break;
2689 case CDF_UINT1:
2690 *((uChar *) toPtr) = (uChar) *((Int32 *) fromPtr);
2691 break;
2692 case CDF_INT2:
2693 *((Int16 *) toPtr) = (Int16) *((Int32 *) fromPtr);
2694 break;
2695 case CDF_UINT2:
2696 *((uInt16 *) toPtr) = (uInt16) *((Int32 *) fromPtr);
2697 break;
2698 case CDF_INT4:
2699 *((Int32 *) toPtr) = (Int32) *((Int32 *) fromPtr);
2700 break;
2701 case CDF_UINT4:
2702 *((uInt32 *) toPtr) = (uInt32) *((Int32 *) fromPtr);
2703 break;
2704 case CDF_FLOAT:
2705 case CDF_REAL4:
2706 *((float *) toPtr) = (float) *((Int32 *) fromPtr);
2707 break;
2708 case CDF_EPOCH:
2709 case CDF_DOUBLE:
2710 case CDF_REAL8:
2711 *((double *) toPtr) = (double) *((Int32 *) fromPtr);
2712 break;
2713 case CDF_EPOCH16:
2714 *((double *) toPtr) = (double) *((Int32 *) fromPtr);
2715 *(((double *) toPtr) + 1) = (double) *(((Int32 *) fromPtr) + 1);
2716 break;
2717 case CDF_CHAR:
2718 case CDF_UCHAR: {
2719 int i, len;
2720 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2721 sprintf (tmp, "%ld", (long) *((Int32 *) fromPtr));
2722 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2723 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2724 }
2725 break;
2726 }
2727 }
2728 break;
2729 /**************************************************************************
2730 * 4-byte unsigned integer to...
2731 **************************************************************************/
2732 case CDF_UINT4:
2733 switch (toDataType) {
2734 case CDF_BYTE:
2735 case CDF_INT1:
2736 *((sChar *) toPtr) = (sChar) *((uInt32 *) fromPtr);
2737 break;
2738 case CDF_UINT1:
2739 *((uChar *) toPtr) = (uChar) *((uInt32 *) fromPtr);
2740 break;
2741 case CDF_INT2:
2742 *((Int16 *) toPtr) = (Int16) *((uInt32 *) fromPtr);
2743 break;
2744 case CDF_UINT2:
2745 *((uInt16 *) toPtr) = (uInt16) *((uInt32 *) fromPtr);
2746 break;
2747 case CDF_INT4:
2748 *((Int32 *) toPtr) = (Int32) *((uInt32 *) fromPtr);
2749 break;
2750 case CDF_UINT4:
2751 *((uInt32 *) toPtr) = (uInt32) *((uInt32 *) fromPtr);
2752 break;
2753 case CDF_FLOAT:
2754 case CDF_REAL4:
2755 *((float *) toPtr) = (float) *((uInt32 *) fromPtr);
2756 break;
2757 case CDF_EPOCH:
2758 case CDF_DOUBLE:
2759 case CDF_REAL8:
2760 *((double *) toPtr) = (double) *((uInt32 *) fromPtr);
2761 break;
2762 case CDF_EPOCH16:
2763 *((double *) toPtr) = (double) *((uInt32 *) fromPtr);
2764 *(((double *) toPtr) + 1) = (double) *(((uInt32 *) fromPtr) + 1);
2765 break;
2766 case CDF_CHAR:
2767 case CDF_UCHAR: {
2768 int i, len;
2769 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2770 sprintf (tmp, "%lu", (uLong) *((uInt32 *) fromPtr));
2771 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2772 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2773 }
2774 break;
2775 }
2776 }
2777 break;
2778 /**************************************************************************
2779 * 4-byte floating-point to...
2780 **************************************************************************/
2781 case CDF_FLOAT:
2782 case CDF_REAL4:
2783 switch (toDataType) {
2784 case CDF_BYTE:
2785 case CDF_INT1:
2786 *((sChar *) toPtr) = (sChar) *((float *) fromPtr);
2787 break;
2788 case CDF_UINT1:
2789 *((uChar *) toPtr) = (uChar) *((float *) fromPtr);
2790 break;
2791 case CDF_INT2:
2792 *((Int16 *) toPtr) = (Int16) *((float *) fromPtr);
2793 break;
2794 case CDF_UINT2:
2795 *((uInt16 *) toPtr) = (uInt16) *((float *) fromPtr);
2796 break;
2797 case CDF_INT4:
2798 *((Int32 *) toPtr) = (Int32) *((float *) fromPtr);
2799 break;
2800 case CDF_UINT4:
2801 *((uInt32 *) toPtr) = (uInt32) *((float *) fromPtr);
2802 break;
2803 case CDF_FLOAT:
2804 case CDF_REAL4:
2805 *((float *) toPtr) = (float) *((float *) fromPtr);
2806 break;
2807 case CDF_EPOCH:
2808 case CDF_DOUBLE:
2809 case CDF_REAL8:
2810 *((double *) toPtr) = (double) *((float *) fromPtr);
2811 break;
2812 case CDF_EPOCH16:
2813 *((double *) toPtr) = (double) *((float *) fromPtr);
2814 *(((double *) toPtr) + 1) = (double) *(((float *) fromPtr) + 1);
2815 break;
2816 case CDF_CHAR:
2817 case CDF_UCHAR: {
2818 int i, len;
2819 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2820 sprintf (tmp, "%f", *((float *) fromPtr));
2821 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2822 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2823 }
2824 break;
2825 }
2826 }
2827 break;
2828 /**************************************************************************
2829 * 8-byte floating-point to...
2830 **************************************************************************/
2831 case CDF_EPOCH:
2832 case CDF_DOUBLE:
2833 case CDF_REAL8:
2834 switch (toDataType) {
2835 case CDF_BYTE:
2836 case CDF_INT1:
2837 *((sChar *) toPtr) = (sChar) *((double *) fromPtr);
2838 break;
2839 case CDF_UINT1:
2840 *((uChar *) toPtr) = (uChar) *((double *) fromPtr);
2841 break;
2842 case CDF_INT2:
2843 *((Int16 *) toPtr) = (Int16) *((double *) fromPtr);
2844 break;
2845 case CDF_UINT2:
2846 *((uInt16 *) toPtr) = (uInt16) *((double *) fromPtr);
2847 break;
2848 case CDF_INT4:
2849 *((Int32 *) toPtr) = (Int32) *((double *) fromPtr);
2850 break;
2851 case CDF_UINT4:
2852 *((uInt32 *) toPtr) = (uInt32) *((double *) fromPtr);
2853 break;
2854 case CDF_FLOAT:
2855 case CDF_REAL4:
2856 *((float *) toPtr) = (float) *((double *) fromPtr);
2857 break;
2858 case CDF_EPOCH:
2859 case CDF_DOUBLE:
2860 case CDF_REAL8:
2861 *((double *) toPtr) = (double) *((double *) fromPtr);
2862 break;
2863 case CDF_CHAR:
2864 case CDF_UCHAR: {
2865 int i, len;
2866 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2867 sprintf (tmp, "%f", *((double *) fromPtr));
2868 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2869 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2870 }
2871 break;
2872 }
2873 }
2874 break;
2875 /**************************************************************************
2876 * 16-byte floating-point to...
2877 **************************************************************************/
2878 case CDF_EPOCH16:
2879 switch (toDataType) {
2880 case CDF_BYTE:
2881 case CDF_INT1:
2882 *((sChar *) toPtr) = (sChar) *((double *) fromPtr);
2883 *(((sChar *) toPtr) + 1) = (sChar) *(((double *) fromPtr) + 1);
2884 break;
2885 case CDF_UINT1:
2886 *((uChar *) toPtr) = (uChar) *((double *) fromPtr);
2887 *(((uChar *) toPtr) + 1) = (uChar) *(((double *) fromPtr) + 1);
2888 break;
2889 case CDF_INT2:
2890 *((Int16 *) toPtr) = (Int16) *((double *) fromPtr);
2891 *(((Int16 *) toPtr) + 1) = (Int16) *(((double *) fromPtr) + 1);
2892 break;
2893 case CDF_UINT2:
2894 *((uInt16 *) toPtr) = (uInt16) *((double *) fromPtr);
2895 *(((uInt16 *) toPtr) + 1) = (uInt16) *(((double *) fromPtr) + 1);
2896 break;
2897 case CDF_INT4:
2898 *((Int32 *) toPtr) = (Int32) *((double *) fromPtr);
2899 *(((Int32 *) toPtr) + 1) = (Int32) *(((double *) fromPtr) + 1);
2900 break;
2901 case CDF_UINT4:
2902 *((uInt32 *) toPtr) = (uInt32) *((double *) fromPtr);
2903 *(((uInt32 *) toPtr) + 1) = (uInt32) *(((double *) fromPtr) + 1);
2904 break;
2905 case CDF_FLOAT:
2906 case CDF_REAL4:
2907 *((float *) toPtr) = (float) *((double *) fromPtr);
2908 *(((float *) toPtr) + 1) = (float) *(((double *) fromPtr) + 1);
2909 break;
2910 case CDF_EPOCH:
2911 case CDF_DOUBLE:
2912 case CDF_REAL8:
2913 *((double *) toPtr) = (double) *((double *) fromPtr);
2914 *(((double *) toPtr) + 1) = (double) *(((double *) fromPtr) + 1);
2915 break;
2916 case CDF_EPOCH16:
2917 *((double *) toPtr) = (double) *((double *) fromPtr);
2918 *(((double *) toPtr) + 1) = (double) *(((double *) fromPtr) + 1);
2919 break;
2920 case CDF_CHAR:
2921 case CDF_UCHAR: {
2922 int i, j, len;
2923 char tmp[MAX_nonSTRING_VALUE_LEN+1];
2924 sprintf (tmp, "%f", *((double *) fromPtr));
2925 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2926 *((char *) toPtr + i) = (i < len ? tmp[i] : ' ');
2927 }
2928 sprintf (tmp, "%f", *(((double *) fromPtr) + 1));
2929 j = i;
2930 for (i = 0, len = strlen(tmp); i < toNumElems; i++) {
2931 *((char *) toPtr + j) = (i < len ? tmp[i] : ' ');
2932 }
2933 break;
2934 }
2935 }
2936 break;
2937 /**************************************************************************
2938 * character (string) to...
2939 **************************************************************************/
2940 case CDF_CHAR:
2941 case CDF_UCHAR: {
2942 size_t nBytes = (size_t) (fromNumElems + 1);
2943 char *str = (char *) cdf_AllocateMemory (nBytes, FatalError);
2944 memmove (str, fromPtr, (size_t) fromNumElems);
2945 str[(int)fromNumElems] = NUL;
2946 switch (toDataType) {
2947 case CDF_BYTE:
2948 case CDF_INT1: {
2949 int tmp;
2950 if (sscanf(str,"%d",&tmp) < 1)
2951 *((sChar *) toPtr) = 0;
2952 else
2953 *((sChar *) toPtr) = (sChar) tmp;
2954 break;
2955 }
2956 case CDF_UINT1: {
2957 uInt tmp;
2958 if (sscanf(str,"%u",&tmp) < 1)
2959 *((uChar *) toPtr) = 0;
2960 else
2961 *((uChar *) toPtr) = (uChar) tmp;
2962 break;
2963 }
2964 case CDF_INT2: {
2965 int tmp;
2966 if (sscanf(str,"%d",&tmp) < 1)
2967 *((Int16 *) toPtr) = 0;
2968 else
2969 *((Int16 *) toPtr) = (Int16) tmp;
2970 break;
2971 }
2972 case CDF_UINT2: {
2973 uInt tmp;
2974 if (sscanf(str,"%u",&tmp) < 1)
2975 *((uInt16 *) toPtr) = 0;
2976 else
2977 *((uInt16 *) toPtr) = (uInt16) tmp;
2978 break;
2979 }
2980 case CDF_INT4: {
2981 long tmp;
2982 if (sscanf(str,"%ld",&tmp) < 1)
2983 *((Int32 *) toPtr) = 0;
2984 else
2985 *((Int32 *) toPtr) = (Int32) tmp;
2986 break;
2987 }
2988 case CDF_UINT4: {
2989 uLong tmp;
2990 if (sscanf(str,"%lu",&tmp) < 1)
2991 *((uInt32 *) toPtr) = 0;
2992 else
2993 *((uInt32 *) toPtr) = (uInt32) tmp;
2994 break;
2995 }
2996 case CDF_FLOAT:
2997 case CDF_REAL4: {
2998 float tmp;
2999 if (sscanf(str,"%g",&tmp) < 1)
3000 *((float *) toPtr) = (float) 0.0;
3001 else
3002 *((float *) toPtr) = tmp;
3003 break;
3004 }
3005 case CDF_EPOCH:
3006 case CDF_DOUBLE:
3007 case CDF_REAL8: {
3008 double tmp;
3009 if (sscanf(str,"%lg",&tmp) < 1)
3010 *((double *) toPtr) = 0.0;
3011 else
3012 *((double *) toPtr) = tmp;
3013 break;
3014 }
3015 case CDF_EPOCH16: {
3016 double tmp1, tmp2;
3017 if (sscanf(str,"%lg %lg",&tmp1, &tmp2) < 2) {
3018 *((double *) toPtr) = 0.0;
3019 *(((double *) toPtr) + 1) = 0.0;
3020 } else {
3021 *((double *) toPtr) = tmp1;
3022 *(((double *) toPtr) + 1) = tmp2;
3023 }
3024 break;
3025 }
3026 case CDF_CHAR:
3027 case CDF_UCHAR: {
3028 int i;
3029 for (i = 0; i < toNumElems; i++) {
3030 *((char *) toPtr + i) = (i < fromNumElems ? str[i] : ' ');
3031 }
3032 break;
3033 }
3034 }
3035 cdf_FreeMemory (str, FatalError);
3036 break;
3037 }
3038 }
3039 return;
3040 }
3041
3042 /******************************************************************************
3043 * DecodeValues.
3044 * Memory for the values is allocated here but is NOT freed (unless an
3045 * error occurred.)
3046 ******************************************************************************/
3047
DecodeValues(string,dataType,numElems,values,style)3048 Logical DecodeValues (string, dataType, numElems, values, style)
3049 char *string;
3050 long dataType;
3051 long *numElems;
3052 void **values;
3053 int style; /* EPOCH style. */
3054 {
3055 if (STRINGdataType(dataType)) {
3056 /****************************************************************************
3057 * Delimited character string.
3058 ****************************************************************************/
3059 char delim;
3060 char *firstDelim, *secondDelim;
3061 char *ptr = string;
3062 while (*ptr != NUL && Spacing(*ptr)) ptr++; /* Skip to delimiter. */
3063 if (*ptr == NUL) return FALSE; /* Null-string. */
3064 delim = *ptr;
3065 firstDelim = ptr;
3066 secondDelim = strchr (ptr + 1, delim);
3067 if (secondDelim == NULL) return FALSE;
3068 *numElems = secondDelim - firstDelim - 1;
3069 *values = cdf_AllocateMemory ((size_t) (*numElems + 1), FatalError);
3070 memmove (*values, firstDelim + 1, (size_t) *numElems);
3071 ((char *) *values)[(int)(*numElems)] = NUL;
3072 }
3073 else {
3074 /****************************************************************************
3075 * Comma separated values.
3076 ****************************************************************************/
3077 int i, Ncommas; char *ptr;
3078 for (Ncommas = 0, i = 0; string[i] != NUL; i++) /* Count commas. */
3079 if (string[i] == ',') Ncommas++;
3080 *numElems = Ncommas + 1;
3081 *values = cdf_AllocateMemory ((size_t) (*numElems * CDFelemSize(dataType)),
3082 FatalError);
3083 for (ptr = string, i = 0; i < *numElems; i++) {
3084 switch (dataType) {
3085 case CDF_BYTE:
3086 case CDF_INT1: {
3087 int temp;
3088 if (sscanf(ptr,"%d",&temp) != 1) {
3089 cdf_FreeMemory (*values, FatalError);
3090 return FALSE;
3091 }
3092 if (temp < -128 || temp > 127) {
3093 cdf_FreeMemory (*values, FatalError);
3094 return FALSE;
3095 }
3096 *((sChar *) *values + i) = (sChar) temp;
3097 break;
3098 }
3099 case CDF_UINT1: {
3100 int temp;
3101 if (sscanf(ptr,"%d",&temp) != 1) {
3102 cdf_FreeMemory (*values, FatalError);
3103 return FALSE;
3104 }
3105 if (temp < 0 || temp > 255) {
3106 cdf_FreeMemory (*values, FatalError);
3107 return FALSE;
3108 }
3109 *((uChar *) *values + i) = (uChar) temp;
3110 break;
3111 }
3112 case CDF_INT2: {
3113 if (sscanf(ptr,"%hd",(Int16 *) *values + i) != 1) {
3114 cdf_FreeMemory (*values, FatalError);
3115 return FALSE;
3116 }
3117 break;
3118 }
3119 case CDF_UINT2: {
3120 long temp;
3121 if (sscanf(ptr,"%ld",&temp) != 1) {
3122 cdf_FreeMemory (*values, FatalError);
3123 return FALSE;
3124 }
3125 if (temp < 0 || temp > 65535L) {
3126 cdf_FreeMemory (*values, FatalError);
3127 return FALSE;
3128 }
3129 *((uInt16 *) *values + i) = (uInt16) temp;
3130 break;
3131 }
3132 case CDF_INT4:
3133 if (!DecodeInt32(ptr,(Int32 *) *values + i)) {
3134 cdf_FreeMemory (*values, FatalError);
3135 return FALSE;
3136 }
3137 break;
3138 case CDF_UINT4:
3139 if (!DecodeInt32u(ptr,(uInt32 *) *values + i)) {
3140 cdf_FreeMemory (*values, FatalError);
3141 return FALSE;
3142 }
3143 break;
3144 case CDF_REAL4:
3145 case CDF_FLOAT:
3146 if (sscanf(ptr,"%f",(float *) *values + i) != 1) {
3147 cdf_FreeMemory (*values, FatalError);
3148 return FALSE;
3149 }
3150 break;
3151 case CDF_REAL8:
3152 case CDF_DOUBLE:
3153 if (sscanf(ptr,"%lf",(double *) *values + i) != 1) {
3154 cdf_FreeMemory (*values, FatalError);
3155 return FALSE;
3156 }
3157 break;
3158 case CDF_EPOCH: {
3159 double value;
3160 switch (style) {
3161 case EPOCH0_STYLE:
3162 value = parseEPOCH (ptr);
3163 break;
3164 case EPOCH1_STYLE:
3165 value = parseEPOCH1 (ptr);
3166 break;
3167 case EPOCH2_STYLE:
3168 value = parseEPOCH2 (ptr);
3169 break;
3170 case EPOCH3_STYLE:
3171 value = parseEPOCH3 (ptr);
3172 break;
3173 case EPOCHf_STYLE:
3174 cdf_FreeMemory (*values, FatalError);
3175 return DecodeValues(string,CDF_DOUBLE,numElems,values,style);
3176 case EPOCHx_STYLE:
3177 value = parseEPOCH (ptr); /* Assume EPOCH0_STYLE instead. */
3178 break;
3179 }
3180 if (value == ILLEGAL_EPOCH_VALUE) {
3181 cdf_FreeMemory (*values, FatalError);
3182 return FALSE;
3183 }
3184 else
3185 *((double *) *values + i) = value;
3186 break;
3187 }
3188 case CDF_EPOCH16: {
3189 double value[2], dummy;
3190 switch (style) {
3191 case EPOCH0_STYLE:
3192 dummy = parseEPOCH16 (ptr, value);
3193 break;
3194 case EPOCH1_STYLE:
3195 dummy = parseEPOCH16_1 (ptr, value);
3196 break;
3197 case EPOCH2_STYLE:
3198 dummy = parseEPOCH16_2 (ptr, value);
3199 break;
3200 case EPOCH3_STYLE:
3201 dummy = parseEPOCH16_3 (ptr, value);
3202 break;
3203 case EPOCHf_STYLE:
3204 cdf_FreeMemory (*values, FatalError);
3205 return DecodeValues(string,CDF_DOUBLE,numElems,values,style);
3206 case EPOCHx_STYLE: /* Assume EPOCH0_STYLE instead. */
3207 dummy = parseEPOCH16 (ptr, value);
3208 break;
3209 }
3210 if (dummy == ILLEGAL_EPOCH_VALUE ||
3211 value[0] == ILLEGAL_EPOCH_VALUE ||
3212 value[1] == ILLEGAL_EPOCH_VALUE) {
3213 cdf_FreeMemory (*values, FatalError);
3214 return FALSE;
3215 }
3216 else {
3217 int j = 2 * i;
3218 *((double *) *values + j) = value[0];
3219 *(((double *) *values + j) + 1) = value[1];
3220 }
3221 break;
3222 }
3223 }
3224 ptr = strchr (ptr, ',') + 1; /* Garbage last time, doesn't matter. */
3225 }
3226 }
3227 return TRUE;
3228 }
3229
3230 /******************************************************************************
3231 * DecodeInt32.
3232 * This routine is necessary because DEC Alphas running OpenVMS do not
3233 * decode "-2147483648" properly.
3234 ******************************************************************************/
3235
DecodeInt32(text,binary)3236 static Logical DecodeInt32 (text, binary)
3237 char *text;
3238 Int32 *binary;
3239 {
3240 if (EqStringsIgLTws(text,"-2147483648"))
3241 #if defined(dos)
3242 *binary = (Int32) -2147483648L;
3243 #else
3244 *binary = (Int32) 0x80000000;
3245 #endif
3246 else
3247 if (sscanf(text,Int32FORMAT,binary) != 1) return FALSE;
3248 return TRUE;
3249 }
3250
3251 /******************************************************************************
3252 * DecodeInt32u.
3253 * This routine is necessary because VAX/VMS systems do not properly decode
3254 * unsigned values.
3255 ******************************************************************************/
3256
DecodeInt32u(text,binary)3257 static Logical DecodeInt32u (text, binary)
3258 char *text;
3259 uInt32 *binary;
3260 {
3261 char *start = text;
3262 char *end, temp[MAX_ENCODED_INT4_LEN+1];
3263 int len; uLong tempB;
3264 while (*start != NUL && Spacing(*start)) start++;
3265 if (*start == NUL) return FALSE;
3266 end = start;
3267 while (*end != NUL && Decimal(*end)) end++;
3268 len = (int) (end - start);
3269 if (len > MAX_ENCODED_INT4_LEN) return FALSE;
3270 strcpyX (temp, start, MINIMUM(len,MAX_ENCODED_INT4_LEN));
3271 if (len < MAX_ENCODED_INT4_LEN) {
3272 if (sscanf(temp,"%ld",&tempB) != 1) return FALSE;
3273 }
3274 else {
3275 if (strcmp(temp,"4294967295") > 0) return FALSE;
3276 if (sscanf(&temp[1],"%ld",&tempB) != 1) return FALSE;
3277 #if defined(dos)
3278 tempB += (1000000000UL * (temp[0] - '0'));
3279 #else
3280 tempB += ((uLong) 1000000000 * (temp[0] - '0'));
3281 #endif
3282 }
3283 *binary = (uInt32) tempB;
3284 return TRUE;
3285 }
3286
3287 /******************************************************************************
3288 * EqStringsIgLTws.
3289 * Compares two strings ignoring leading and trailing white space.
3290 ******************************************************************************/
3291
EqStringsIgLTws(string1,string2)3292 static Logical EqStringsIgLTws (string1, string2)
3293 char *string1;
3294 char *string2;
3295 {
3296 char *tString1, *tString2, *ptr;
3297 size_t nChars;
3298 Logical returnValue;
3299 /****************************************************************************
3300 * Strip leading and trailing white space from 1st string.
3301 ****************************************************************************/
3302 ptr = string1;
3303 while (*ptr != NUL && Spacing(*ptr)) ptr++;
3304 nChars = strlen (ptr);
3305 tString1 = (char *) cdf_AllocateMemory (nChars + 1, FatalError);
3306 strcpyX (tString1, ptr, 0);
3307 ptr = tString1 + nChars;
3308 while (ptr != tString1 && Spacing(*(ptr-1))) ptr--;
3309 *ptr = NUL;
3310 /****************************************************************************
3311 * Strip leading and trailing white space from 2nd string.
3312 ****************************************************************************/
3313 ptr = string2;
3314 while (*ptr != NUL && Spacing(*ptr)) ptr++;
3315 nChars = strlen (ptr);
3316 tString2 = (char *) cdf_AllocateMemory (nChars + 1, FatalError);
3317 strcpyX (tString2, ptr, 0);
3318 ptr = tString2 + nChars;
3319 while (ptr != tString2 && Spacing(*(ptr-1))) ptr--;
3320 *ptr = NUL;
3321 /****************************************************************************
3322 * Free temporary strings and return result of comparison.
3323 ****************************************************************************/
3324 returnValue = (!strcmp(tString1,tString2) ? TRUE : FALSE);
3325 cdf_FreeMemory (tString1, FatalError);
3326 cdf_FreeMemory (tString2, FatalError);
3327 return returnValue;
3328 }
3329
3330 /******************************************************************************
3331 * LongWidth.
3332 ******************************************************************************/
3333
LongWidth(value)3334 int LongWidth (value)
3335 long value;
3336 {
3337 if (value < -999999999L) return 11;
3338 if (value < -99999999L) return 10;
3339 if (value < -9999999L) return 9;
3340 if (value < -999999L) return 8;
3341 if (value < -99999L) return 7;
3342 if (value < -9999L) return 6;
3343 if (value < -999L) return 5;
3344 if (value < -99L) return 4;
3345 if (value < -9L) return 3;
3346 if (value < 0L) return 2;
3347 if (value < 10L) return 1;
3348 if (value < 100L) return 2;
3349 if (value < 1000L) return 3;
3350 if (value < 10000L) return 4;
3351 if (value < 100000L) return 5;
3352 if (value < 1000000L) return 6;
3353 if (value < 10000000L) return 7;
3354 if (value < 100000000L) return 8;
3355 if (value < 1000000000L) return 9;
3356 return 10;
3357 }
3358
3359 /******************************************************************************
3360 * Long64Width.
3361 ******************************************************************************/
3362
Long64Width(value)3363 int Long64Width (value)
3364 OFF_T value;
3365 {
3366 #if !defined(win32) && !defined(__osf__)
3367 if (value < (OFF_T) -999999999999999999LL) return 20;
3368 if (value < (OFF_T) -99999999999999999LL) return 19;
3369 if (value < (OFF_T) -9999999999999999LL) return 18;
3370 if (value < (OFF_T) -999999999999999LL) return 17;
3371 if (value < (OFF_T) -99999999999999LL) return 16;
3372 if (value < (OFF_T) -9999999999999LL) return 15;
3373 if (value < (OFF_T) -999999999999LL) return 14;
3374 if (value < (OFF_T) -99999999999LL) return 13;
3375 if (value < (OFF_T) -9999999999LL) return 12;
3376 if (value < (OFF_T) -999999999LL) return 11;
3377 if (value < (OFF_T) -99999999LL) return 10;
3378 if (value < (OFF_T) -9999999LL) return 9;
3379 if (value < (OFF_T) -999999LL) return 8;
3380 if (value < (OFF_T) -99999LL) return 7;
3381 if (value < (OFF_T) -9999LL) return 6;
3382 if (value < (OFF_T) -999LL) return 5;
3383 if (value < (OFF_T) -99LL) return 4;
3384 if (value < (OFF_T) -9LL) return 3;
3385 if (value < (OFF_T) 0LL) return 2;
3386 if (value < (OFF_T) 10LL) return 1;
3387 if (value < (OFF_T) 100LL) return 2;
3388 if (value < (OFF_T) 1000LL) return 3;
3389 if (value < (OFF_T) 10000LL) return 4;
3390 if (value < (OFF_T) 100000LL) return 5;
3391 if (value < (OFF_T) 1000000LL) return 6;
3392 if (value < (OFF_T) 10000000LL) return 7;
3393 if (value < (OFF_T) 100000000LL) return 8;
3394 if (value < (OFF_T) 1000000000LL) return 9;
3395 if (value < (OFF_T) 10000000000LL) return 10;
3396 if (value < (OFF_T) 100000000000LL) return 11;
3397 if (value < (OFF_T) 1000000000000LL) return 12;
3398 if (value < (OFF_T) 10000000000000LL) return 13;
3399 if (value < (OFF_T) 100000000000000LL) return 14;
3400 if (value < (OFF_T) 1000000000000000LL) return 15;
3401 if (value < (OFF_T) 10000000000000000LL) return 16;
3402 if (value < (OFF_T) 100000000000000000LL) return 17;
3403 if (value < (OFF_T) 1000000000000000000LL) return 18;
3404 #else
3405 if (value < (OFF_T) -999999999999999999L) return 20;
3406 if (value < (OFF_T) -99999999999999999L) return 19;
3407 if (value < (OFF_T) -9999999999999999L) return 18;
3408 if (value < (OFF_T) -999999999999999L) return 17;
3409 if (value < (OFF_T) -99999999999999L) return 16;
3410 if (value < (OFF_T) -9999999999999L) return 15;
3411 if (value < (OFF_T) -999999999999L) return 14;
3412 if (value < (OFF_T) -99999999999L) return 13;
3413 if (value < (OFF_T) -9999999999L) return 12;
3414 if (value < (OFF_T) -999999999L) return 11;
3415 if (value < (OFF_T) -99999999L) return 10;
3416 if (value < (OFF_T) -9999999L) return 9;
3417 if (value < (OFF_T) -999999L) return 8;
3418 if (value < (OFF_T) -99999L) return 7;
3419 if (value < (OFF_T) -9999L) return 6;
3420 if (value < (OFF_T) -999L) return 5;
3421 if (value < (OFF_T) -99L) return 4;
3422 if (value < (OFF_T) -9L) return 3;
3423 if (value < (OFF_T) 0L) return 2;
3424 if (value < (OFF_T) 10L) return 1;
3425 if (value < (OFF_T) 100L) return 2;
3426 if (value < (OFF_T) 1000L) return 3;
3427 if (value < (OFF_T) 10000L) return 4;
3428 if (value < (OFF_T) 100000L) return 5;
3429 if (value < (OFF_T) 1000000L) return 6;
3430 if (value < (OFF_T) 10000000L) return 7;
3431 if (value < (OFF_T) 100000000L) return 8;
3432 if (value < (OFF_T) 1000000000L) return 9;
3433 if (value < (OFF_T) 10000000000L) return 10;
3434 if (value < (OFF_T) 100000000000L) return 11;
3435 if (value < (OFF_T) 1000000000000L) return 12;
3436 if (value < (OFF_T) 10000000000000L) return 13;
3437 if (value < (OFF_T) 100000000000000L) return 14;
3438 if (value < (OFF_T) 1000000000000000L) return 15;
3439 if (value < (OFF_T) 10000000000000000L) return 16;
3440 if (value < (OFF_T) 100000000000000000L) return 17;
3441 if (value < (OFF_T) 1000000000000000000L) return 18;
3442 #endif
3443 return 19;
3444 }
3445
3446 /******************************************************************************
3447 * ParseCacheSizes.
3448 * It can be assumed that there is at least one character in `sizes' or QOP
3449 * would have failed.
3450 ******************************************************************************/
3451
ParseCacheSizes(sizes,workingCache,stageCache,compressCache)3452 Logical ParseCacheSizes (sizes, workingCache, stageCache, compressCache)
3453 char *sizes;
3454 long *workingCache;
3455 long *stageCache;
3456 long *compressCache;
3457 {
3458 char *p, *size, tmp[MAX_CACHESIZES_LEN+1];
3459 /****************************************************************************
3460 * Initialize all cache sizes in case only some have been specified.
3461 ****************************************************************************/
3462 *workingCache = useDEFAULTcacheSIZE;
3463 *stageCache = useDEFAULTcacheSIZE;
3464 *compressCache = useDEFAULTcacheSIZE;
3465 /****************************************************************************
3466 * Move cache sizes to a temporary buffer and remove all spacing.
3467 ****************************************************************************/
3468 strcpyX (tmp, sizes, MAX_CACHESIZES_LEN);
3469 RemoveWhiteSpace (tmp);
3470 p = tmp;
3471 /****************************************************************************
3472 * Check for (and skip) parenthesis on VMS systems.
3473 ****************************************************************************/
3474 #if defined(vms)
3475 if (*p == '(') {
3476 char *lastChar = p + strlen(p) - 1;
3477 if (*lastChar != ')') return FALSE;
3478 p++;
3479 *lastChar = NUL;
3480 }
3481 #endif
3482 /****************************************************************************
3483 * Scan the list of cache sizes...
3484 ****************************************************************************/
3485 for (;;) {
3486 /*************************************************************************
3487 * Save the location of the size and increment to the next non-decimal
3488 * character (ie. past the size).
3489 *************************************************************************/
3490 size = p;
3491 while (Decimal(*p)) p++;
3492 /*************************************************************************
3493 * Based on the non-decimal character reached...
3494 *************************************************************************/
3495 switch (*p) {
3496 case 's':
3497 if (sscanf(size,"%lds",stageCache) != 1) return FALSE;
3498 break;
3499 case 'c':
3500 if (sscanf(size,"%ldc",compressCache) != 1) return FALSE;
3501 break;
3502 case 'd':
3503 if (sscanf(size,"%ldd,",workingCache) != 1) return FALSE;
3504 break;
3505 case ',':
3506 if (sscanf(size,"%ld,",workingCache) != 1) return FALSE;
3507 break;
3508 case NUL:
3509 if (sscanf(size,"%ld",workingCache) != 1) return FALSE;
3510 return TRUE;
3511 default:
3512 return FALSE;
3513 }
3514 /*************************************************************************
3515 * Increment to the beginning of the next cache size (or to the end of the
3516 * sizes).
3517 *************************************************************************/
3518 if (*p != ',') p++;
3519 if (*p == ',') p++;
3520 if (*p == NUL) return TRUE;
3521 }
3522 }
3523
3524 /******************************************************************************
3525 * Remove the ".skt" file extension from the given file name if it's there.
3526 * It ignores the case.
3527 * Example:
3528 * mydata.skt => mydata
3529 ******************************************************************************/
3530
RemoveCDFSktExtension(sktName,sktPath)3531 void RemoveCDFSktExtension (sktName, sktPath)
3532 char *sktName; /* CDF skeleton table file name. */
3533 char *sktPath; /* The string holding file name without extension. */
3534 {
3535 int ptr = -1;
3536
3537 strcpyX (sktPath, sktName, CDF_PATHNAME_LEN);
3538 if (EndsWithIgCase (sktPath, ".skt")) {
3539 ptr = StrLaststrIgCase(sktPath, ".skt");
3540 if (ptr != -1) ((char *) sktPath)[ptr] = (char) '\0';
3541 }
3542 return;
3543 }
3544
3545 /******************************************************************************
3546 * GetNumTokens.
3547 ******************************************************************************/
3548
GetNumTokens(token,string)3549 int GetNumTokens (token, string)
3550 int token;
3551 char *string;
3552 {
3553 int count = 0;
3554 char *temp1, *temp2;
3555 char *ptr1, terminator;
3556 /****************************************************************************
3557 * Check that the entered list of tokens is not a NUL string, that there are
3558 * some possible tokens to match, etc.
3559 ****************************************************************************/
3560 if (NULstring(string)) {
3561 return 0; /* Obviously, no tokens were found. */
3562 }
3563 /****************************************************************************
3564 * Scan the entered string of tokens searching for matches with the token.
3565 * First determine the starting character position and the * ending delimiter.
3566 ****************************************************************************/
3567 switch (string[0]) {
3568 case '(': /* VMS-style. */
3569 terminator = ')';
3570 ptr1 = string + 1;
3571 break;
3572 case '"': /* UNIX-style on a Mac (double quotes not stripped). */
3573 terminator = '"';
3574 ptr1 = string + 1;
3575 break;
3576 default: /* UNIX-style on a UNIX machine or IBM PC. */
3577 terminator = NUL;
3578 ptr1 = string;
3579 break;
3580 }
3581 temp1 = ptr1;
3582 temp2 = ptr1 + strlen(ptr1) - 1;
3583 while (temp1 <= temp2) {
3584 if ((int) *temp1 == token) count++;
3585 temp1++;
3586 }
3587 count++;
3588 return count;
3589 }
3590
3591 /******************************************************************************
3592 * ParseStringForTokens.
3593 ******************************************************************************/
3594
ParseStringForTokens(token,string,items)3595 void ParseStringForTokens (token, string, items)
3596 int token;
3597 char *string;
3598 char *items[];
3599 {
3600 int tokenN; size_t tokenLen;
3601 char *ptr1, *ptr2, terminator;
3602 /****************************************************************************
3603 * Check that the entered list of tokens is not a NUL string, that there are
3604 * some possible tokens to match, etc.
3605 ****************************************************************************/
3606 if (NULstring(string)) {
3607 return; /* Obviously, no tokens were found. */
3608 }
3609 /****************************************************************************
3610 * Scan the entered string of tokens searching for matches with the token.
3611 * First determine the starting character position and the * ending delimiter.
3612 ****************************************************************************/
3613 switch (string[0]) {
3614 case '(': /* VMS-style. */
3615 terminator = ')';
3616 ptr1 = string + 1;
3617 break;
3618 case '"': /* UNIX-style on a Mac (double quotes not stripped). */
3619 terminator = '"';
3620 ptr1 = string + 1;
3621 break;
3622 default: /* UNIX-style on a UNIX machine or IBM PC. */
3623 terminator = NUL;
3624 ptr1 = string;
3625 break;
3626 }
3627 tokenN = 0;
3628 for (;;) {
3629 /*************************************************************************
3630 * Find beginning of the next token in list (skipping past any leading
3631 * blanks). If the end of the list is reached instead, then there are
3632 * no more tokens.
3633 *************************************************************************/
3634 while (*ptr1 == ' ') ptr1++;
3635 if (*ptr1 == terminator) return;
3636 /*************************************************************************
3637 * Find the end of the token and copy. The token is ended by either a
3638 * blank, comma, or the terminator.
3639 *************************************************************************/
3640 ptr2 = ptr1 + 1;
3641 while ((int) *ptr2 != token && *ptr2 != terminator) ptr2++;
3642 tokenLen = (size_t) (ptr2 - ptr1);
3643 strcpyX (items[tokenN], ptr1, tokenLen);
3644 tokenN++;
3645 /*************************************************************************
3646 * Setup to search for next token in list.
3647 *************************************************************************/
3648 if ((int) *ptr2 == token)
3649 /*********************************************************************
3650 * The last token was ended by a comma. The next token begins one
3651 * character beyond the comma.
3652 *********************************************************************/
3653 ptr1 = ptr2 + 1;
3654 else
3655 /*********************************************************************
3656 * The terminator must have ended the last token.
3657 *********************************************************************/
3658 return;
3659 }
3660 }
3661
3662
3663