1 /******************************************************************************
2 *
3 * NSSDC/CDF CDFexport/1.
4 *
5 * Version 1.2b, 21-Feb-97, Hughes STX.
6 *
7 * Modification history:
8 *
9 * V1.0 15-Sep-95, J Love Original version.
10 * V1.0a 18-Sep-95, J Love Macintosh event handling.
11 * V1.1 26-Aug-96, J Love CDF V2.6.
12 * V1.2 15-Nov-96, J Love Added `simple' mode.
13 * V1.2a 15-Jan-97, J Love Added attribute entries to beginning of text
14 * file listings.
15 * V1.2b 21-Feb-97, J Love Removed RICE.
16 *
17 ******************************************************************************/
18
19 #include "cdfxp.h"
20
21 /******************************************************************************
22 * Error messages.
23 ******************************************************************************/
24
25 static char listOpenError[] = "Error opening listing file.";
26 static char listWriteError[] = "Error writing to listing file.";
27 static char listCloseError[] = "Error closing listing file.";
28
29 /******************************************************************************
30 * Function prototypes.
31 ******************************************************************************/
32
33 char *StandardFormat PROTOARGs((long dataType));
34 int StandardWidth PROTOARGs((long dataType, long numElems));
35
36 /******************************************************************************
37 * ToScreenHori.
38 * Output to ASCII/screen, horizontal listing.
39 * Returns FALSE if a fatal CDF error occurred (meaning NO_MORE_ACCESS).
40 ******************************************************************************/
41
ToScreenHori()42 Logical ToScreenHori () {
43 AOSs1 (header, BLANKs78)
44 static char screenLines[SCREENtextMAX+1];
45 static char line[] = { BLANKs78 };
46 AOSs1A (keyDefsPrompt, "More: ________ Exit: ________ Help: ________ Continuous: ________")
47 AOSs1B (keyDefsEnd, "End of listing. Hit ________ to continue.")
48 AOSs1C (keyDefsLoading, "Loading lines. Use ________ to abort.")
49 AOSs1D (keyDefsCruise, "Continuous. Use ________ to stop.")
50 static char *keyDefsAborting[1] = { "Aborting at user's request." };
51 static char *keyDefsInitial[1] = { "Loading..." };
52 static int exitKeys[] = { NUL };
53 static struct EditWindowStruct EWscr = {
54 " Screen Listing ", 0, 0, SCREEN_WIDTH, 1, header, screenLines,
55 NUMscreenLINES, 1, NULL, FALSE, TRUE, exitKeys, REFRESHkey_FSI, NUL, NUL,
56 NUL, NUL, NUL, NUL, NUL, NUL, NUL
57 };
58 int lineN, totalWidth = 0, noRoom = 0, filterStatus, addL, key;
59 int lineL = SCREEN_WIDTH - 2; long firstRec, lastRec, recN, nRecs;
60 static Logical first = TRUE; Logical prompt = TRUE;
61 double timeMark; CDFstatus status; struct ItemStruct *Item, *exportHead;
62 /****************************************************************************
63 * Encode key definitions first time.
64 ****************************************************************************/
65 if (first) {
66 EncodeKeyDefinitions (1, keyDefsPrompt, ENTERkey_FSI, EXITkey_FSI,
67 HELPkey_FSI, CRUISEkey_EXPORT);
68 EncodeKeyDefinitions (1, keyDefsEnd, ENTERkey_FSI);
69 EncodeKeyDefinitions (1, keyDefsCruise, ABORTkey_EXPORT);
70 EncodeKeyDefinitions (1, keyDefsLoading, ABORTkey_EXPORT);
71 first = FALSE;
72 }
73 /****************************************************************************
74 * Build export list.
75 ****************************************************************************/
76 BuildExportList (&exportHead, LogicalFALSE);
77 /****************************************************************************
78 * Validate `Record' and `Indices' selections.
79 ****************************************************************************/
80 ValidateRecordIndices (OUTPUTtoSCREENh, FALSE, 0L, exportHead);
81 /****************************************************************************
82 * Check for enough room for each exported item and calculate the maximum
83 * record number.
84 ****************************************************************************/
85 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
86 if (Item->output) {
87 /***********************************************************************
88 * Determine if enough room.
89 ***********************************************************************/
90 addL = BOO(totalWidth == 0,0,opt.spacing);
91 switch (Item->type) {
92 case RECORDt:
93 addL += Item->width;
94 break;
95 case VARIABLEt:
96 addL += (int) ((Item->Var->nRecordValues * Item->width) +
97 (opt.spacing * (Item->Var->nRecordValues - 1)));
98 break;
99 }
100 if (totalWidth + addL <= lineL) {
101 totalWidth += addL;
102 continue;
103 }
104 /***********************************************************************
105 * Not enough room.
106 ***********************************************************************/
107 noRoom++;
108 Item->output = FALSE;
109 }
110 }
111 /****************************************************************************
112 * Display message if some items could not be listed.
113 ****************************************************************************/
114 if (noRoom > 0) {
115 char msg[SCREEN_WIDTH+1];
116 sprintf (msg, "Not enough room for %d item%s.",
117 noRoom, BOO(noRoom == 1,"","s"));
118 DisplayMessage (msg, NOBEEPWAIT1);
119 }
120 /****************************************************************************
121 * Check if a valid listing.
122 ****************************************************************************/
123 if (totalWidth == 0) {
124 DisplayMessage ("Nothing selected for listing.", BEEPWAIT1);
125 return TRUE;
126 }
127 /****************************************************************************
128 * Determine first/last records.
129 ****************************************************************************/
130 switch (FirstLastRecord(&firstRec,&lastRec,FALSE,exportHead)) {
131 case PASSED: break;
132 case FAILED: return TRUE;
133 case FATAL: return FALSE;
134 }
135 /****************************************************************************
136 * Remove items from the export list that are not being output or filtered.
137 ****************************************************************************/
138 RemoveExportItems (&exportHead);
139 /****************************************************************************
140 * Initialize header.
141 ****************************************************************************/
142 MakeNUL (header[0]);
143 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
144 if (Item->output) {
145 if (!NULstring(header[0])) CatNcharacters (header[0],opt.spacing,' ');
146 switch (Item->type) {
147 case RECORDt:
148 CatToString (header[0], "Record", Item->width, LEFT_JUSTIFY, "*");
149 break;
150 case VARIABLEt: {
151 int varWidth = (int) ((Item->Var->nRecordValues * Item->width) +
152 (opt.spacing * (Item->Var->nRecordValues-1)));
153 CatToString (header[0], Item->Var->name, varWidth, CENTER_JUSTIFY,
154 "*");
155 break;
156 }
157 }
158 }
159 }
160 /****************************************************************************
161 * Initialize listing lines.
162 ****************************************************************************/
163 MakeNUL (screenLines);
164 lineN = 0;
165 /****************************************************************************
166 * Display listing window.
167 ****************************************************************************/
168 EWscr.tLines = keyDefsInitial;
169 EditWindow (NEWew, &EWscr, LogicalTRUE);
170 nRecs = lastRec - firstRec + 1;
171 timeMark = SystemClock ();
172 /****************************************************************************
173 * Read values until end of listing or user requests an early exit.
174 ****************************************************************************/
175 for (recN = firstRec; recN <= lastRec; recN++) {
176 /*************************************************************************
177 * Check if the abort key has been entered.
178 *************************************************************************/
179 if (read_input(
180 #if defined(CURSESui)
181 EWscr.wid,
182 #endif
183 &key,PASSTHRUri,FALSE)) {
184 if (key == ABORTkey_EXPORT) {
185 if (prompt) {
186 EWscr.tLines = keyDefsAborting;
187 EditWindow (UPDATEew, &EWscr, LogicalTRUE);
188 zzzzz (1.0);
189 EditWindow (DELETEew, &EWscr, TRUE);
190 return TRUE;
191 }
192 else
193 prompt = TRUE;
194 }
195 else
196 EditWindow (BEEPew, &EWscr);
197 }
198 /*************************************************************************
199 * Should `loading' message be displayed?
200 *************************************************************************/
201 if (SystemClock() - timeMark > 1.0) {
202 UpdateToScreen (&EWscr, keyDefsLoading[0], recN, nRecs);
203 timeMark = SystemClock ();
204 }
205 /*************************************************************************
206 * Encode line.
207 *************************************************************************/
208 status = EncodeLineHori(line,recN,&filterStatus,exportHead,FALSE);
209 if (StatusBAD(status)) {
210 char text[CDF_STATUSTEXT_LEN+1];
211 CDFlib (SELECT_, CDF_STATUS_, status,
212 GET_, STATUS_TEXT_, text,
213 NULL_);
214 InfoWindow ("An error occurred while reading the CDF.", text, NULL,
215 TRUE, TRUE, 0);
216 EditWindow (DELETEew, &EWscr, TRUE);
217 return FALSE;
218 }
219 /*************************************************************************
220 * Check if line should be added to display.
221 *************************************************************************/
222 if (SHOWline(filterStatus)) {
223 if (lineN == NUMscreenLINES) {
224 Logical loop = TRUE;
225 UpdateToScreen (&EWscr, BOO(prompt,keyDefsPrompt[0],keyDefsCruise[0]),
226 recN, nRecs);
227 if (prompt)
228 EditWindow (READew, &EWscr);
229 else
230 EWscr.key = ENTERkey_FSI;
231 while (loop) {
232 switch (EWscr.key) {
233 case CRUISEkey_EXPORT:
234 prompt = FALSE; /* No `break' is intentional. */
235 case ENTERkey_FSI:
236 MakeNUL (screenLines);
237 lineN = 0;
238 loop = FALSE;
239 break;
240 case HELPkey_FSI:
241 OnlineHelpWindow ("cdfxp.ilh", SCREENhelpID);
242 EditWindow (READew, &EWscr);
243 break;
244 case EXITkey_FSI:
245 EditWindow (DELETEew, &EWscr, TRUE);
246 return TRUE;
247 default:
248 EditWindow (BEEPew, &EWscr);
249 EditWindow (READew, &EWscr);
250 break;
251 }
252 }
253 timeMark = SystemClock ();
254 }
255 strcatX (screenLines, line, SCREENtextMAX);
256 strcatX (screenLines, "\n", SCREENtextMAX);
257 lineN++;
258 }
259 }
260 /****************************************************************************
261 * End of listing.
262 ****************************************************************************/
263 EWscr.tLines = keyDefsEnd;
264 EditWindow (UPDATEew, &EWscr, LogicalTRUE);
265 EditWindow (READew, &EWscr);
266 EditWindow (DELETEew, &EWscr, TRUE);
267 return TRUE;
268 }
269
270 /******************************************************************************
271 * ToFileHori.
272 * Output to ASCII/file, horizontal listing.
273 * Returns FALSE if a fatal CDF error occurred (meaning NO_MORE_ACCESS).
274 ******************************************************************************/
275
ToFileHori()276 Logical ToFileHori () {
277 long addL, lineL = 0; int filterStatus;
278 char *line; long firstRec, lastRec, recN, nRecs;
279 struct ItemStruct *Item, *exportHead; FILE *oFp;
280 CDFstatus status; Logical first = TRUE, cdfFatal;
281 static char pctMsg[] = "Listing started...";
282 static char keyDefsBlank[] = "\n\n";
283 static char keyDefsAbort[] = "Abort: ________\n\n";
284 /****************************************************************************
285 * Encode key definitions first time.
286 ****************************************************************************/
287 if (first) {
288 char *p1 = keyDefsAbort;
289 EncodeKeyDefinitions (1, &p1, ABORTkey_EXPORT);
290 first = FALSE;
291 }
292 /****************************************************************************
293 * Build export list.
294 ****************************************************************************/
295 BuildExportList (&exportHead, LogicalFALSE);
296 /****************************************************************************
297 * Validate `Record' and `Indices' selections.
298 ****************************************************************************/
299 ValidateRecordIndices (OUTPUTtoFILEh, FALSE, 0L, exportHead);
300 /****************************************************************************
301 * Calculate the width of each line and the maximum record number.
302 ****************************************************************************/
303 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
304 if (Item->output) {
305 /***********************************************************************
306 * Add to total width.
307 ***********************************************************************/
308 addL = BOO(lineL == 0,0,opt.spacing);
309 switch (Item->type) {
310 case RECORDt:
311 addL += Item->width;
312 break;
313 case VARIABLEt: {
314 int width = BOO(simpleMode,
315 StandardWidth(Item->Var->dataType,
316 Item->Var->numElems),Item->width);
317 addL += (Item->Var->nRecordValues * width) +
318 (opt.spacing * (Item->Var->nRecordValues - 1));
319 break;
320 }
321 }
322 lineL += addL;
323 }
324 }
325 /****************************************************************************
326 * Check if a valid listing.
327 ****************************************************************************/
328 if (lineL == 0) {
329 DisplayMessage ("Nothing selected for listing.", BEEPWAIT1);
330 return TRUE;
331 }
332 /****************************************************************************
333 * Determine first/last records.
334 ****************************************************************************/
335 switch (FirstLastRecord(&firstRec,&lastRec,FALSE,exportHead)) {
336 case PASSED: break;
337 case FAILED: return TRUE;
338 case FATAL: return FALSE;
339 }
340 /****************************************************************************
341 * Remove items from the export list that are not being output or filtered.
342 ****************************************************************************/
343 RemoveExportItems (&exportHead);
344 /****************************************************************************
345 * Allocate buffer for line.
346 ****************************************************************************/
347 #if defined(dos)
348 if (TOObigIBMpc(lineL+1))
349 line = NULL;
350 else
351 #endif
352 line = (char *) cdf_AllocateMemory ((size_t) (lineL+1), NULL);
353 if (line == NULL) {
354 DisplayMessage ("Not enough memory.", BEEPWAIT);
355 return TRUE;
356 }
357 /****************************************************************************
358 * Prompt for listing file path (unless in batch mode) and open file.
359 ****************************************************************************/
360 if (!BATCH(batchMode)) {
361 if (!PromptFor(outputText,DU_MAX_PATH_LEN,strlen(outputText),
362 "Enter path for listing file...",oFILEhelpID)) {
363 cdf_FreeMemory (line, FatalError);
364 return TRUE;
365 }
366 }
367 oFp = fopen (outputText, "w");
368 if (oFp == NULL) {
369 DisplayMessage (listOpenError, BEEPWAIT);
370 cdf_FreeMemory (line, FatalError);
371 return TRUE;
372 }
373 /****************************************************************************
374 * Output header line(s).
375 ****************************************************************************/
376 if (opt.textHeading) {
377 if (!ListAttributes(oFp,&cdfFatal)) {
378 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
379 cdf_FreeMemory (line, FatalError);
380 return (!cdfFatal);
381 }
382 MakeNUL (line);
383 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
384 if (Item->output) {
385 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
386 switch (Item->type) {
387 case RECORDt:
388 CatToString (line, "Record", Item->width, LEFT_JUSTIFY, "*");
389 break;
390 case VARIABLEt: {
391 int standardWidth = StandardWidth(Item->Var->dataType,
392 Item->Var->numElems);
393 int valueWidth = BOO(simpleMode,standardWidth,Item->width);
394 int varWidth = (int) ((Item->Var->nRecordValues*valueWidth) +
395 (opt.spacing*(Item->Var->nRecordValues-1)));
396 CatToString (line, Item->Var->name, varWidth,
397 CENTER_JUSTIFY, "*");
398 break;
399 }
400 }
401 }
402 }
403 if (fprintf(oFp,"\nVariables:\n\n%s\n",line) < 0) {
404 DisplayMessage (listWriteError, BEEPWAIT);
405 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
406 cdf_FreeMemory (line, FatalError);
407 return TRUE;
408 }
409 }
410 /****************************************************************************
411 * Read/output values until end of listing.
412 ****************************************************************************/
413 nRecs = lastRec - firstRec + 1;
414 DisplayPctComplete (NO_PCT, pctMsg);
415 NEWkeyDEFS (EWkey, keyDefsAbort, batchMode)
416 for (recN = firstRec; recN <= lastRec; recN++) {
417 if (AbortListing(oFp,line)) {
418 NEWkeyDEFS (EWkey, keyDefsBlank, batchMode)
419 return TRUE;
420 }
421 status = EncodeLineHori(line,recN,&filterStatus,exportHead,simpleMode);
422 DisplayStatus (status, readingCDF);
423 if (StatusBAD(status)) {
424 if (fprintf(oFp,"Incomplete listing.\n") < 0) {
425 DisplayMessage (listWriteError, BEEPWAIT);
426 }
427 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
428 cdf_FreeMemory (line, FatalError);
429 return FALSE;
430 }
431 if (SHOWline(filterStatus)) {
432 if (fprintf(oFp,"%s\n",line) < 0) {
433 DisplayMessage (listWriteError, BEEPWAIT);
434 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
435 cdf_FreeMemory (line, FatalError);
436 return TRUE;
437 }
438 }
439 DisplayPctComplete (PCT(recN,nRecs,1,1), pctMsg);
440 }
441 /****************************************************************************
442 * End of listing.
443 ****************************************************************************/
444 NEWkeyDEFS (EWkey, keyDefsBlank, batchMode)
445 if (fclose(oFp) == EOF) {
446 DisplayMessage (listCloseError, BEEPWAIT);
447 cdf_FreeMemory (line, FatalError);
448 return TRUE;
449 }
450 cdf_FreeMemory (line, FatalError);
451 if (!BATCH(batchMode)) DisplayMessage ("Complete.", NOBEEPWAIT1);
452 return TRUE;
453 }
454
455 /******************************************************************************
456 * EncodeLineHori.
457 ******************************************************************************/
458
EncodeLineHori(line,recN,filterStatus,exportHead,standard)459 CDFstatus EncodeLineHori (line, recN, filterStatus, exportHead, standard)
460 char *line;
461 long recN;
462 int *filterStatus;
463 struct ItemStruct *exportHead;
464 Logical standard;
465 {
466 struct ItemStruct *Item; Logical failedFilter; CDFstatus pStatus = CDF_OK;
467 Logical outRowMajor = ROWmajor(MAJORITYtoOUT(opt.majority,inMajority));
468 /****************************************************************************
469 * Initialize line and filter status.
470 ****************************************************************************/
471 MakeNUL (line);
472 *filterStatus = PASSes;
473 /****************************************************************************
474 * Encode each exported item.
475 ****************************************************************************/
476 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
477 switch (Item->type) {
478 /***********************************************************************
479 * Record number.
480 ***********************************************************************/
481 case RECORDt: {
482 /*********************************************************************
483 * Check to see if record number passes filter. If the record number
484 * failed the filter...
485 *********************************************************************/
486 failedFilter = RECORDfailedFILTER(Item,recN);
487 if (failedFilter) {
488 if (opt.showFiltered)
489 *filterStatus = SHOWit;
490 else {
491 *filterStatus = FAILrecord;
492 return pStatus;
493 }
494 }
495 /*********************************************************************
496 * Output record number.
497 *********************************************************************/
498 if (Item->output) {
499 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
500 if (failedFilter)
501 CatNcharacters (line, Item->width, '-');
502 else
503 EncodeRecordJustify (EofS(line), recN, -(Item->width));
504 }
505 break;
506 }
507 /***********************************************************************
508 * Variable.
509 ***********************************************************************/
510 case VARIABLEt: {
511 CDFstatus status; int dimN;
512 /*********************************************************************
513 * Select variable, record number, and indices and read value.
514 *********************************************************************/
515 status = CDFlib (SELECT_, BOO(Item->Var->zVar,
516 zVAR_,rVAR_), Item->Var->varN,
517 BOO(Item->Var->zVar,
518 zVAR_RECNUMBER_,
519 rVARs_RECNUMBER_), recN,
520 NULL_);
521 if (!sX(status,&pStatus)) return pStatus;
522 /*********************************************************************
523 * Process each value in the variable record (array).
524 *********************************************************************/
525 for (dimN = 0; dimN < Item->Var->numDims; dimN++) {
526 Item->Var->indices[dimN] = 0;
527 }
528 for (Item->Var->valueN = 0;
529 Item->Var->valueN < Item->Var->nRecordValues;
530 Item->Var->valueN++) {
531 /******************************************************************
532 * Read the next value.
533 ******************************************************************/
534 status = CDFlib (SELECT_, BOO(Item->Var->zVar,
535 zVAR_DIMINDICES_,
536 rVARs_DIMINDICES_),
537 Item->Var->indices,
538 GET_, VAR_DATA(Item->Var->zVar), Item->Var->value,
539 NULL_);
540 if (!sX(status,&pStatus)) return pStatus;
541 /******************************************************************
542 * Filter value. If a scalar value was filtered out...
543 ******************************************************************/
544 failedFilter = VARfailedFILTER(Item,Item->Var->value);
545 if (failedFilter && Item->Var->scalar) {
546 if (opt.showFiltered)
547 *filterStatus = SHOWit;
548 else {
549 *filterStatus = FAILrecord;
550 return pStatus;
551 }
552 }
553 /******************************************************************
554 * Encode value.
555 ******************************************************************/
556 if (Item->output) {
557 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
558 if (failedFilter)
559 CatNcharacters (line, Item->width, '-');
560 else {
561 int standardWidth = StandardWidth(Item->Var->dataType,
562 Item->Var->numElems);
563 int width = BOO(standard,standardWidth,Item->width);
564 char *format = BOO(standard,
565 StandardFormat(Item->Var->dataType),
566 Item->Var->format);
567 EncodeValuesFormat (Item->Var->dataType, Item->Var->numElems,
568 Item->Var->value, EofS(line),
569 format, width, width, opt.epochStyle);
570 }
571 }
572 /******************************************************************
573 * Increment indices.
574 ******************************************************************/
575 if (outRowMajor)
576 INCRindicesROW (Item->Var->numDims, Item->Var->dimSizes,
577 Item->Var->indices);
578 else
579 INCRindicesCOL (Item->Var->numDims, Item->Var->dimSizes,
580 Item->Var->indices);
581 }
582 break;
583 }
584 }
585 }
586 return pStatus;
587 }
588
589 /******************************************************************************
590 * ToScreenVert.
591 * Output to ASCII/screen, vertical listing.
592 * Returns FALSE if a fatal CDF error occurred (meaning NO_MORE_ACCESS).
593 ******************************************************************************/
594
ToScreenVert()595 Logical ToScreenVert () {
596 AOSs1 (header, BLANKs78)
597 static char screenLines[SCREENtextMAX+1];
598 static char line[] = { BLANKs78 };
599 AOSs1A (keyDefsPrompt, "More: ________ Exit: ________ Help: ________ Continuous: ________")
600 AOSs1B (keyDefsEnd, "End of listing. Hit ________ to continue.")
601 AOSs1C (keyDefsLoading, "Loading lines. Use ________ to abort.")
602 AOSs1D (keyDefsCruise, "Continuous. Use ________ to stop.")
603 static char *keyDefsAborting[1] = { "Aborting at user's request." };
604 static char *keyDefsInitial[1] = { "Loading..." };
605 static int exitKeys[] = { NUL };
606 static struct EditWindowStruct EWscr = {
607 " Screen Listing ", 0, 0, SCREEN_WIDTH, 1, header, screenLines,
608 NUMscreenLINES, 1, NULL, FALSE, TRUE, exitKeys, REFRESHkey_FSI, NUL, NUL,
609 NUL, NUL, NUL, NUL, NUL, NUL, NUL
610 };
611 int lineN, totalWidth = 0, filterStatus, noRoom = 0, addL, key;
612 int lineL = SCREEN_WIDTH - 2; double timeMark;
613 struct ItemStruct *Item, *exportHead; CDFstatus status;
614 long firstRec, lastRec, recN, nValues = 0, valueN, numDims, atLine;
615 long dimSizes[CDF_MAX_DIMS], indices[CDF_MAX_DIMS], nLinesTotal;
616 long firstIndices[CDF_MAX_DIMS], lastIndices[CDF_MAX_DIMS];
617 Logical prompt = TRUE, same, sameGt0; static Logical first = TRUE;
618 Logical outRowMajor = ROWmajor(MAJORITYtoOUT(opt.majority,inMajority));
619 /****************************************************************************
620 * Encode key definitions first time.
621 ****************************************************************************/
622 if (first) {
623 EncodeKeyDefinitions (1, keyDefsPrompt, ENTERkey_FSI, EXITkey_FSI,
624 HELPkey_FSI, CRUISEkey_EXPORT);
625 EncodeKeyDefinitions (1, keyDefsEnd, ENTERkey_FSI);
626 EncodeKeyDefinitions (1, keyDefsCruise, ABORTkey_EXPORT);
627 EncodeKeyDefinitions (1, keyDefsLoading, ABORTkey_EXPORT);
628 first = FALSE;
629 }
630 /****************************************************************************
631 * Build export list.
632 ****************************************************************************/
633 BuildExportList (&exportHead, LogicalFALSE);
634 /****************************************************************************
635 * Determine if the dimensionalities are all the same.
636 ****************************************************************************/
637 same = SameDimensionalities (&numDims, dimSizes, exportHead);
638 sameGt0 = (same && numDims > 0);
639 /****************************************************************************
640 * Validate `Record' and `Indices' selections.
641 ****************************************************************************/
642 ValidateRecordIndices (OUTPUTtoSCREENv, same, numDims, exportHead);
643 /****************************************************************************
644 * Check for enough room for each exported item and calculate the maximum
645 * record number and maximum number of values per record (array).
646 ****************************************************************************/
647 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
648 if (Item->output) {
649 /***********************************************************************
650 * Determine if enough room.
651 ***********************************************************************/
652 addL = BOO(totalWidth == 0,0,opt.spacing) + Item->width;
653 if (totalWidth + addL <= lineL) {
654 totalWidth += addL;
655 if (Item->type == VARIABLEt) {
656 nValues = MAXIMUM(nValues,Item->Var->nRecordValues);
657 }
658 continue;
659 }
660 /***********************************************************************
661 * Not enough room.
662 ***********************************************************************/
663 noRoom++;
664 Item->output = FALSE;
665 }
666 }
667 /****************************************************************************
668 * Display message if some items could not be listed.
669 ****************************************************************************/
670 if (noRoom > 0) {
671 char msg[SCREEN_WIDTH+1];
672 sprintf (msg, "Not enough room for %d item%s.",
673 noRoom, BOO(noRoom == 1,"","s"));
674 DisplayMessage (msg, NOBEEPWAIT1);
675 }
676 /****************************************************************************
677 * Check if a valid listing.
678 ****************************************************************************/
679 if (totalWidth == 0) {
680 DisplayMessage ("Nothing selected for listing.", BEEPWAIT1);
681 return TRUE;
682 }
683 /****************************************************************************
684 * Determine first/last record/indices.
685 ****************************************************************************/
686 switch (FirstLastRecord(&firstRec,&lastRec,FALSE,exportHead)) {
687 case PASSED: break;
688 case FAILED: return TRUE;
689 case FATAL: return FALSE;
690 }
691 if (sameGt0) {
692 switch (FirstLastIndices(numDims,dimSizes,firstIndices,
693 lastIndices,&nValues,FALSE,exportHead)) {
694 case PASSED: break;
695 case FAILED: return TRUE;
696 case FATAL: return FALSE;
697 }
698 }
699 /****************************************************************************
700 * Remove items from the export list that are not being output or filtered.
701 ****************************************************************************/
702 RemoveExportItems (&exportHead);
703 /****************************************************************************
704 * Initialize header.
705 ****************************************************************************/
706 MakeNUL (header[0]);
707 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
708 if (Item->output) {
709 if (!NULstring(header[0])) CatNcharacters (header[0],opt.spacing,' ');
710 switch (Item->type) {
711 case RECORDt:
712 CatToString (header[0], "Record", Item->width, LEFT_JUSTIFY, "*");
713 break;
714 case INDICESt:
715 CatToString (header[0], "Indices", Item->width, LEFT_JUSTIFY, "*");
716 break;
717 case VARIABLEt:
718 CatToString (header[0], Item->Var->name, Item->width,
719 CENTER_JUSTIFY, "*");
720 break;
721 }
722 }
723 }
724 /****************************************************************************
725 * Initialize listing lines and display listing window.
726 ****************************************************************************/
727 MakeNUL (screenLines);
728 lineN = 0;
729 EWscr.tLines = keyDefsInitial;
730 EditWindow (NEWew, &EWscr, LogicalTRUE);
731 nLinesTotal = (lastRec - firstRec + 1) * nValues;
732 timeMark = SystemClock ();
733 /****************************************************************************
734 * Read/list values until end of listing or user requests an early exit.
735 ****************************************************************************/
736 for (recN = firstRec, atLine = 0; recN <= lastRec; recN++) {
737 /*************************************************************************
738 * If same dimensionalities, initialize indices.
739 *************************************************************************/
740 if (sameGt0) {
741 ARRAYtoARRAY (indices, firstIndices, numDims)
742 }
743 /*************************************************************************
744 * For each value...
745 *************************************************************************/
746 for (valueN = 0; valueN < nValues; valueN++) {
747 /**********************************************************************
748 * Check if the abort key has been entered.
749 **********************************************************************/
750 if (read_input(
751 #if defined(CURSESui)
752 EWscr.wid,
753 #endif
754 &key,PASSTHRUri,FALSE)) {
755 if (key == ABORTkey_EXPORT) {
756 if (prompt) {
757 EWscr.tLines = keyDefsAborting;
758 EditWindow (UPDATEew, &EWscr, LogicalTRUE);
759 zzzzz (1.0);
760 EditWindow (DELETEew, &EWscr, TRUE);
761 return TRUE;
762 }
763 else
764 prompt = TRUE;
765 }
766 else
767 EditWindow (BEEPew, &EWscr);
768 }
769 /**********************************************************************
770 * Should `loading' message be displayed?
771 **********************************************************************/
772 if (SystemClock() - timeMark > 1.0) {
773 UpdateToScreen (&EWscr, keyDefsLoading[0], atLine, nLinesTotal);
774 timeMark = SystemClock ();
775 }
776 /**********************************************************************
777 * Encode line.
778 **********************************************************************/
779 status = EncodeLineVert(line,recN,valueN,numDims,indices,
780 same,&filterStatus,exportHead,
781 outRowMajor,FALSE);
782 if (StatusBAD(status)) {
783 char text[CDF_STATUSTEXT_LEN+1];
784 CDFlib (SELECT_, CDF_STATUS_, status,
785 GET_, STATUS_TEXT_, text,
786 NULL_);
787 InfoWindow ("An error occurred while reading the CDF.", text, NULL,
788 TRUE, TRUE, 0);
789 EditWindow (DELETEew, &EWscr, TRUE);
790 return FALSE;
791 }
792 /**********************************************************************
793 * Check filter status to see if the line should be added to the screen.
794 **********************************************************************/
795 if (SHOWline(filterStatus)) {
796 if (lineN == NUMscreenLINES) {
797 Logical loop = TRUE;
798 UpdateToScreen (&EWscr, BOO(prompt,keyDefsPrompt[0],
799 keyDefsCruise[0]),
800 atLine, nLinesTotal);
801 if (prompt)
802 EditWindow (READew, &EWscr);
803 else
804 EWscr.key = ENTERkey_FSI;
805 while (loop) {
806 switch (EWscr.key) {
807 case CRUISEkey_EXPORT:
808 prompt = FALSE; /* No `break' is intentional. */
809 case ENTERkey_FSI:
810 MakeNUL (screenLines);
811 lineN = 0;
812 loop = FALSE;
813 break;
814 case HELPkey_FSI:
815 OnlineHelpWindow ("cdfxp.ilh", SCREENhelpID);
816 EditWindow (READew, &EWscr);
817 break;
818 case EXITkey_FSI:
819 EditWindow (DELETEew, &EWscr, TRUE);
820 return TRUE;
821 default:
822 EditWindow (BEEPew, &EWscr);
823 EditWindow (READew, &EWscr);
824 break;
825 }
826 }
827 timeMark = SystemClock ();
828 }
829 strcatX (screenLines, line, SCREENtextMAX);
830 strcatX (screenLines, "\n", SCREENtextMAX);
831 lineN++;
832 }
833 /**********************************************************************
834 * Check filter status to see if this record should be aborted.
835 **********************************************************************/
836 if (filterStatus == FAILrecord) {
837 atLine += nValues;
838 break;
839 }
840 /**********************************************************************
841 * If same dimensionalities, increment indices.
842 **********************************************************************/
843 if (sameGt0) {
844 if (outRowMajor)
845 IncrIndicesFirstLastRow (numDims, firstIndices,
846 lastIndices, indices);
847 else
848 IncrIndicesFirstLastCol (numDims, firstIndices,
849 lastIndices, indices);
850 }
851 /**********************************************************************
852 * Increment percentage counter.
853 **********************************************************************/
854 atLine++;
855 }
856 }
857 /****************************************************************************
858 * End of listing.
859 ****************************************************************************/
860 EWscr.tLines = keyDefsEnd;
861 EditWindow (UPDATEew, &EWscr, LogicalTRUE);
862 EditWindow (READew, &EWscr);
863 EditWindow (DELETEew, &EWscr, TRUE);
864 return TRUE;
865 }
866
867 /******************************************************************************
868 * ToFileVert.
869 * Output to ASCII/file, vertical listing.
870 * Returns FALSE if a fatal CDF error occurred (meaning NO_MORE_ACCESS).
871 ******************************************************************************/
872
ToFileVert()873 Logical ToFileVert () {
874 int lineL = 0, filterStatus;
875 struct ItemStruct *Item, *exportHead; FILE *oFp; char *line;
876 long firstRec, lastRec, recN, maxRecordValues = 0, valueN, numDims;
877 long dimSizes[CDF_MAX_DIMS], nLinesTotal, atLine;
878 long indices[CDF_MAX_DIMS], firstIndices[CDF_MAX_DIMS];
879 long lastIndices[CDF_MAX_DIMS]; Logical same, sameGt0;
880 Logical outRowMajor = ROWmajor(MAJORITYtoOUT(opt.majority,inMajority));
881 CDFstatus status; Logical first = TRUE, cdfFatal;
882 static char pctMsg[] = "Listing started...";
883 static char keyDefsBlank[] = "\n\n";
884 static char keyDefsAbort[] = "Abort: ________\n\n";
885 /****************************************************************************
886 * Encode key definitions first time.
887 ****************************************************************************/
888 if (first) {
889 char *p1 = keyDefsAbort;
890 EncodeKeyDefinitions (1, &p1, ABORTkey_EXPORT);
891 first = FALSE;
892 }
893 /****************************************************************************
894 * Build export list.
895 ****************************************************************************/
896 BuildExportList (&exportHead, LogicalFALSE);
897 /****************************************************************************
898 * Determine if the dimensionalities are all the same.
899 ****************************************************************************/
900 same = SameDimensionalities (&numDims, dimSizes, exportHead);
901 sameGt0 = (same && numDims > 0);
902 /****************************************************************************
903 * Validate `Record' and `Indices' selections.
904 ****************************************************************************/
905 ValidateRecordIndices (OUTPUTtoFILEv, same, numDims, exportHead);
906 /****************************************************************************
907 * Calculate the width of each line and the maximum record number and
908 * maximum number of values per record (array).
909 ****************************************************************************/
910 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
911 if (Item->output) {
912 switch (Item->type) {
913 case RECORDt:
914 case INDICESt:
915 lineL += BOO(lineL == 0,0,opt.spacing) + Item->width;
916 break;
917 case VARIABLEt: {
918 int width = BOO(simpleMode,
919 StandardWidth(Item->Var->dataType,
920 Item->Var->numElems),Item->width);
921 int addL = BOO(lineL == 0,0,opt.spacing) + width;
922 lineL += addL;
923 maxRecordValues = MAXIMUM(maxRecordValues,Item->Var->nRecordValues);
924 break;
925 }
926 }
927 }
928 }
929 /****************************************************************************
930 * Check if a valid listing.
931 ****************************************************************************/
932 if (lineL == 0) {
933 DisplayMessage ("Nothing selected for listing.", BEEPWAIT1);
934 return TRUE;
935 }
936 /****************************************************************************
937 * Determine first/last records/indices.
938 ****************************************************************************/
939 switch (FirstLastRecord(&firstRec,&lastRec,FALSE,exportHead)) {
940 case PASSED: break;
941 case FAILED: return TRUE;
942 case FATAL: return FALSE;
943 }
944 if (sameGt0) {
945 switch (FirstLastIndices(numDims,dimSizes,firstIndices,lastIndices,
946 &maxRecordValues,FALSE,exportHead)) {
947 case PASSED: break;
948 case FAILED: return TRUE;
949 case FATAL: return FALSE;
950 }
951 }
952 /****************************************************************************
953 * Remove items from the export list that are not being output or filtered.
954 ****************************************************************************/
955 RemoveExportItems (&exportHead);
956 /****************************************************************************
957 * Allocate buffer for line.
958 ****************************************************************************/
959 line = (char *) cdf_AllocateMemory ((size_t) (lineL + 1), NULL);
960 if (line == NULL) {
961 DisplayMessage ("Not enough memory.", BEEPWAIT);
962 return TRUE;
963 }
964 /****************************************************************************
965 * Prompt for listing file path (unless in batch mode) and open file.
966 ****************************************************************************/
967 if (!BATCH(batchMode)) {
968 if (!PromptFor(outputText,DU_MAX_PATH_LEN,strlen(outputText),
969 "Enter path for listing file...",oFILEhelpID)) {
970 cdf_FreeMemory (line, FatalError);
971 return TRUE;
972 }
973 }
974 oFp = fopen (outputText, "w");
975 if (oFp == NULL) {
976 DisplayMessage (listOpenError, BEEPWAIT);
977 cdf_FreeMemory (line, FatalError);
978 return TRUE;
979 }
980 /****************************************************************************
981 * Output header line(s).
982 ****************************************************************************/
983 if (opt.textHeading) {
984 if (!ListAttributes(oFp,&cdfFatal)) {
985 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
986 cdf_FreeMemory (line, FatalError);
987 return (!cdfFatal);
988 }
989 MakeNUL (line);
990 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
991 if (Item->output) {
992 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
993 switch (Item->type) {
994 case RECORDt:
995 CatToString (line, "Record", Item->width, LEFT_JUSTIFY, "*");
996 break;
997 case INDICESt:
998 CatToString (line, "Indices", Item->width, LEFT_JUSTIFY, "*");
999 break;
1000 case VARIABLEt: {
1001 int standardWidth = StandardWidth(Item->Var->dataType,
1002 Item->Var->numElems);
1003 int valueWidth = BOO(simpleMode,standardWidth,Item->width);
1004 CatToString (line, Item->Var->name, valueWidth,
1005 CENTER_JUSTIFY, "*");
1006 break;
1007 }
1008 }
1009 }
1010 }
1011 if (fprintf(oFp,"\nVariables:\n\n%s\n",line) < 0) {
1012 DisplayMessage (listWriteError, BEEPWAIT);
1013 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
1014 cdf_FreeMemory (line, FatalError);
1015 return TRUE;
1016 }
1017 }
1018 /****************************************************************************
1019 * If same dimensionalities, initialize indices.
1020 ****************************************************************************/
1021 if (sameGt0) {
1022 ARRAYtoARRAY (indices, firstIndices, numDims)
1023 }
1024 /****************************************************************************
1025 * Read/output values until end of listing.
1026 ****************************************************************************/
1027 nLinesTotal = (lastRec - firstRec + 1) * maxRecordValues;
1028 DisplayPctComplete (NO_PCT, pctMsg);
1029 NEWkeyDEFS (EWkey, keyDefsAbort, batchMode)
1030 for (recN = firstRec, atLine = 0; recN <= lastRec; recN++) {
1031 for (valueN = 0; valueN < maxRecordValues; valueN++) {
1032 /**********************************************************************
1033 * Check for abort key.
1034 **********************************************************************/
1035 if (AbortListing(oFp,line)) {
1036 NEWkeyDEFS (EWkey, keyDefsBlank, batchMode)
1037 return TRUE;
1038 }
1039 /**********************************************************************
1040 * Encode line.
1041 **********************************************************************/
1042 status = EncodeLineVert(line,recN,valueN,numDims,indices,
1043 same,&filterStatus,exportHead,
1044 outRowMajor,simpleMode);
1045 DisplayStatus (status, readingCDF);
1046 if (StatusBAD(status)) {
1047 if (fprintf(oFp,"Incomplete listing.\n") < 0) {
1048 DisplayMessage (listWriteError, BEEPWAIT);
1049 }
1050 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
1051 cdf_FreeMemory (line, FatalError);
1052 return FALSE;
1053 }
1054 /**********************************************************************
1055 * Check filter status to see if the line should be output.
1056 **********************************************************************/
1057 if (SHOWline(filterStatus)) {
1058 if (fprintf(oFp,"%s\n",line) < 0) {
1059 DisplayMessage (listWriteError, BEEPWAIT);
1060 if (fclose(oFp) == EOF) DisplayMessage (listCloseError, BEEPWAIT);
1061 cdf_FreeMemory (line, FatalError);
1062 return TRUE;
1063 }
1064 }
1065 /**********************************************************************
1066 * Check filter status to see if this record should be aborted.
1067 **********************************************************************/
1068 if (filterStatus == FAILrecord) {
1069 while (valueN < maxRecordValues) {
1070 DisplayPctComplete (PCT(atLine,nLinesTotal,1,1), pctMsg);
1071 valueN++;
1072 atLine++;
1073 }
1074 break;
1075 }
1076 /**********************************************************************
1077 * If same dimensionalities, increment indices.
1078 **********************************************************************/
1079 if (sameGt0) {
1080 if (outRowMajor)
1081 IncrIndicesFirstLastRow (numDims, firstIndices,
1082 lastIndices, indices);
1083 else
1084 IncrIndicesFirstLastCol (numDims, firstIndices,
1085 lastIndices, indices);
1086 }
1087 /**********************************************************************
1088 * Update percentage complete message.
1089 **********************************************************************/
1090 DisplayPctComplete (PCT(atLine,nLinesTotal,1,1), pctMsg);
1091 atLine++;
1092 }
1093 }
1094 /****************************************************************************
1095 * End of listing.
1096 ****************************************************************************/
1097 NEWkeyDEFS (EWkey, keyDefsBlank, batchMode)
1098 if (fclose(oFp) == EOF) {
1099 DisplayMessage (listCloseError, BEEPWAIT);
1100 cdf_FreeMemory (line, FatalError);
1101 return TRUE;
1102 }
1103 cdf_FreeMemory (line, FatalError);
1104 if (!BATCH(batchMode)) DisplayMessage ("Complete.", NOBEEPWAIT1);
1105 return TRUE;
1106 }
1107
1108 /******************************************************************************
1109 * EncodeLineVert.
1110 ******************************************************************************/
1111
EncodeLineVert(line,recN,valueN,numDims,indices,same,filterStatus,exportHead,outRowMajor,standard)1112 CDFstatus EncodeLineVert (line, recN, valueN, numDims, indices, same,
1113 filterStatus, exportHead, outRowMajor, standard)
1114 char *line;
1115 long recN;
1116 long valueN; /* Ignored if same dimensionalities. */
1117 long numDims; /* Ignored if different dimensionalities. */
1118 long indices[CDF_MAX_DIMS]; /* Ignored if different dimensionalities. */
1119 Logical same;
1120 int *filterStatus;
1121 struct ItemStruct *exportHead;
1122 Logical outRowMajor;
1123 Logical standard;
1124 {
1125 struct ItemStruct *Item; CDFstatus pStatus = CDF_OK; Logical failedFilter;
1126 /****************************************************************************
1127 * Initialize line and filter status.
1128 ****************************************************************************/
1129 MakeNUL (line);
1130 *filterStatus = PASSes;
1131 /****************************************************************************
1132 * Encode each exported item.
1133 ****************************************************************************/
1134 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
1135 switch (Item->type) {
1136 /***********************************************************************
1137 * Record number.
1138 ***********************************************************************/
1139 case RECORDt: {
1140 failedFilter = RECORDfailedFILTER(Item,recN);
1141 if (failedFilter) {
1142 if (opt.showFiltered)
1143 *filterStatus = SHOWit;
1144 else {
1145 *filterStatus = FAILrecord;
1146 return pStatus;
1147 }
1148 }
1149 if (Item->output) {
1150 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
1151 if (failedFilter)
1152 CatNcharacters (line, Item->width, '-');
1153 else
1154 EncodeRecordJustify (EofS(line), recN, -(Item->width));
1155 }
1156 break;
1157 }
1158 /***********************************************************************
1159 * Indices.
1160 * This case will not occur if different dimensionalities.
1161 ***********************************************************************/
1162 case INDICESt: {
1163 /*********************************************************************
1164 * Filter indices.
1165 *********************************************************************/
1166 failedFilter = INDICESfailedFILTER(Item,indices);
1167 if (failedFilter) {
1168 if (opt.showFiltered)
1169 *filterStatus = SHOWit;
1170 else {
1171 *filterStatus = FAILline;
1172 return pStatus;
1173 }
1174 }
1175 /*********************************************************************
1176 * Output indices (if requested).
1177 *********************************************************************/
1178 if (Item->output) {
1179 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
1180 if (failedFilter)
1181 CatNcharacters (line, Item->width, '-');
1182 else
1183 EncodeIndicesJustify (EofS(line), numDims, indices,
1184 -(Item->width));
1185 }
1186 break;
1187 }
1188 /***********************************************************************
1189 * Variable.
1190 ***********************************************************************/
1191 case VARIABLEt: {
1192 CDFstatus status; int dimN;
1193 int standardWidth = StandardWidth(Item->Var->dataType,
1194 Item->Var->numElems);
1195 int width = BOO(standard,standardWidth,Item->width);
1196 char *format = BOO(standard,
1197 StandardFormat(Item->Var->dataType),
1198 Item->Var->format);
1199 /*********************************************************************
1200 * If different dimensionalities and first value in a record,
1201 * initialize the indices and value number for the variable.
1202 *********************************************************************/
1203 if (!same) {
1204 if (valueN == 0) {
1205 for (dimN = 0; dimN < Item->Var->numDims; dimN++) {
1206 Item->Var->indices[dimN] = 0;
1207 }
1208 Item->Var->valueN = 0;
1209 }
1210 }
1211 /*********************************************************************
1212 * If different dimensionalities, check if no more values for this
1213 * variable.
1214 *********************************************************************/
1215 if (!same) {
1216 if (Item->Var->valueN == Item->Var->nRecordValues) {
1217 if (Item->output) {
1218 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
1219 CatNcharacters (line, width, ' ');
1220 }
1221 break;
1222 }
1223 }
1224 /*********************************************************************
1225 * Select variable, record number, and indices and then read value.
1226 *********************************************************************/
1227 status = CDFlib (SELECT_, BOO(Item->Var->zVar,
1228 zVAR_,rVAR_), Item->Var->varN,
1229 BOO(Item->Var->zVar,
1230 zVAR_RECNUMBER_,rVARs_RECNUMBER_), recN,
1231 BOO(Item->Var->zVar,
1232 zVAR_DIMINDICES_,
1233 rVARs_DIMINDICES_),
1234 BOO(same,indices,Item->Var->indices),
1235 GET_, BOO(Item->Var->zVar,
1236 zVAR_DATA_,rVAR_DATA_), Item->Var->value,
1237 NULL_);
1238 if (!sX(status,&pStatus)) return pStatus;
1239 /*********************************************************************
1240 * Filter value. If the value failed the filter...
1241 *********************************************************************/
1242 failedFilter = VARfailedFILTER(Item,Item->Var->value);
1243 if (failedFilter) {
1244 if (opt.showFiltered)
1245 *filterStatus = SHOWit;
1246 else {
1247 if (same) {
1248 if (Item->Var->scalar)
1249 *filterStatus = FAILrecord;
1250 else
1251 *filterStatus = FAILline;
1252 return pStatus;
1253 }
1254 else {
1255 if (Item->Var->nRecordValues == 1) {
1256 *filterStatus = FAILrecord;
1257 return pStatus;
1258 }
1259 }
1260 }
1261 }
1262 /*********************************************************************
1263 * Encode value.
1264 *********************************************************************/
1265 if (Item->output) {
1266 if (!NULstring(line)) CatNcharacters (line, opt.spacing, ' ');
1267 if (failedFilter)
1268 CatNcharacters (line, width, '-');
1269 else
1270 EncodeValuesFormat (Item->Var->dataType, Item->Var->numElems,
1271 Item->Var->value, EofS(line),
1272 format, width, width, opt.epochStyle);
1273 }
1274 /*********************************************************************
1275 * If different dimensionalities, increment to next value/indices.
1276 *********************************************************************/
1277 if (!same) {
1278 if (outRowMajor)
1279 INCRindicesROW (Item->Var->numDims, Item->Var->dimSizes,
1280 Item->Var->indices);
1281 else
1282 INCRindicesCOL (Item->Var->numDims, Item->Var->dimSizes,
1283 Item->Var->indices);
1284 Item->Var->valueN++;
1285 }
1286 break;
1287 }
1288 }
1289 }
1290 return pStatus;
1291 }
1292
1293 /******************************************************************************
1294 * ListAttributes.
1295 * Returns FALSE if an error occurred.
1296 ******************************************************************************/
1297
ListAttributes(oFp,cdfFatal)1298 Logical ListAttributes (oFp, cdfFatal)
1299 FILE *oFp;
1300 Logical *cdfFatal; /* Set TRUE if a fatal CDF error occurred. */
1301 {
1302 CDFstatus status; long attrN, nAttrs;
1303 /****************************************************************************
1304 * Display heading.
1305 ****************************************************************************/
1306 if (fprintf(oFp,"Global attributes:\n") < 0) {
1307 *cdfFatal = FALSE;
1308 return FALSE;
1309 }
1310 /****************************************************************************
1311 * Inquire the number of attributes.
1312 ****************************************************************************/
1313 status = CDFlib (GET_, CDF_NUMATTRS_, &nAttrs,
1314 NULL_);
1315 DisplayStatus (status, readingCDF);
1316 if (StatusBAD(status)) {
1317 *cdfFatal = TRUE;
1318 return FALSE;
1319 }
1320 /****************************************************************************
1321 * For each attribute...
1322 ****************************************************************************/
1323 for (attrN = 0; attrN < nAttrs; attrN++) {
1324 long scope;
1325 /*************************************************************************
1326 * Inquire the attribute scope.
1327 *************************************************************************/
1328 status = CDFlib (SELECT_, ATTR_, attrN,
1329 GET_, ATTR_SCOPE_, &scope,
1330 NULL_);
1331 DisplayStatus (status, readingCDF);
1332 if (StatusBAD(status)) {
1333 *cdfFatal = TRUE;
1334 return FALSE;
1335 }
1336 /*************************************************************************
1337 * If a gAttribute...
1338 *************************************************************************/
1339 if (scope == GLOBAL_SCOPE) {
1340 long maxEntry, entryN; char attrName[CDF_ATTR_NAME_LEN+1];
1341 /***********************************************************************
1342 * Inquire the attribute's name and maximum gEntry number.
1343 ***********************************************************************/
1344 status = CDFlib (GET_, ATTR_NAME_, attrName,
1345 ATTR_MAXgENTRY_, &maxEntry,
1346 NULL_);
1347 DisplayStatus (status, readingCDF);
1348 if (StatusBAD(status)) {
1349 *cdfFatal = TRUE;
1350 return FALSE;
1351 }
1352 RemoveTrailingBlanks (attrName);
1353 if (fprintf(oFp,"\n %s\n",attrName) < 0) {
1354 *cdfFatal = FALSE;
1355 return FALSE;
1356 }
1357 /***********************************************************************
1358 * For each gEntry...
1359 ***********************************************************************/
1360 for (entryN = 0; entryN <= maxEntry; entryN++) {
1361 long dataType, numElems, nBytes; void *value;
1362 char encoded[MAXgENTRYencodedLEN+1];
1363 /********************************************************************
1364 * If this entry might exist...
1365 ********************************************************************/
1366 status = CDFlib (SELECT_, gENTRY_, entryN,
1367 CONFIRM_, CURgENTRY_EXISTENCE_,
1368 NULL_);
1369 if (status != NO_SUCH_ENTRY) {
1370 /******************************************************************
1371 * Check if some other error occurred.
1372 ******************************************************************/
1373 DisplayStatus (status, readingCDF);
1374 if (StatusBAD(status)) {
1375 *cdfFatal = TRUE;
1376 return FALSE;
1377 }
1378 /******************************************************************
1379 * Inquire the data specification.
1380 ******************************************************************/
1381 status = CDFlib (GET_, gENTRY_DATATYPE_, &dataType,
1382 gENTRY_NUMELEMS_, &numElems,
1383 NULL_);
1384 DisplayStatus (status, readingCDF);
1385 if (StatusBAD(status)) {
1386 *cdfFatal = TRUE;
1387 return FALSE;
1388 }
1389 /******************************************************************
1390 * Inquire the value.
1391 ******************************************************************/
1392 nBytes = CDFelemSize(dataType) * numElems;
1393 value = cdf_AllocateMemory ((size_t) nBytes, FatalError);
1394 status = CDFlib (GET_, gENTRY_DATA_, value,
1395 NULL_);
1396 DisplayStatus (status, readingCDF);
1397 if (StatusBAD(status)) {
1398 *cdfFatal = TRUE;
1399 return FALSE;
1400 }
1401 /******************************************************************
1402 * List the value.
1403 ******************************************************************/
1404 EncodeValuesFormat (dataType, numElems, value, encoded, NULL,
1405 0, MAXgENTRYencodedLEN, opt.epochStyle);
1406 if (fprintf(oFp," %s\n",encoded) < 0) {
1407 *cdfFatal = FALSE;
1408 return FALSE;
1409 }
1410 cdf_FreeMemory (value, FatalError);
1411 }
1412 }
1413 }
1414 }
1415 return TRUE;
1416 }
1417
1418 /******************************************************************************
1419 * ToCDF.
1420 * Output to CDF.
1421 * Returns FALSE if a fatal error occurred on the input CDF only.
1422 * This routine must ensure that the input CDF is made the current CDF
1423 * before returning. It is assumed that the input CDF is also the current
1424 * CDF when this routine is called.
1425 ******************************************************************************/
1426
ToCDF(inID)1427 Logical ToCDF (inID)
1428 CDFid inID;
1429 {
1430 int dimN; CDFid outID; Logical same, sameGt0;
1431 struct ItemStruct *Item; CDFstatus status;
1432 struct ItemStruct *exportHead;
1433 long outMajority = MAJORITYtoOUT(opt.majority,inMajority);
1434 long firstRec, lastRec, nAttrs;
1435 long numDims, dimSizes[CDF_MAX_DIMS];
1436 long firstIndices[CDF_MAX_DIMS], lastIndices[CDF_MAX_DIMS];
1437 static char keyDefsBlank[] = "\n\n";
1438 /****************************************************************************
1439 * Build export list.
1440 ****************************************************************************/
1441 BuildExportList (&exportHead, LogicalFALSE);
1442 /****************************************************************************
1443 * Determine if the variables being output/filtered have the same
1444 * dimensionalities.
1445 ****************************************************************************/
1446 same = SameDimensionalities (&numDims, dimSizes, exportHead);
1447 sameGt0 = (same && numDims > 0);
1448 /****************************************************************************
1449 * Validate `Record' and `Indices' selections.
1450 ****************************************************************************/
1451 ValidateRecordIndices (OUTPUTtoCDF, same, numDims, exportHead);
1452 /****************************************************************************
1453 * Check the number of variables being output. Note that at this point if
1454 * an item is being output then it must be a variable.
1455 ****************************************************************************/
1456 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
1457 if (Item->output) break;
1458 }
1459 if (Item == NULL) {
1460 DisplayMessage ("No variables selected for output.", BEEPWAIT1);
1461 return TRUE;
1462 }
1463 /****************************************************************************
1464 * Calculate the first/last record and indices.
1465 ****************************************************************************/
1466 switch (FirstLastRecord(&firstRec,&lastRec,TRUE,exportHead)) {
1467 case PASSED: break;
1468 case FAILED: return TRUE;
1469 case FATAL: return FALSE;
1470 }
1471 if (sameGt0) {
1472 switch (FirstLastIndices(numDims,dimSizes,firstIndices,
1473 lastIndices,NULL,TRUE,exportHead)) {
1474 case PASSED: break;
1475 case FAILED: return TRUE;
1476 case FATAL: return FALSE;
1477 }
1478 }
1479 /****************************************************************************
1480 * Remove items from the export list that are not being output or filtered.
1481 ****************************************************************************/
1482 RemoveExportItems (&exportHead);
1483 /****************************************************************************
1484 * Prompt for new CDF's path unless in batch mode.
1485 ****************************************************************************/
1486 if (!BATCH(batchMode)) {
1487 if (!PromptFor(outputCDF,CDF_PATHNAME_LEN,strlen(outputCDF),
1488 "Enter path for output CDF...",oCDFhelpID)) return TRUE;
1489 }
1490 /****************************************************************************
1491 * If same dimensionalities, calculate rDimensionality for output CDF. If
1492 * different dimensionalities, inquire rDimensionality of input CDF.
1493 ****************************************************************************/
1494 if (sameGt0) {
1495 for (dimN = 0; dimN < numDims; dimN++) {
1496 dimSizes[dimN] = lastIndices[dimN] - firstIndices[dimN] + 1;
1497 }
1498 }
1499 else {
1500 status = CDFlib (GET_, rVARs_NUMDIMS_, &numDims,
1501 rVARs_DIMSIZES_, dimSizes,
1502 NULL_);
1503 DisplayStatus (status, readingCDF);
1504 if (StatusBAD(status)) return FALSE;
1505 }
1506 /****************************************************************************
1507 * Delete existing CDF with same name?
1508 ****************************************************************************/
1509 if (opt.deleteExisting) {
1510 if (IsCDF(outputCDF)) {
1511 if (!BATCH(batchMode)) {
1512 DisplayMessage ("Deleting existing output CDF...", NOWAIT);
1513 }
1514 status = CDFlib (OPEN_, CDF_, outputCDF, &outID,
1515 NULL_);
1516 DisplayStatus (status, "opening existing CDF");
1517 if (StatusBAD(status)) {
1518 SELECTcdf (inID);
1519 return TRUE;
1520 }
1521 status = CDFlib (DELETE_, CDF_,
1522 NULL_);
1523 DisplayStatus (status, "deleting existing CDF");
1524 if (StatusBAD(status)) {
1525 CDFclose (outID);
1526 SELECTcdf (inID);
1527 return TRUE;
1528 }
1529 if (!BATCH(batchMode)) DisplayMessage ("", NOWAIT);
1530 }
1531 }
1532 /****************************************************************************
1533 * Create output CDF.
1534 ****************************************************************************/
1535 if (!BATCH(batchMode)) DisplayMessage ("Creating output CDF...", NOWAIT);
1536 status = CDFlib (CREATE_, CDF_, outputCDF, numDims, dimSizes, &outID,
1537 NULL_);
1538 DisplayStatus (status, "creating output CDF");
1539 if (StatusBAD(status)) {
1540 SELECTcdf (inID);
1541 return TRUE;
1542 }
1543 status = CDFlib (SELECT_, CDF_CACHESIZE_, workingCache,
1544 STAGE_CACHESIZE_, stageCache,
1545 COMPRESS_CACHESIZE_, compressCache,
1546 PUT_, CDF_FORMAT_, BOO(opt.singleFile,SINGLE_FILE,
1547 MULTI_FILE),
1548 CDF_ENCODING_, opt.encoding,
1549 CDF_MAJORITY_, outMajority,
1550 CDF_COMPRESSION_, CDFcType, CDFcParms,
1551 CDF_CHECKSUM_, CDFchecksum,
1552 NULL_);
1553 DisplayStatus (status, "configuring output CDF");
1554 if (StatusBAD(status)) {
1555 CDFclose (outID);
1556 SELECTcdf (inID);
1557 return TRUE;
1558 }
1559 /****************************************************************************
1560 * Create attributes/entries and variables in output CDF.
1561 ****************************************************************************/
1562 switch (CopyAttributesANDgEntries(inID,outID,&nAttrs)) {
1563 case SUCCESS:
1564 break;
1565 case FATALin:
1566 CDFclose (outID);
1567 SELECTcdf (inID);
1568 return FALSE;
1569 case FATALout:
1570 CDFclose (outID);
1571 SELECTcdf (inID);
1572 return TRUE;
1573 }
1574 switch (CopyVariablesANDrzEntries(inID,outID,nAttrs,same,
1575 numDims,dimSizes,exportHead)) {
1576 case SUCCESS:
1577 break;
1578 case FATALin:
1579 CDFclose (outID);
1580 SELECTcdf (inID);
1581 return FALSE;
1582 case FATALout:
1583 CDFclose (outID);
1584 SELECTcdf (inID);
1585 return TRUE;
1586 }
1587 /****************************************************************************
1588 * Write to variables in output CDF.
1589 ****************************************************************************/
1590 switch (BOO(sameGt0,ToCDFsameGt0(inID,outID,firstRec,lastRec,
1591 numDims,dimSizes,firstIndices,
1592 outMajority,exportHead),
1593 ToCDFdiffOrZero(inID,outID,firstRec,
1594 lastRec,outMajority,exportHead))) {
1595 case SUCCESS:
1596 break;
1597 case FATALin:
1598 CDFclose (outID);
1599 SELECTcdf (inID);
1600 return FALSE;
1601 case FATALout:
1602 CDFclose (outID);
1603 SELECTcdf (inID);
1604 return TRUE;
1605 }
1606 /****************************************************************************
1607 * Close output CDF.
1608 ****************************************************************************/
1609 NEWkeyDEFS (EWkey, keyDefsBlank, batchMode)
1610 if (!BATCH(batchMode)) DisplayMessage ("Closing CDF...", NOWAIT);
1611 if (dumpStats) {
1612 vSTATS vStatsDotCDF, vStatsStage, vStatsCompress;
1613 char temp1[MAX_SCREENLINE_LEN+1],
1614 temp2[MAX_SCREENLINE_LEN+1],
1615 temp3[MAX_SCREENLINE_LEN+1];
1616 if (!BATCH(batchMode)) DisplayMessage ("", NOWAIT);
1617 status = CDFlib (SELECT_, CDF_, outID,
1618 CLOSE_, CDFwithSTATS_, &vStatsDotCDF,
1619 &vStatsStage,
1620 &vStatsCompress,
1621 NULL_);
1622 DisplayStatus (status, "closing output CDF");
1623 if (StatusOK(status)) {
1624 if (vStatsDotCDF.maxBuffers > 0) {
1625 BuildStatistics ("output CDF DotCDF file", &vStatsDotCDF,
1626 temp1, temp2, temp3);
1627 if (BATCH(batchMode))
1628 printf ("%s\n%s\n%s\n", temp1, temp2, temp3);
1629 else
1630 InfoWindow (temp1, temp2, temp3, FALSE, FALSE, 0);
1631 }
1632 if (vStatsStage.maxBuffers > 0) {
1633 BuildStatistics ("output CDF staging file", &vStatsStage,
1634 temp1, temp2, temp3);
1635 if (BATCH(batchMode))
1636 printf ("%s\n%s\n%s\n", temp1, temp2, temp3);
1637 else
1638 InfoWindow (temp1, temp2, temp3, FALSE, FALSE, 0);
1639 }
1640 if (vStatsCompress.maxBuffers > 0) {
1641 BuildStatistics ("output CDF compression scratch file",
1642 &vStatsCompress, temp1, temp2, temp3);
1643 if (BATCH(batchMode))
1644 printf ("%s\n%s\n%s\n", temp1, temp2, temp3);
1645 else
1646 InfoWindow (temp1, temp2, temp3, FALSE, FALSE, 0);
1647 }
1648 }
1649 }
1650 else {
1651 status = CDFclose (outID);
1652 DisplayStatus (status, "closing output CDF");
1653 if (StatusOK(status)) {
1654 if (!BATCH(batchMode)) DisplayMessage ("", NOBEEPWAIT1);
1655 }
1656 }
1657 SELECTcdf (inID);
1658 return TRUE;
1659 }
1660
1661 /******************************************************************************
1662 * ToCDFsameGt0.
1663 * Same dimensionalities and the number of dimensions is greater than zero.
1664 * Returns SUCCESS, FATALin, or FATALout;
1665 ******************************************************************************/
1666
ToCDFsameGt0(inID,outID,firstRec,lastRec,numDims,dimSizes,firstIndices,outMajority,exportHead)1667 int ToCDFsameGt0 (inID, outID, firstRec, lastRec, numDims, dimSizes,
1668 firstIndices, outMajority, exportHead)
1669 CDFid inID;
1670 CDFid outID;
1671 long firstRec;
1672 long lastRec;
1673 long numDims; /* For the output CDF. */
1674 long dimSizes[]; /* For the output CDF. */
1675 long firstIndices[]; /* From the input CDF. */
1676 long outMajority;
1677 struct ItemStruct *exportHead;
1678 {
1679 long nValues, nRecordValues, indicesI[CDF_MAX_DIMS], nHypers, hyperN;
1680 long recF, recL; static Logical first = TRUE;
1681 int dimN, i; Byte ***handles; size_t *nValueBytes;
1682 int scalarCount, hyperCount, varCount, scalarX, hyperX;
1683 struct ItemStruct *Item, *prevItem, *scalarHead, *scalarTail;
1684 struct ItemStruct *hyperHead, *hyperTail;
1685 struct HyperStruct hyper; struct GroupStruct groups;
1686 Logical filteringScalars, filteringHypers; CDFstatus status;
1687 static char rvMsg[] = "Reading/writing variable values...";
1688 static char keyDefsAbort[] = "Abort: ________\n\n";
1689 /****************************************************************************
1690 * Encode key definitions first time.
1691 ****************************************************************************/
1692 if (first) {
1693 char *p1 = keyDefsAbort;
1694 EncodeKeyDefinitions (1, &p1, ABORTkey_EXPORT);
1695 first = FALSE;
1696 }
1697 /****************************************************************************
1698 * Read/write first (and only) record for NRV variables. Note that
1699 * if an item is being output it must be a variable.
1700 ****************************************************************************/
1701 switch (OutputNRVvalues(inID,outID,exportHead,TRUE,
1702 dimSizes,firstIndices,outMajority)) {
1703 case SUCCESS: break;
1704 case FATALin: return FATALin;
1705 case FATALout: return FATALout;
1706 }
1707 /****************************************************************************
1708 * Remove NRV variables from export list if they are not being filtered.
1709 ****************************************************************************/
1710 for (Item = exportHead, prevItem = NULL;
1711 Item != NULL; Item = Item->nextExport) {
1712 if (!Item->Var->recVary && !Item->filter) {
1713 if (prevItem == NULL)
1714 exportHead = Item->nextExport;
1715 else
1716 prevItem->nextExport = Item->nextExport;
1717 }
1718 else
1719 prevItem = Item;
1720 }
1721 /****************************************************************************
1722 * Determine scalars and hypers.
1723 ****************************************************************************/
1724 for (Item = exportHead, scalarCount = 0, hyperCount = 0;
1725 Item != NULL; Item = Item->nextExport) {
1726 if (Item->Var->scalar)
1727 scalarCount++;
1728 else
1729 hyperCount++;
1730 }
1731 varCount = scalarCount + hyperCount;
1732 handles = (Byte ***) cdf_AllocateMemory (varCount * sizeof(Byte **),
1733 FatalError);
1734 nValueBytes = (size_t *) cdf_AllocateMemory (varCount * sizeof(size_t),
1735 FatalError);
1736 for (Item = exportHead, scalarX = 0, hyperX = scalarCount,
1737 scalarHead = scalarTail = NULL, hyperHead = hyperTail = NULL,
1738 filteringScalars = FALSE, filteringHypers = FALSE;
1739 Item != NULL; Item = Item->nextExport) {
1740 if (Item->Var->scalar) {
1741 handles[scalarX] = &(Item->Var->buffer);
1742 nValueBytes[scalarX++] = Item->Var->nValueBytes;
1743 if (scalarHead == NULL)
1744 scalarHead = scalarTail = Item;
1745 else
1746 scalarTail = scalarTail->nextScalar = Item;
1747 Item->nextScalar = NULL;
1748 if (Item->filter) filteringScalars = TRUE;
1749 }
1750 else {
1751 handles[hyperX] = &(Item->Var->buffer);
1752 nValueBytes[hyperX++] = Item->Var->nValueBytes;
1753 if (hyperHead == NULL)
1754 hyperHead = hyperTail = Item;
1755 else
1756 hyperTail = hyperTail->nextHyper = Item;
1757 Item->nextHyper = NULL;
1758 if (Item->filter) filteringHypers = TRUE;
1759 }
1760 }
1761 /****************************************************************************
1762 * Preallocate variable records.
1763 ****************************************************************************/
1764 if (opt.preAllocate) {
1765 switch (PreAllocateRecords(inID,outID,scalarHead,
1766 hyperHead,&firstRec,&lastRec)) {
1767 case SUCCESS: break;
1768 case FATALin: return FATALin;
1769 case FATALout: return FATALout;
1770 }
1771 }
1772 /****************************************************************************
1773 * Allocate buffers.
1774 ****************************************************************************/
1775 DisplayPctComplete (NO_PCT, rvMsg);
1776 NEWkeyDEFS (EWkey, keyDefsAbort, batchMode)
1777 AllocateBuffers (lastRec - firstRec + 1, numDims, dimSizes, &groups,
1778 scalarCount, hyperCount, handles, nValueBytes,
1779 ROWmajor(inMajority), 5, FatalError);
1780 cdf_FreeMemory (handles, FatalError);
1781 cdf_FreeMemory (nValueBytes, FatalError);
1782 /****************************************************************************
1783 * Count number of values per record.
1784 ****************************************************************************/
1785 for (dimN = 0, nRecordValues = 1; dimN < numDims; dimN++) {
1786 nRecordValues *= dimSizes[dimN];
1787 }
1788 /****************************************************************************
1789 * Read/write each record for RV variables. Note that NRV variables are
1790 * still read for filtering.
1791 ****************************************************************************/
1792 if (HyperFullRecord(&groups,numDims)) {
1793 /**************************************************************************
1794 * Each hyper read/write consists of one or more hyper records.
1795 **************************************************************************/
1796 long recNo = 0, recX, firstX, lastX, thisCount;
1797 InitHyperParms (&hyper, &groups, numDims, &nHypers, &nValues);
1798 for (hyperN = 0; hyperN < nHypers; hyperN++) {
1799 /***********************************************************************
1800 * Hyper read scalar input variables.
1801 ***********************************************************************/
1802 for (Item = scalarHead; Item != NULL; Item = Item->nextScalar) {
1803 status = HYPERget (inID, Item->Var->varN, Item->Var->zVar,
1804 firstRec + hyper.recNumber, hyper.recCount,
1805 dimIndices_0, dimCounts_1, Item->Var->buffer);
1806 DisplayStatus (status, readingCDF);
1807 if (StatusBAD(status)) {
1808 FreeExportBuffers (exportHead);
1809 return FATALin;
1810 }
1811 }
1812 DisplayPctComplete (PCT(hyperN,nHypers,1,2), rvMsg);
1813 if (AbortCDF(exportHead)) return SUCCESS;
1814 /***********************************************************************
1815 * Until no more records...
1816 ***********************************************************************/
1817 for (recX = 0;;) {
1818 /********************************************************************
1819 * Determine first record to be output.
1820 ********************************************************************/
1821 firstX = FindFirstRecord (recX, scalarHead, filteringScalars,
1822 hyper.recCount);
1823 if (firstX == NO_RECORD) break;
1824 /********************************************************************
1825 * Determine last record to be output.
1826 ********************************************************************/
1827 lastX = FindLastRecord (firstX, scalarHead, filteringScalars,
1828 hyper.recCount);
1829 thisCount = lastX - firstX + 1;
1830 recF = firstRec + hyper.recNumber + firstX;
1831 recL = firstRec + hyper.recNumber + lastX;
1832 /********************************************************************
1833 * Hyper write to scalar output variables (being output).
1834 ********************************************************************/
1835 for (Item = scalarHead; Item != NULL; Item = Item->nextScalar) {
1836 if (Item->output) {
1837 if (recF <= Item->Var->maxRec) {
1838 long count = MINIMUM(recL,Item->Var->maxRec) - recF + 1;
1839 Byte *buffer = Item->Var->buffer +
1840 (size_t) (Item->Var->nValueBytes * firstX);
1841 status = HYPERput (outID, Item->Var->varNo, Item->Var->zVar,
1842 recNo, count, dimIndices_0, dimCounts_1,
1843 buffer);
1844 DisplayStatus (status, writingCDF);
1845 if (StatusBAD(status)) {
1846 FreeExportBuffers (exportHead);
1847 return FATALout;
1848 }
1849 }
1850 }
1851 }
1852 if (AbortCDF(exportHead)) return SUCCESS;
1853 /********************************************************************
1854 * Read hyper input variables.
1855 ********************************************************************/
1856 for (Item = hyperHead; Item != NULL; Item = Item->nextHyper) {
1857 status = HYPERget (inID, Item->Var->varN, Item->Var->zVar,
1858 recF, thisCount, firstIndices, dimSizes,
1859 Item->Var->buffer);
1860 DisplayStatus (status, readingCDF);
1861 if (StatusBAD(status)) {
1862 FreeExportBuffers (exportHead);
1863 return FATALin;
1864 }
1865 if (AbortCDF(exportHead)) return SUCCESS;
1866 }
1867 /********************************************************************
1868 * Filter hyper variables.
1869 ********************************************************************/
1870 if (filteringHypers) FilterHypers (hyperHead, nValues);
1871 /********************************************************************
1872 * Write to hyper output variables (being output).
1873 ********************************************************************/
1874 for (Item = hyperHead; Item != NULL; Item = Item->nextHyper) {
1875 if (Item->output) {
1876 if (AbortCDF(exportHead)) return SUCCESS;
1877 if (recF <= Item->Var->maxRec) {
1878 long count = MINIMUM(recL,Item->Var->maxRec) - recF + 1;
1879 if (!OutputHyperBuffer(outID,Item->Var->varNo,
1880 Item->Var->zVar,outMajority,
1881 recNo,count,dimIndices_0,dimSizes,
1882 numDims,dimSizes,Item->Var->buffer,
1883 nValues,TRUE,Item->Var->nValueBytes,
1884 nRecordValues)) {
1885 FreeExportBuffers (exportHead);
1886 return FATALout;
1887 }
1888 }
1889 }
1890 }
1891 /********************************************************************
1892 * Increment to next...
1893 ********************************************************************/
1894 recNo += thisCount;
1895 recX = lastX + 1;
1896 if (recX == hyper.recCount) break;
1897 }
1898 DisplayPctComplete (PCT(hyperN,nHypers,2,2), rvMsg);
1899 /***********************************************************************
1900 * Increment to next hyper group.
1901 ***********************************************************************/
1902 IncrHyperParms (&hyper, &groups, numDims, ROWmajor(inMajority),
1903 &nValues);
1904 }
1905 }
1906 else {
1907 /**************************************************************************
1908 * Each hyper read/write consists of less than a full record.
1909 **************************************************************************/
1910 long nHypersPerRecord = HypersPerRecord (&groups, numDims);
1911 long recNi, recNo = -1;
1912 InitHyperParms (&hyper, &groups, numDims, &nHypers, &nValues);
1913 for (hyperN = 0; hyperN < nHypers; hyperN++) {
1914 recNi = firstRec + hyper.recNumber;
1915 /***********************************************************************
1916 * If at the start of a record...
1917 ***********************************************************************/
1918 if (HyperStartOfRecord(&hyper,numDims)) {
1919 Logical skipRecord = FALSE;
1920 /*********************************************************************
1921 * Read/filter values for scalar input variables.
1922 *********************************************************************/
1923 for (Item = scalarHead; Item != NULL; Item = Item->nextScalar) {
1924 status = SINGLEget (inID, Item->Var->varN, Item->Var->zVar,
1925 recNi, dimIndices_0, Item->Var->buffer);
1926 DisplayStatus (status, readingCDF);
1927 if (StatusBAD(status)) {
1928 FreeExportBuffers (exportHead);
1929 return FATALin;
1930 }
1931 if (VARfailedFILTER(Item,Item->Var->buffer)) {
1932 skipRecord = TRUE;
1933 break;
1934 }
1935 }
1936 /*********************************************************************
1937 * If this record is to be skipped, increment the hyper counter by
1938 * one less than the number of hypers per record. This is because
1939 * the `continue' still causes the increment part of the `for' loop
1940 * to be executed.
1941 *********************************************************************/
1942 if (skipRecord) {
1943 for (i = 0; i < nHypersPerRecord; i++) {
1944 IncrHyperParms (&hyper,&groups,numDims,
1945 ROWmajor(inMajority),&nValues);
1946 }
1947 hyperN += (nHypersPerRecord - 1);
1948 continue;
1949 }
1950 else
1951 recNo++;
1952 /*********************************************************************
1953 * Single write to scalar output variables (being output).
1954 *********************************************************************/
1955 for (Item = scalarHead; Item != NULL; Item = Item->nextScalar) {
1956 if (Item->output && recNi <= Item->Var->maxRec) {
1957 status = SINGLEput (outID, Item->Var->varNo, Item->Var->zVar,
1958 recNo, dimIndices_0, Item->Var->buffer);
1959 DisplayStatus (status, readingCDF);
1960 if (StatusBAD(status)) {
1961 FreeExportBuffers (exportHead);
1962 return FATALout;
1963 }
1964 }
1965 }
1966 }
1967 DisplayPctComplete (PCT(hyperN,nHypers,1,4), rvMsg);
1968 if (AbortCDF(exportHead)) return SUCCESS;
1969 /***********************************************************************
1970 * Read from hyper input variables.
1971 ***********************************************************************/
1972 for (Item = hyperHead; Item != NULL; Item = Item->nextHyper) {
1973 for (dimN = 0; dimN < numDims; dimN++) {
1974 indicesI[dimN] = firstIndices[dimN] + hyper.dimIndices[dimN];
1975 }
1976 status = HYPERget (inID, Item->Var->varN, Item->Var->zVar, recNi,
1977 1L, indicesI, hyper.dimCounts, Item->Var->buffer);
1978 DisplayStatus (status, readingCDF);
1979 if (StatusBAD(status)) {
1980 FreeExportBuffers (exportHead);
1981 return FATALin;
1982 }
1983 if (AbortCDF(exportHead)) return SUCCESS;
1984 }
1985 DisplayPctComplete (PCT(hyperN,nHypers,2,4), rvMsg);
1986 /***********************************************************************
1987 * Filter values in hyper buffers.
1988 ***********************************************************************/
1989 if (filteringHypers) FilterHypers (hyperHead, nValues);
1990 DisplayPctComplete (PCT(hyperN,nHypers,3,4), rvMsg);
1991 /***********************************************************************
1992 * Hyper/single write to hyper output variables (being output).
1993 ***********************************************************************/
1994 for (Item = hyperHead; Item != NULL; Item = Item->nextHyper) {
1995 if (Item->output && recNi <= Item->Var->maxRec) {
1996 if (!OutputHyperBuffer(outID,Item->Var->varNo,Item->Var->zVar,
1997 outMajority,recNo,1L,hyper.dimIndices,
1998 hyper.dimCounts,numDims,dimSizes,
1999 Item->Var->buffer,nValues,FALSE,
2000 Item->Var->nValueBytes,nRecordValues)) {
2001 FreeExportBuffers (exportHead);
2002 return FATALout;
2003 }
2004 if (AbortCDF(exportHead)) return SUCCESS;
2005 }
2006 }
2007 DisplayPctComplete (PCT(hyperN,nHypers,4,4), rvMsg);
2008 /***********************************************************************
2009 * Increment to next hyper group.
2010 ***********************************************************************/
2011 IncrHyperParms (&hyper,&groups,numDims,ROWmajor(inMajority),&nValues);
2012 }
2013 }
2014 FreeExportBuffers (exportHead);
2015 return SUCCESS;
2016 }
2017
2018 /******************************************************************************
2019 * ToCDFdiffOrZero.
2020 * Different dimensionalities or all with zero dimensions.
2021 * Returns SUCCESS, FATALin, or FATALout;
2022 ******************************************************************************/
2023
ToCDFdiffOrZero(inID,outID,firstRec,lastRec,outMajority,exportHead)2024 int ToCDFdiffOrZero (inID, outID, firstRec, lastRec, outMajority, exportHead)
2025 CDFid inID;
2026 CDFid outID;
2027 long firstRec;
2028 long lastRec;
2029 long outMajority;
2030 struct ItemStruct *exportHead;
2031 {
2032 int scalarCount, hyperCount, scalarX; size_t *nValueBytes;
2033 long recNo, nHypers, hyperN, nValues, recX, firstX, lastX, thisCount;
2034 long recF, recL; Byte ***handles; CDFstatus status;
2035 Logical filteringScalars; static Logical first = TRUE;
2036 struct ItemStruct *Item, *prevItem, *scalarHead, *scalarTail, *hyperHead;
2037 struct ItemStruct *hyperTail; struct GroupStruct groups;
2038 struct HyperStruct hyper;
2039 static char rvMsg[] = "Reading/writing variable values...";
2040 static char keyDefsAbort[] = "Abort: ________\n\n";
2041 /****************************************************************************
2042 * Encode key definitions first time.
2043 ****************************************************************************/
2044 if (first) {
2045 char *p1 = keyDefsAbort;
2046 EncodeKeyDefinitions (1, &p1, ABORTkey_EXPORT);
2047 first = FALSE;
2048 }
2049 /****************************************************************************
2050 * Read/write first (and only) record for NRV variables. Note that
2051 * if an item is being output it must be a variable.
2052 ****************************************************************************/
2053 switch (OutputNRVvalues(inID,outID,exportHead,FALSE,NULL,NULL,outMajority)) {
2054 case SUCCESS: break;
2055 case FATALin: return FATALin;
2056 case FATALout: return FATALout;
2057 }
2058 /****************************************************************************
2059 * Remove NRV variables and hyper variables not being output from export list.
2060 ****************************************************************************/
2061 for (Item = exportHead, prevItem = NULL;
2062 Item != NULL; Item = Item->nextExport) {
2063 if (!Item->Var->recVary || (!Item->Var->scalar && !Item->output)) {
2064 if (prevItem == NULL)
2065 exportHead = Item->nextExport;
2066 else
2067 prevItem->nextExport = Item->nextExport;
2068 }
2069 else
2070 prevItem = Item;
2071 }
2072 /****************************************************************************
2073 * Count scalars/hypers and allocate buffers for scalars.
2074 ****************************************************************************/
2075 for (Item = exportHead, scalarCount = 0, hyperCount = 0;
2076 Item != NULL; Item = Item->nextExport) {
2077 if (Item->Var->scalar)
2078 scalarCount++;
2079 else
2080 hyperCount++;
2081 }
2082 handles = (Byte ***) cdf_AllocateMemory (scalarCount * sizeof(Byte **),
2083 FatalError);
2084 nValueBytes = (size_t *) cdf_AllocateMemory (scalarCount * sizeof(size_t),
2085 FatalError);
2086 for (Item = exportHead, scalarX = 0, scalarHead = scalarTail = NULL,
2087 hyperHead = hyperTail = NULL, filteringScalars = FALSE;
2088 Item != NULL; Item = Item->nextExport) {
2089 if (Item->Var->scalar) {
2090 handles[scalarX] = &(Item->Var->buffer);
2091 nValueBytes[scalarX++] = Item->Var->nValueBytes;
2092 if (scalarHead == NULL)
2093 scalarHead = scalarTail = Item;
2094 else
2095 scalarTail = scalarTail->nextScalar = Item;
2096 Item->nextScalar = NULL;
2097 if (Item->filter) filteringScalars = TRUE;
2098 }
2099 else {
2100 if (hyperHead == NULL)
2101 hyperHead = hyperTail = Item;
2102 else
2103 hyperTail = hyperTail->nextHyper = Item;
2104 Item->nextHyper = NULL;
2105 Item->Var->buffer = NULL;
2106 }
2107 }
2108 /****************************************************************************
2109 * Preallocate variable records.
2110 ****************************************************************************/
2111 if (opt.preAllocate) {
2112 switch (PreAllocateRecords(inID,outID,scalarHead,
2113 hyperHead,&firstRec,&lastRec)) {
2114 case SUCCESS:
2115 break;
2116 case FATALin:
2117 if (handles != NULL) cdf_FreeMemory (handles, FatalError);
2118 if (nValueBytes != NULL) cdf_FreeMemory (nValueBytes, FatalError);
2119 return FATALin;
2120 case FATALout:
2121 if (handles != NULL) cdf_FreeMemory (handles, FatalError);
2122 if (nValueBytes != NULL) cdf_FreeMemory (nValueBytes, FatalError);
2123 return FATALout;
2124 }
2125 }
2126 /****************************************************************************
2127 * Allocate buffers for scalar variables. Note that if there were no scalar
2128 * variables the handles and value sizes would be NULL and one hyper would be
2129 * specified covering the entire range of input records.
2130 ****************************************************************************/
2131 DisplayPctComplete (NO_PCT, rvMsg);
2132 NEWkeyDEFS (EWkey, keyDefsAbort, batchMode)
2133 AllocateBuffers(lastRec - firstRec + 1, 0L, NULL, &groups, scalarCount, 0,
2134 handles, nValueBytes, ROWmajor(inMajority), 5, FatalError);
2135 if (handles != NULL) cdf_FreeMemory (handles, FatalError);
2136 if (nValueBytes != NULL) cdf_FreeMemory (nValueBytes, FatalError);
2137 /****************************************************************************
2138 * For each hyper...
2139 ****************************************************************************/
2140 InitHyperParms (&hyper, &groups, 0L, &nHypers, &nValues);
2141 for (hyperN = 0, recNo = 0; hyperN < nHypers; hyperN++) {
2142 /*************************************************************************
2143 * Hyper read scalar input variables.
2144 *************************************************************************/
2145 for (Item = scalarHead; Item != NULL; Item = Item->nextScalar) {
2146 status = HYPERget (inID, Item->Var->varN, Item->Var->zVar,
2147 firstRec + hyper.recNumber, hyper.recCount,
2148 dimIndices_0, dimCounts_1, Item->Var->buffer);
2149 DisplayStatus (status, readingCDF);
2150 if (StatusBAD(status)) {
2151 FreeExportBuffers (exportHead);
2152 return FATALin;
2153 }
2154 }
2155 DisplayPctComplete (PCT(hyperN,nHypers,1,2), rvMsg);
2156 if (AbortCDF(exportHead)) return SUCCESS;
2157 /**********************************************************************
2158 * Until no more records...
2159 **********************************************************************/
2160 for (recX = 0;;) {
2161 /**********************************************************************
2162 * Determine first record to be output.
2163 **********************************************************************/
2164 firstX = FindFirstRecord (recX, scalarHead, filteringScalars,
2165 hyper.recCount);
2166 if (firstX == NO_RECORD) break;
2167 /**********************************************************************
2168 * Determine last record to be output.
2169 **********************************************************************/
2170 lastX = FindLastRecord (firstX, scalarHead, filteringScalars,
2171 hyper.recCount);
2172 thisCount = lastX - firstX + 1;
2173 recF = firstRec + hyper.recNumber + firstX;
2174 recL = firstRec + hyper.recNumber + lastX; /* lastRec -> firstRec */
2175 /**********************************************************************
2176 * Hyper write to scalar output variables (being output).
2177 **********************************************************************/
2178 for (Item = scalarHead; Item != NULL; Item = Item->nextScalar) {
2179 if (Item->output) {
2180 if (recF <= Item->Var->maxRec) {
2181 long count = MINIMUM(recL,Item->Var->maxRec) - recF + 1;
2182 Byte *buffer = Item->Var->buffer +
2183 (size_t) (Item->Var->nValueBytes * firstX);
2184 status = HYPERput (outID, Item->Var->varNo, Item->Var->zVar,
2185 recNo, count, dimIndices_0, dimCounts_1,
2186 buffer);
2187 DisplayStatus (status, writingCDF);
2188 if (StatusBAD(status)) {
2189 FreeExportBuffers (exportHead);
2190 return FATALout;
2191 }
2192 }
2193 }
2194 }
2195 if (AbortCDF(exportHead)) return SUCCESS;
2196 /**********************************************************************
2197 * Hyper read/filter/write each hyper variable being output.
2198 **********************************************************************/
2199 for (Item = hyperHead; Item != NULL; Item = Item->nextHyper) {
2200 if (recF <= Item->Var->maxRec) {
2201 long count = MINIMUM(recL,Item->Var->maxRec) - recF + 1;
2202 struct GroupStruct groups1; Logical fullRecord1;
2203 Byte *buffer1, **handles1 = &buffer1; struct HyperStruct hyper1;
2204 long nHypers1, hyperN1, nValues1;
2205 size_t nValueBytes1 = Item->Var->nValueBytes;
2206 AllocateBuffers (count, Item->Var->numDims, Item->Var->dimSizes,
2207 &groups1, 0, 1, &handles1, &nValueBytes1,
2208 ROWmajor(inMajority), 5, FatalError);
2209 fullRecord1 = HyperFullRecord (&groups1, Item->Var->numDims);
2210 InitHyperParms (&hyper1, &groups1, Item->Var->numDims, &nHypers1,
2211 &nValues1);
2212 for (hyperN1 = 0; hyperN1 < nHypers1; hyperN1++) {
2213 status = HYPERget (inID, Item->Var->varN, Item->Var->zVar,
2214 recF + hyper1.recNumber, hyper1.recCount,
2215 hyper1.dimIndices, hyper1.dimCounts,
2216 buffer1);
2217 DisplayStatus (status, readingCDF);
2218 if (StatusBAD(status)) {
2219 FreeExportBuffers (exportHead);
2220 return FATALin;
2221 }
2222 if (Item->filter) FilterBuffer (Item, buffer1, nValues1);
2223 if (!OutputHyperBuffer(outID,Item->Var->varNo,Item->Var->zVar,
2224 outMajority,recNo + hyper1.recNumber,
2225 hyper1.recCount,hyper1.dimIndices,
2226 hyper1.dimCounts,Item->Var->numDims,
2227 Item->Var->dimSizes,buffer1,nValues1,
2228 fullRecord1,Item->Var->nValueBytes,
2229 Item->Var->nRecordValues)) {
2230 FreeExportBuffers (exportHead);
2231 return FATALout;
2232 }
2233 IncrHyperParms (&hyper1, &groups1, Item->Var->numDims,
2234 ROWmajor(inMajority), &nValues1);
2235 if (AbortCDF(exportHead)) return SUCCESS;
2236 }
2237 cdf_FreeMemory (buffer1, FatalError);
2238 }
2239 }
2240 /*******************************************************************
2241 * Increment to next...
2242 *******************************************************************/
2243 recNo += thisCount;
2244 recX = lastX + 1;
2245 if (recX == hyper.recCount) break;
2246 }
2247 DisplayPctComplete (PCT(hyperN,nHypers,2,2), rvMsg);
2248 /**********************************************************************
2249 * Increment to next hyper group.
2250 **********************************************************************/
2251 IncrHyperParms (&hyper, &groups, 0L, ROWmajor(inMajority), &nValues);
2252 }
2253 FreeExportBuffers (exportHead);
2254 return SUCCESS;
2255 }
2256
2257 /******************************************************************************
2258 * OutputNRVvalues.
2259 * Returns SUCCESS, FATALin, or FATALout;
2260 ******************************************************************************/
2261
OutputNRVvalues(inID,outID,exportHead,same,dimSizes,firstIndices,outMajority)2262 Logical OutputNRVvalues (inID, outID, exportHead, same, dimSizes,
2263 firstIndices, outMajority)
2264 CDFid inID;
2265 CDFid outID;
2266 struct ItemStruct *exportHead;
2267 Logical same; /* Same dimensionalities? */
2268 long dimSizes[]; /* N/a if different dimensionalities. */
2269 long firstIndices[]; /* N/a if different dimensionalities. */
2270 long outMajority;
2271 {
2272 long nrvCount, nrvAt, nHypers, hyperN, nRecordValues; size_t *nValueBytes;
2273 long phyDimSizes[CDF_MAX_DIMS], indicesI[CDF_MAX_DIMS], nValues;
2274 struct HyperStruct hyper; struct GroupStruct groups; struct ItemStruct *Item;
2275 Byte ***handles, *buffer; CDFstatus status; int dimN; Logical fullRecord;
2276 static char nrvMsg[] = "Reading/writing NRV variable values...";
2277 /****************************************************************************
2278 * Count number of NRV variables being output.
2279 ****************************************************************************/
2280 for (Item = exportHead, nrvCount=0; Item != NULL; Item = Item->nextExport) {
2281 if (NRVtoOUTPUT(Item) && Item->Var->maxRec == 0) nrvCount++;
2282 }
2283 DisplayPctComplete (NO_PCT, nrvMsg);
2284 /****************************************************************************
2285 * Output values for each NRV variable.
2286 ****************************************************************************/
2287 for (Item = exportHead, nrvAt = 0; Item != NULL; Item = Item->nextExport) {
2288 if (NRVtoOUTPUT(Item) && Item->Var->maxRec == 0) {
2289 /***********************************************************************
2290 * Allocate hyper buffer.
2291 ***********************************************************************/
2292 for (dimN = 0, nRecordValues = 1; dimN < Item->Var->numDims; dimN++) {
2293 if (Item->Var->dimVarys[dimN])
2294 phyDimSizes[dimN] = BOO(same,dimSizes[dimN],
2295 Item->Var->dimSizes[dimN]);
2296 else
2297 phyDimSizes[dimN] = 1;
2298 nRecordValues *= phyDimSizes[dimN];
2299 }
2300 handles = (Byte ***) cdf_AllocateMemory (sizeof(Byte **), FatalError);
2301 nValueBytes = (size_t *) cdf_AllocateMemory (sizeof(size_t), FatalError);
2302 handles[0] = &buffer;
2303 nValueBytes[0] = Item->Var->nValueBytes;
2304 AllocateBuffers (1L, Item->Var->numDims, phyDimSizes, &groups,
2305 0, 1, handles, nValueBytes, ROWmajor(inMajority),
2306 1, FatalError);
2307 cdf_FreeMemory (handles, FatalError);
2308 cdf_FreeMemory (nValueBytes, FatalError);
2309 /***********************************************************************
2310 * Perform each hyper read/filter/write(s).
2311 ***********************************************************************/
2312 fullRecord = HyperFullRecord (&groups, Item->Var->numDims);
2313 InitHyperParms (&hyper, &groups, Item->Var->numDims, &nHypers,
2314 &nValues);
2315 for (hyperN = 0; hyperN < nHypers; hyperN++) {
2316 /********************************************************************
2317 * Set indices for input CDF.
2318 ********************************************************************/
2319 for (dimN = 0; dimN < Item->Var->numDims; dimN++) {
2320 indicesI[dimN] = hyper.dimIndices[dimN] +
2321 BOO(same,firstIndices[dimN],0);
2322 }
2323 /********************************************************************
2324 * Read the buffer from the input CDF.
2325 ********************************************************************/
2326 status = HYPERget (inID, Item->Var->varN, Item->Var->zVar, 0L, 1L,
2327 indicesI, hyper.dimCounts, buffer);
2328 DisplayStatus (status, readingCDF);
2329 if (StatusBAD(status)) {
2330 cdf_FreeMemory (buffer, FatalError);
2331 return FATALin;
2332 }
2333 /********************************************************************
2334 * If this variable is being filtered, check each value in the
2335 * buffer. If a value fails the filter, replace it with the fill
2336 * value (if one is specified) or the pad value (if a fill value
2337 * is not specified).
2338 ********************************************************************/
2339 if (Item->filter) {
2340 FilterBuffer (Item, buffer, nValues);
2341 }
2342 /********************************************************************
2343 * Write the buffer to the output CDF.
2344 ********************************************************************/
2345 if (!OutputHyperBuffer(outID,Item->Var->varNo,Item->Var->zVar,
2346 outMajority,0L,1L,hyper.dimIndices,
2347 hyper.dimCounts,Item->Var->numDims,
2348 phyDimSizes,buffer,nValues,fullRecord,
2349 Item->Var->nValueBytes,nRecordValues)) {
2350 cdf_FreeMemory (buffer, FatalError);
2351 return FATALout;
2352 }
2353 /********************************************************************
2354 * Increment to the next hyper parameters.
2355 ********************************************************************/
2356 IncrHyperParms (&hyper, &groups, Item->Var->numDims,
2357 ROWmajor(inMajority), &nValues);
2358 }
2359 /***********************************************************************
2360 * Free hyper buffer.
2361 ***********************************************************************/
2362 cdf_FreeMemory (buffer, FatalError);
2363 /***********************************************************************
2364 * Update percent complete message.
2365 ***********************************************************************/
2366 DisplayPctComplete (PCT(nrvAt,nrvCount,1,1), nrvMsg);
2367 nrvAt++;
2368 }
2369 }
2370 return SUCCESS;
2371 }
2372
2373 /******************************************************************************
2374 * OutputHyperBuffer.
2375 * Returns FALSE if an error occurred.
2376 ******************************************************************************/
2377
OutputHyperBuffer(outID,varNo,zVar,outMajority,recNumber,recCount,dimIndices,dimCounts,numDims,dimSizes,buffer,nValues,fullRecord,nValueBytes,nRecordValues)2378 Logical OutputHyperBuffer (outID, varNo, zVar, outMajority, recNumber,
2379 recCount, dimIndices, dimCounts, numDims, dimSizes,
2380 buffer, nValues, fullRecord, nValueBytes,
2381 nRecordValues)
2382 CDFid outID;
2383 long varNo;
2384 Logical zVar;
2385 long outMajority;
2386 long recNumber;
2387 long recCount;
2388 long dimIndices[];
2389 long dimCounts[];
2390 long numDims;
2391 long dimSizes[];
2392 Byte *buffer;
2393 long nValues;
2394 Logical fullRecord;
2395 size_t nValueBytes;
2396 long nRecordValues;
2397 {
2398 CDFstatus status; long indicesO[CDF_MAX_DIMS], recX; Byte *value;
2399 /****************************************************************************
2400 * If majorities are the same use one hyper write.
2401 ****************************************************************************/
2402 if (outMajority == inMajority) {
2403 status = HYPERput (outID, varNo, zVar, recNumber, recCount, dimIndices,
2404 dimCounts, buffer);
2405 DisplayStatus (status, writingCDF);
2406 if (StatusBAD(status)) return FALSE;
2407 return TRUE;
2408 }
2409 /****************************************************************************
2410 * If majority can be switched use one hyper write.
2411 ****************************************************************************/
2412 if (fullRecord) {
2413 if (SwitchMajority(buffer,ROWmajor(inMajority),numDims,
2414 dimSizes,recCount,nValueBytes)) {
2415 status = HYPERput (outID, varNo, zVar, recNumber, recCount, dimIndices,
2416 dimCounts, buffer);
2417 DisplayStatus (status, writingCDF);
2418 if (StatusBAD(status)) return FALSE;
2419 return TRUE;
2420 }
2421 }
2422 /****************************************************************************
2423 * Otherwise use single writes.
2424 ****************************************************************************/
2425 ARRAYtoARRAY (indicesO, dimIndices, numDims)
2426 for (recX = 0, value = buffer; recX < recCount; recX++) {
2427 long nValuesX = BOO(fullRecord,nRecordValues,nValues), valueN;
2428 for (valueN = 0; valueN < nValuesX; valueN++, value += nValueBytes) {
2429 status = SINGLEput (outID, varNo, zVar, recNumber + recX, indicesO,
2430 value);
2431 DisplayStatus (status, writingCDF);
2432 if (StatusBAD(status)) return FALSE;
2433 if (ROWmajor(inMajority))
2434 INCRindicesROW (numDims, dimSizes, indicesO);
2435 else
2436 INCRindicesCOL (numDims, dimSizes, indicesO);
2437 }
2438 }
2439 return TRUE;
2440 }
2441
2442 /******************************************************************************
2443 * CopyAttributesANDgEntries.
2444 * Returns SUCCESS, FATALin, or FATALout;
2445 ******************************************************************************/
2446
CopyAttributesANDgEntries(inID,outID,nAttrs)2447 int CopyAttributesANDgEntries (inID, outID, nAttrs)
2448 CDFid inID;
2449 CDFid outID;
2450 long *nAttrs;
2451 {
2452 long attrN, scope, aNum; CDFstatus status;
2453 char attrName[CDF_ATTR_NAME_LEN+1];
2454 AOSs1A (pctMsg,"Creating attributes/global entries...")
2455 /****************************************************************************
2456 * Inquire number of attributes in input CDF.
2457 ****************************************************************************/
2458 DisplayPctComplete (NO_PCT, pctMsg[0]);
2459 status = CDFlib (SELECT_, CDF_, inID,
2460 GET_, CDF_NUMATTRS_, nAttrs,
2461 NULL_);
2462 DisplayStatus (status, readingCDF);
2463 if (StatusBAD(status)) return FATALin;
2464 /****************************************************************************
2465 * For each attribute in the input CDF create a corresponding attribute in
2466 * the output CDF.
2467 ****************************************************************************/
2468 for (attrN = 0; attrN < *nAttrs; attrN++) {
2469 /*************************************************************************
2470 * Read attribute information from input CDF.
2471 *************************************************************************/
2472 status = CDFlib (SELECT_, CDF_, inID,
2473 ATTR_, attrN,
2474 GET_, ATTR_NAME_, attrName,
2475 ATTR_SCOPE_, &scope,
2476 NULL_);
2477 DisplayStatus (status, readingCDF);
2478 if (StatusBAD(status)) return FATALin;
2479 /*************************************************************************
2480 * Create attribute in output CDF.
2481 *************************************************************************/
2482 status = CDFlib (SELECT_, CDF_, outID,
2483 CREATE_, ATTR_, attrName, scope, &aNum,
2484 NULL_);
2485 DisplayStatus (status, writingCDF);
2486 if (StatusBAD(status)) return FATALout;
2487 /*************************************************************************
2488 * If global-scope, also copy entries from the input CDF to the output CDF.
2489 *************************************************************************/
2490 if (scope == GLOBAL_SCOPE) {
2491 long maxEntry, entryN;
2492 /***********************************************************************
2493 * Inquire maximum gEntry number.
2494 ***********************************************************************/
2495 status = CDFlib (SELECT_, CDF_, inID,
2496 GET_, ATTR_MAXgENTRY_, &maxEntry,
2497 NULL_);
2498 DisplayStatus (status, readingCDF);
2499 if (StatusBAD(status)) return FATALin;
2500 /***********************************************************************
2501 * Copy each entry.
2502 ***********************************************************************/
2503 for (entryN = 0; entryN <= maxEntry; entryN++) {
2504 /********************************************************************
2505 * Confirm that this gEntry exists. If so, write the entry to the
2506 * output CDF.
2507 ********************************************************************/
2508 status = CDFlib (SELECT_, CDF_, inID,
2509 CONFIRM_, gENTRY_EXISTENCE_, entryN,
2510 NULL_);
2511 switch (status) {
2512 case NO_SUCH_ENTRY:
2513 break;
2514 default: {
2515 long dataType, numElems; void *buffer; size_t nBytes;
2516 DisplayStatus (status, readingCDF);
2517 if (StatusBAD(status)) return FATALin;
2518 /****************************************************************
2519 * Inquire the data type/number of elements from the input CDF.
2520 ****************************************************************/
2521 status = CDFlib (SELECT_, CDF_, inID,
2522 gENTRY_, entryN,
2523 GET_, gENTRY_DATATYPE_, &dataType,
2524 gENTRY_NUMELEMS_, &numElems,
2525 NULL_);
2526 DisplayStatus (status, readingCDF);
2527 if (StatusBAD(status)) return FATALin;
2528 /****************************************************************
2529 * Allocate a buffer for the entry value.
2530 ****************************************************************/
2531 nBytes = (size_t) (CDFelemSize(dataType) * numElems);
2532 buffer = cdf_AllocateMemory (nBytes, FatalError);
2533 /****************************************************************
2534 * Read the entry value from the input CDF.
2535 ****************************************************************/
2536 status = CDFlib (SELECT_, CDF_, inID,
2537 GET_, gENTRY_DATA_, buffer,
2538 NULL_);
2539 DisplayStatus (status, readingCDF);
2540 if (StatusBAD(status)) {
2541 cdf_FreeMemory (buffer, FatalError);
2542 return FATALin;
2543 }
2544 /****************************************************************
2545 * Write the entry to the output CDF.
2546 ****************************************************************/
2547 status = CDFlib (SELECT_, CDF_, outID,
2548 gENTRY_, entryN,
2549 PUT_, gENTRY_DATA_, dataType, numElems, buffer,
2550 NULL_);
2551 DisplayStatus (status, writingCDF);
2552 if (StatusBAD(status)) {
2553 cdf_FreeMemory (buffer, FatalError);
2554 return FATALout;
2555 }
2556 /****************************************************************
2557 * Free the buffer.
2558 ****************************************************************/
2559 cdf_FreeMemory (buffer, FatalError);
2560 break;
2561 }
2562 }
2563 }
2564 }
2565 /*************************************************************************
2566 * Update percentage complete message.
2567 *************************************************************************/
2568 DisplayPctComplete (PCT(attrN,*nAttrs,1,1), pctMsg[0]);
2569 }
2570 return SUCCESS;
2571 }
2572
2573 /******************************************************************************
2574 * CopyVariablesANDrzEntries.
2575 * Returns SUCCESS, FATALin, or FATALout;
2576 ******************************************************************************/
2577
CopyVariablesANDrzEntries(inID,outID,nAttrs,same,numDims,dimSizes,exportHead)2578 int CopyVariablesANDrzEntries (inID, outID, nAttrs, same, numDims, dimSizes,
2579 exportHead)
2580 CDFid inID;
2581 CDFid outID;
2582 long nAttrs;
2583 Logical same;
2584 long numDims;
2585 long dimSizes[];
2586 struct ItemStruct *exportHead;
2587 {
2588 struct ItemStruct *Item; CDFstatus status; int nVars, atVar;
2589 AOSs1A (pctMsg,"Creating variables/entries...")
2590 /****************************************************************************
2591 * Count number of variables being output.
2592 ****************************************************************************/
2593 DisplayPctComplete (NO_PCT, pctMsg[0]);
2594 for (Item = exportHead, nVars = 0; Item != NULL; Item = Item->nextExport) {
2595 if (Item->output) nVars++;
2596 }
2597 /****************************************************************************
2598 * Scan list of exported items for variables being output.
2599 ****************************************************************************/
2600 for (Item = exportHead, atVar = 0; Item != NULL; Item = Item->nextExport) {
2601 if (Item->output) {
2602 long attrN;
2603 /***********************************************************************
2604 * Create output variable.
2605 ***********************************************************************/
2606 if (Item->Var->zVar)
2607 status = CDFlib (SELECT_, CDF_, outID,
2608 CREATE_, zVAR_, Item->Var->name,
2609 Item->Var->dataType,
2610 Item->Var->numElems,
2611 BOO(same,numDims,Item->Var->numDims),
2612 BOO(same,dimSizes,
2613 Item->Var->dimSizes),
2614 Item->Var->recVary,
2615 Item->Var->dimVarys,
2616 &(Item->Var->varNo),
2617 NULL_);
2618 else
2619 status = CDFlib (SELECT_, CDF_, outID,
2620 CREATE_, rVAR_, Item->Var->name, Item->Var->dataType,
2621 Item->Var->numElems,
2622 Item->Var->recVary,
2623 Item->Var->dimVarys,
2624 &(Item->Var->varNo),
2625 NULL_);
2626 DisplayStatus (status, writingCDF);
2627 if (StatusBAD(status)) return FATALout;
2628 /***********************************************************************
2629 * If a pad value exists for the input variable, write it to the output
2630 * variable. Note that `Item->Var->pad' will always be non-NULL. It
2631 * points to either the variable's default (based on data type) or
2632 * explicit pad value.
2633 ***********************************************************************/
2634 status = CDFlib (SELECT_, CDF_, inID,
2635 BOO(Item->Var->zVar,
2636 zVAR_,rVAR_), Item->Var->varN,
2637 CONFIRM_, BOO(Item->Var->zVar,
2638 zVAR_PADVALUE_,rVAR_PADVALUE_),
2639 NULL_);
2640 switch (status) {
2641 case NO_PADVALUE_SPECIFIED:
2642 break;
2643 default:
2644 DisplayStatus (status, readingCDF);
2645 if (StatusBAD(status)) return FATALin;
2646 status = CDFlib (SELECT_, CDF_, outID,
2647 PUT_, BOO(Item->Var->zVar,
2648 zVAR_PADVALUE_,
2649 rVAR_PADVALUE_), Item->Var->pad,
2650 NULL_);
2651 DisplayStatus (status, writingCDF);
2652 if (StatusBAD(status)) return FATALout;
2653 break;
2654 }
2655 /***********************************************************************
2656 * Specify sparseness, compression, and blocking factor for output
2657 * variable.
2658 ***********************************************************************/
2659 status = CDFlib (SELECT_, CDF_, outID,
2660 PUT_, BOO(Item->Var->zVar,
2661 zVAR_SPARSERECORDS_,
2662 rVAR_SPARSERECORDS_),
2663 Item->Var->sRecordsType,
2664 BOO(Item->Var->zVar,
2665 zVAR_SPARSEARRAYS_,
2666 rVAR_SPARSEARRAYS_), Item->Var->sArraysType,
2667 Item->Var->sArraysParms,
2668 BOO(Item->Var->zVar,
2669 zVAR_COMPRESSION_,
2670 rVAR_COMPRESSION_), Item->Var->cType,
2671 Item->Var->cParms,
2672 BOO(Item->Var->zVar,
2673 zVAR_BLOCKINGFACTOR_,
2674 rVAR_BLOCKINGFACTOR_), Item->Var->blocking,
2675 NULL_);
2676 DisplayStatus (status, writingCDF);
2677 if (StatusBAD(status)) return FATALout;
2678 /***********************************************************************
2679 * Specify reserve percentage for output variable.
2680 ***********************************************************************/
2681 if (Item->Var->reserve != NA_RESERVE) {
2682 status = CDFlib (SELECT_, BOO(Item->Var->zVar,
2683 zVAR_RESERVEPERCENT_,
2684 rVAR_RESERVEPERCENT_),
2685 Item->Var->reserve,
2686 NULL_);
2687 DisplayStatus (status, writingCDF);
2688 if (StatusBAD(status)) return FATALout;
2689 }
2690 /***********************************************************************
2691 * Copy corresponding r/zEntries from the input CDF to the output CDF.
2692 ***********************************************************************/
2693 for (attrN = 0; attrN < nAttrs; attrN++) {
2694 long scope;
2695 /********************************************************************
2696 * Determine attribute name and scope.
2697 ********************************************************************/
2698 status = CDFlib (SELECT_, CDF_, inID,
2699 ATTR_, attrN,
2700 GET_, ATTR_SCOPE_, &scope,
2701 NULL_);
2702 DisplayStatus (status, readingCDF);
2703 if (StatusBAD(status)) return FATALin;
2704 /********************************************************************
2705 * If variable-scope, copy r/zEntry if it exists.
2706 ********************************************************************/
2707 if (scope == VARIABLE_SCOPE) {
2708 status = CDFlib (SELECT_, CDF_, inID,
2709 CONFIRM_, BOO(Item->Var->zVar,
2710 zENTRY_EXISTENCE_,
2711 rENTRY_EXISTENCE_), Item->Var->varN,
2712 NULL_);
2713 switch (status) {
2714 case NO_SUCH_ENTRY:
2715 break;
2716 default: {
2717 long dataType, numElems; void *buffer; size_t nBytes;
2718 DisplayStatus (status, readingCDF);
2719 if (StatusBAD(status)) return FATALin;
2720 /**************************************************************
2721 * Inquire the data type/number of elements from the input CDF.
2722 **************************************************************/
2723 status = CDFlib (SELECT_, CDF_, inID,
2724 BOO(Item->Var->zVar,
2725 zENTRY_,rENTRY_),Item->Var->varN,
2726 GET_, BOO(Item->Var->zVar,
2727 zENTRY_DATATYPE_,
2728 rENTRY_DATATYPE_), &dataType,
2729 BOO(Item->Var->zVar,
2730 zENTRY_NUMELEMS_,
2731 rENTRY_NUMELEMS_), &numElems,
2732 NULL_);
2733 DisplayStatus (status, readingCDF);
2734 if (StatusBAD(status)) return FATALin;
2735 /**************************************************************
2736 * Allocate a buffer for the entry value.
2737 **************************************************************/
2738 nBytes = (size_t) (CDFelemSize(dataType) * numElems);
2739 buffer = cdf_AllocateMemory (nBytes, FatalError);
2740 /**************************************************************
2741 * Read the entry value from the input CDF.
2742 **************************************************************/
2743 status = CDFlib (SELECT_, CDF_, inID,
2744 GET_, BOO(Item->Var->zVar,
2745 zENTRY_DATA_,rENTRY_DATA_), buffer,
2746 NULL_);
2747 DisplayStatus (status, readingCDF);
2748 if (StatusBAD(status)) {
2749 cdf_FreeMemory (buffer, FatalError);
2750 return FATALin;
2751 }
2752 /**************************************************************
2753 * Write the entry to the output CDF.
2754 **************************************************************/
2755 status = CDFlib (SELECT_, CDF_, outID,
2756 ATTR_, attrN,
2757 BOO(Item->Var->zVar,
2758 zENTRY_,
2759 rENTRY_), Item->Var->varNo,
2760 PUT_, BOO(Item->Var->zVar,
2761 zENTRY_DATA_,
2762 rENTRY_DATA_), dataType, numElems,
2763 buffer,
2764 NULL_);
2765 DisplayStatus (status, writingCDF);
2766 if (StatusBAD(status)) {
2767 cdf_FreeMemory (buffer, FatalError);
2768 return FATALout;
2769 }
2770 /**************************************************************
2771 * Free the buffer.
2772 **************************************************************/
2773 cdf_FreeMemory (buffer, FatalError);
2774 break;
2775 }
2776 }
2777 }
2778 }
2779 /***********************************************************************
2780 * Update percentage complete message.
2781 ***********************************************************************/
2782 DisplayPctComplete (PCT(atVar,nVars,1,1), pctMsg[0]);
2783 atVar++;
2784 }
2785 }
2786 return SUCCESS;
2787 }
2788
2789 /******************************************************************************
2790 * FirstLastRecord.
2791 * Returns: FATAL if a fatal error occurred,
2792 * FAILED if the output/listing should not continue, or
2793 * PASSED if the output/listing should continue.
2794 * The existence of at least one record in the CDF is assumed.
2795 ******************************************************************************/
2796
FirstLastRecord(firstRec,lastRec,toCDF,exportHead)2797 int FirstLastRecord (firstRec, lastRec, toCDF, exportHead)
2798 long *firstRec;
2799 long *lastRec;
2800 Logical toCDF;
2801 struct ItemStruct *exportHead;
2802 {
2803 CDFstatus status; long rMaxRec, zMaxRec; struct ItemStruct *Item;
2804 static char noRecordsMsg[] = "No records in valid range.";
2805 /****************************************************************************
2806 * Inquire maximum r/zRecord.
2807 ****************************************************************************/
2808 status = CDFlib (GET_, rVARs_MAXREC_, &rMaxRec,
2809 zVARs_MAXREC_, &zMaxRec,
2810 NULL_);
2811 DisplayStatus (status, readingCDF);
2812 if (StatusBAD(status)) return FATAL;
2813 /****************************************************************************
2814 * Set first and last records based on number of records in CDF.
2815 ****************************************************************************/
2816 *firstRec = 0;
2817 *lastRec = MAXIMUM(rMaxRec,zMaxRec);
2818 /****************************************************************************
2819 * If filters are disabled or filtered lines are to be shown (and output is
2820 * not to a CDF), return now.
2821 ****************************************************************************/
2822 if (!opt.overallFilter) return PASSED;
2823 if (opt.showFiltered && !toCDF) return PASSED;
2824 /****************************************************************************
2825 * Scan list of exported items.
2826 ****************************************************************************/
2827 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
2828 switch (Item->type) {
2829 case RECORDt:
2830 if (Item->filter) {
2831 if (Item->Record->min != NOminMax) {
2832 /*****************************************************************
2833 * Check if last record passes minimum filter value.
2834 *****************************************************************/
2835 if (!RecordPassesMin(Item,*lastRec)) {
2836 DisplayMessage (noRecordsMsg, BEEPWAIT1);
2837 return FAILED;
2838 }
2839 /*****************************************************************
2840 * Reset first record based on minimum filter value.
2841 *****************************************************************/
2842 *firstRec = MaxLong(*firstRec,BOO(Item->inclusive,
2843 Item->Record->min,
2844 Item->Record->min + 1));
2845 }
2846 if (Item->Record->max != NOminMax) {
2847 /*****************************************************************
2848 * Check if first record passes maximum filter value.
2849 *****************************************************************/
2850 if (!RecordPassesMax(Item,*firstRec)) {
2851 DisplayMessage (noRecordsMsg, BEEPWAIT1);
2852 return FAILED;
2853 }
2854 /*****************************************************************
2855 * Reset last record based on maximum filter value.
2856 *****************************************************************/
2857 *lastRec = MinLong(*lastRec,BOO(Item->inclusive,
2858 Item->Record->max,
2859 Item->Record->max - 1));
2860 }
2861 Item->filter = FALSE;
2862 }
2863 break;
2864 case VARIABLEt:
2865 if (Item->filter) {
2866 if (Item->Var->scalar) {
2867 if (Item->Var->monotonic == UNKNOWNmono) {
2868 if (!SetVarMonotonicity(Item->Var)) return FATAL;
2869 }
2870 switch (Item->Var->monotonic) {
2871 case INCREASEmono:
2872 /*************************************************************
2873 * Check if a minimum filter value exists.
2874 *************************************************************/
2875 if (Item->Var->min != NULL) {
2876 /***********************************************************
2877 * Check if scalar value at last record passes minimum filter
2878 * value.
2879 ***********************************************************/
2880 if (!ReadScalarValue(Item->Var,*lastRec)) return FATAL;
2881 if (!VarPassesMin(Item,Item->Var->value)) {
2882 DisplayMessage (noRecordsMsg, BEEPWAIT1);
2883 return FAILED;
2884 }
2885 /***********************************************************
2886 * Increment first record until it either reaches the last
2887 * record or passes the minimum filter value.
2888 ***********************************************************/
2889 while (*firstRec < *lastRec) {
2890 if (!ReadScalarValue(Item->Var,*firstRec)) return FATAL;
2891 if (VarPassesMin(Item,Item->Var->value)) break;
2892 (*firstRec)++;
2893 }
2894 }
2895 /*************************************************************
2896 * Check if a maximum filter value exists.
2897 *************************************************************/
2898 if (Item->Var->max != NULL) {
2899 /***********************************************************
2900 * Check if scalar value at first record passes maximum
2901 * filter value.
2902 ***********************************************************/
2903 if (!ReadScalarValue(Item->Var,*firstRec)) return FATAL;
2904 if (!VarPassesMax(Item,Item->Var->value)) {
2905 DisplayMessage (noRecordsMsg, BEEPWAIT1);
2906 return FAILED;
2907 }
2908 /***********************************************************
2909 * Decrement last record until it either reaches the first
2910 * record or passes the maximum filter value.
2911 ***********************************************************/
2912 while (*lastRec > *firstRec) {
2913 if (!ReadScalarValue(Item->Var,*lastRec)) return FATAL;
2914 if (VarPassesMax(Item,Item->Var->value)) break;
2915 (*lastRec)--;
2916 }
2917 }
2918 Item->filter = FALSE;
2919 break;
2920 case DECREASEmono:
2921 if (Item->Var->min != NULL) {
2922 /***********************************************************
2923 * Check if scalar value at first record passes minimum
2924 * filter value.
2925 ***********************************************************/
2926 if (!ReadScalarValue(Item->Var,*firstRec)) return FATAL;
2927 if (!VarPassesMin(Item,Item->Var->value)) {
2928 DisplayMessage (noRecordsMsg, BEEPWAIT1);
2929 return FAILED;
2930 }
2931 /***********************************************************
2932 * Decrement last record until it either reaches the first
2933 * record or passes the minimum filter value.
2934 ***********************************************************/
2935 while (*lastRec > *firstRec) {
2936 if (!ReadScalarValue(Item->Var,*lastRec)) return FATAL;
2937 if (VarPassesMin(Item,Item->Var->value)) break;
2938 (*lastRec)--;
2939 }
2940 }
2941 /*************************************************************
2942 * Check if a maximum filter value exists.
2943 *************************************************************/
2944 if (Item->Var->max != NULL) {
2945 /***********************************************************
2946 * Check if scalar value at last record passes maximum filter
2947 * value.
2948 ***********************************************************/
2949 if (!ReadScalarValue(Item->Var,*lastRec)) return FATAL;
2950 if (!VarPassesMax(Item,Item->Var->value)) {
2951 DisplayMessage (noRecordsMsg, BEEPWAIT1);
2952 return FAILED;
2953 }
2954 /***********************************************************
2955 * Increment first record until it either reaches the last
2956 * record or passes the maximum filter value.
2957 ***********************************************************/
2958 while (*firstRec < *lastRec) {
2959 if (!ReadScalarValue(Item->Var,*firstRec)) return FATAL;
2960 if (VarPassesMax(Item,Item->Var->value)) break;
2961 (*firstRec)++;
2962 }
2963 }
2964 Item->filter = FALSE;
2965 break;
2966 }
2967 }
2968 }
2969 break;
2970 }
2971 }
2972 return PASSED;
2973 }
2974
2975 /******************************************************************************
2976 * FirstLastIndices.
2977 * Returns: FATAL if a fatal error occurred,
2978 * FAILED if the output/listing should not continue, or
2979 * PASSED if the output/listing should continue.
2980 * The existence of at least one record in the CDF is assumed.
2981 ******************************************************************************/
2982
FirstLastIndices(numDims,dimSizes,firstIndices,lastIndices,nValues,toCDF,exportHead)2983 int FirstLastIndices (numDims, dimSizes, firstIndices, lastIndices, nValues,
2984 toCDF, exportHead)
2985 long numDims;
2986 long dimSizes[];
2987 long firstIndices[];
2988 long lastIndices[];
2989 long *nValues; /* NULL if not requested. */
2990 Logical toCDF;
2991 struct ItemStruct *exportHead;
2992 {
2993 int dimN; struct ItemStruct *Item;
2994 static char noIndicesMsg[] = "No indices in valid range.";
2995 /****************************************************************************
2996 * Set first and last indices based on dimensionality.
2997 ****************************************************************************/
2998 for (dimN = 0; dimN < numDims; dimN++) {
2999 firstIndices[dimN] = 0;
3000 lastIndices[dimN] = dimSizes[dimN] - 1;
3001 }
3002 /****************************************************************************
3003 * If filters are disabled or filtered lines are to be shown (and output is
3004 * not to a CDF), return now.
3005 ****************************************************************************/
3006 if (!opt.overallFilter) return PASSED;
3007 if (opt.showFiltered && !toCDF) return PASSED;
3008 /****************************************************************************
3009 * Scan list of exported items.
3010 ****************************************************************************/
3011 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
3012 switch (Item->type) {
3013 case INDICESt: {
3014 if (Item->filter) {
3015 if (Item->Indices->minNumDims != NOminMax) {
3016 /*****************************************************************
3017 * Check if last indices pass minimum filter value.
3018 *****************************************************************/
3019 if (!IndicesPassMin(Item,lastIndices)) {
3020 DisplayMessage (noIndicesMsg, BEEPWAIT1);
3021 return FAILED;
3022 }
3023 /*****************************************************************
3024 * Reset first indices based on minimum filter value.
3025 *****************************************************************/
3026 for (dimN = 0; dimN < numDims; dimN++) {
3027 firstIndices[dimN] = MaxLong(firstIndices[dimN],
3028 BOO(Item->inclusive,
3029 Item->Indices->minIndices[dimN],
3030 Item->Indices->minIndices[dimN] + 1));
3031 }
3032 }
3033 if (Item->Indices->maxNumDims != NOminMax) {
3034 /*****************************************************************
3035 * Check if first indices pass maximum filter value.
3036 *****************************************************************/
3037 if (!IndicesPassMax(Item,firstIndices)) {
3038 DisplayMessage (noIndicesMsg, BEEPWAIT1);
3039 return FAILED;
3040 }
3041 /*****************************************************************
3042 * Reset last indices based on maximum filter value.
3043 *****************************************************************/
3044 for (dimN = 0; dimN < numDims; dimN++) {
3045 lastIndices[dimN] = MinLong(lastIndices[dimN],
3046 BOO(Item->inclusive,
3047 Item->Indices->maxIndices[dimN],
3048 Item->Indices->maxIndices[dimN]-1));
3049 }
3050 }
3051 Item->filter = FALSE;
3052 }
3053 break;
3054 }
3055 case VARIABLEt:
3056 if (Item->filter) {
3057 if (DimensionalVariable(Item->Var,&dimN)) {
3058 if (Item->Var->monotonic == UNKNOWNmono) {
3059 if (!SetVarMonotonicity(Item->Var)) return FATAL;
3060 }
3061 switch (Item->Var->monotonic) {
3062 case INCREASEmono:
3063 /*************************************************************
3064 * Check if a minimum filter value exists.
3065 *************************************************************/
3066 if (Item->Var->min != NULL) {
3067 /***********************************************************
3068 * Check if value at last index passes minimum filter value.
3069 ***********************************************************/
3070 if (!ReadDimensionalValue(Item->Var,
3071 lastIndices)) return FATAL;
3072 if (!VarPassesMin(Item,Item->Var->value)) {
3073 DisplayMessage (noIndicesMsg, BEEPWAIT1);
3074 return FAILED;
3075 }
3076 /***********************************************************
3077 * Increment first index until it either reaches the last
3078 * index or passes the minimum filter value.
3079 ***********************************************************/
3080 while (firstIndices[dimN] < lastIndices[dimN]) {
3081 if (!ReadDimensionalValue(Item->Var,
3082 firstIndices)) return FATAL;
3083 if (VarPassesMin(Item,Item->Var->value)) break;
3084 firstIndices[dimN]++;
3085 }
3086 }
3087 /*************************************************************
3088 * Check if a maximum filter value exists.
3089 *************************************************************/
3090 if (Item->Var->max != NULL) {
3091 /***********************************************************
3092 * Check if value at first index passes maximum filter value.
3093 ***********************************************************/
3094 if (!ReadDimensionalValue(Item->Var,
3095 firstIndices)) return FATAL;
3096 if (!VarPassesMax(Item,Item->Var->value)) {
3097 DisplayMessage (noIndicesMsg, BEEPWAIT1);
3098 return FAILED;
3099 }
3100 /***********************************************************
3101 * Decrement last index until it either reaches the first
3102 * index or passes the maximum filter value.
3103 ***********************************************************/
3104 while (lastIndices[dimN] > firstIndices[dimN]) {
3105 if (!ReadDimensionalValue(Item->Var,
3106 lastIndices)) return FATAL;
3107 if (VarPassesMax(Item,Item->Var->value)) break;
3108 lastIndices[dimN]--;
3109 }
3110 }
3111 Item->filter = FALSE;
3112 break;
3113 case DECREASEmono:
3114 if (Item->Var->min != NULL) {
3115 /***********************************************************
3116 * Check if value at first index passes minimum filter value.
3117 ***********************************************************/
3118 if (!ReadDimensionalValue(Item->Var,
3119 firstIndices)) return FATAL;
3120 if (!VarPassesMin(Item,Item->Var->value)) {
3121 DisplayMessage (noIndicesMsg, BEEPWAIT1);
3122 return FAILED;
3123 }
3124 /***********************************************************
3125 * Decrement last index until it either reaches the first
3126 * index or passes the minimum filter value.
3127 ***********************************************************/
3128 while (lastIndices[dimN] > firstIndices[dimN]) {
3129 if (!ReadDimensionalValue(Item->Var,
3130 lastIndices)) return FATAL;
3131 if (VarPassesMin(Item,Item->Var->value)) break;
3132 lastIndices[dimN]--;
3133 }
3134 }
3135 /*************************************************************
3136 * Check if a maximum filter value exists.
3137 *************************************************************/
3138 if (Item->Var->max != NULL) {
3139 /***********************************************************
3140 * Check if value at last index passes maximum filter value.
3141 ***********************************************************/
3142 if (!ReadDimensionalValue(Item->Var,
3143 lastIndices)) return FATAL;
3144 if (!VarPassesMax(Item,Item->Var->value)) {
3145 DisplayMessage (noIndicesMsg, BEEPWAIT1);
3146 return FAILED;
3147 }
3148 /***********************************************************
3149 * Increment first index until it either reaches the last
3150 * index or passes the maximum filter value.
3151 ***********************************************************/
3152 while (firstIndices[dimN] < lastIndices[dimN]) {
3153 if (!ReadDimensionalValue(Item->Var,
3154 firstIndices)) return FATAL;
3155 if (VarPassesMax(Item,Item->Var->value)) break;
3156 firstIndices[dimN]++;
3157 }
3158 }
3159 Item->filter = FALSE;
3160 break;
3161 }
3162 }
3163 }
3164 break;
3165 }
3166 }
3167 /****************************************************************************
3168 * Recalculate number of values.
3169 ****************************************************************************/
3170 if (nValues != NULL) {
3171 for (*nValues = 1, dimN = 0; dimN < numDims; dimN++) {
3172 *nValues *= (lastIndices[dimN] - firstIndices[dimN] + 1);
3173 }
3174 }
3175 return PASSED;
3176 }
3177
3178 /******************************************************************************
3179 * ScalarVariable.
3180 ******************************************************************************/
3181
ScalarVariable(Var)3182 Logical ScalarVariable (Var)
3183 struct VarStruct *Var;
3184 {
3185 switch (Var->numDims) {
3186 case 0:
3187 return TRUE;
3188 default: {
3189 int dimN;
3190 for (dimN = 0; dimN < Var->numDims; dimN++) {
3191 if (Var->dimVarys[dimN] && Var->dimSizes[dimN] > 1) return FALSE;
3192 }
3193 return TRUE;
3194 }
3195 }
3196 }
3197
3198 /******************************************************************************
3199 * DimensionalVariable.
3200 ******************************************************************************/
3201
DimensionalVariable(Var,dimN)3202 Logical DimensionalVariable (Var, dimN)
3203 struct VarStruct *Var;
3204 int *dimN;
3205 {
3206 int dimNt, count;
3207 if (Var->recVary) return FALSE;
3208 if (Var->numDims == 0) return FALSE;
3209 for (count = 0, dimNt = 0; dimNt < Var->numDims; dimNt++) {
3210 if (Var->dimVarys[dimNt]) {
3211 *dimN = dimNt;
3212 count++;
3213 }
3214 }
3215 return (count == 1);
3216 }
3217
3218 /******************************************************************************
3219 * OneDimensionVaries.
3220 ******************************************************************************/
3221
OneDimensionVaries(Var)3222 Logical OneDimensionVaries (Var)
3223 struct VarStruct *Var;
3224 {
3225 int dimN, count = 0;
3226 if (Var->recVary) count++;
3227 for (dimN = 0; dimN < Var->numDims; dimN++) {
3228 if (Var->dimVarys[dimN]) count++;
3229 }
3230 return (count == 1);
3231 }
3232
3233 /******************************************************************************
3234 * ReadScalarValue.
3235 ******************************************************************************/
3236
ReadScalarValue(Var,recN)3237 Logical ReadScalarValue (Var, recN)
3238 struct VarStruct *Var;
3239 long recN;
3240 {
3241 static long indices[CDF_MAX_DIMS] = { 0,0,0,0,0,0,0,0,0,0 };
3242 CDFstatus status;
3243 status = CDFlib (SELECT_, BOO(Var->zVar,zVAR_,rVAR_), Var->varN,
3244 BOO(Var->zVar,zVAR_RECNUMBER_,
3245 rVARs_RECNUMBER_), recN,
3246 BOO(Var->zVar,zVAR_DIMINDICES_,
3247 rVARs_DIMINDICES_), indices,
3248 GET_, BOO(Var->zVar,zVAR_DATA_,rVAR_DATA_), Var->value,
3249 NULL_);
3250 DisplayStatus (status, readingCDF);
3251 if (StatusBAD(status)) return FALSE;
3252 return TRUE;
3253 }
3254
3255 /******************************************************************************
3256 * ReadDimensionalValue.
3257 ******************************************************************************/
3258
ReadDimensionalValue(Var,indices)3259 Logical ReadDimensionalValue (Var, indices)
3260 struct VarStruct *Var;
3261 long indices[];
3262 {
3263 CDFstatus status;
3264 status = CDFlib (SELECT_, BOO(Var->zVar,zVAR_,rVAR_), Var->varN,
3265 BOO(Var->zVar,zVAR_RECNUMBER_,
3266 rVARs_RECNUMBER_), 0L,
3267 BOO(Var->zVar,zVAR_DIMINDICES_,
3268 rVARs_DIMINDICES_), indices,
3269 GET_, BOO(Var->zVar,zVAR_DATA_,rVAR_DATA_), Var->value,
3270 NULL_);
3271 DisplayStatus (status, readingCDF);
3272 if (StatusBAD(status)) return FALSE;
3273 return TRUE;
3274 }
3275
3276 /******************************************************************************
3277 * ValidFormat.
3278 ******************************************************************************/
3279
ValidFormat(format)3280 Logical ValidFormat (format)
3281 char *format;
3282 {
3283 if (NULstring(format)) return FALSE;
3284 return TRUE;
3285 }
3286
3287 /******************************************************************************
3288 * SameDimensionalities.
3289 ******************************************************************************/
3290
SameDimensionalities(numDims,dimSizes,exportHead)3291 Logical SameDimensionalities (numDims, dimSizes, exportHead)
3292 long *numDims;
3293 long dimSizes[];
3294 struct ItemStruct *exportHead;
3295 {
3296 struct ItemStruct *Item; Logical first = TRUE; int n;
3297 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
3298 if (Item->type == VARIABLEt && (Item->output || Item->filter)) {
3299 if (first) {
3300 *numDims = Item->Var->numDims;
3301 for (n = 0; n < *numDims; n++) dimSizes[n] = Item->Var->dimSizes[n];
3302 first = FALSE;
3303 }
3304 else {
3305 if (Item->Var->numDims != *numDims) return FALSE;
3306 for (n = 0; n < *numDims; n++) {
3307 if (Item->Var->dimSizes[n] != dimSizes[n]) return FALSE;
3308 }
3309 }
3310 }
3311 }
3312 return TRUE;
3313 }
3314
3315 /******************************************************************************
3316 * ValidateRecordIndices.
3317 ******************************************************************************/
3318
ValidateRecordIndices(type,same,numDims,exportHead)3319 void ValidateRecordIndices (type, same, numDims, exportHead)
3320 int type; /* Output type. */
3321 Logical same; /* Ignored if horizontal mode. */
3322 long numDims; /* Ignored if horizontal mode. */
3323 struct ItemStruct *exportHead;
3324 {
3325 struct ItemStruct *Item; int dimN;
3326 static char recordMsgOUT[] = {
3327 "`Record' not allowed for output."
3328 };
3329 static char indicesMsgODD[] = {
3330 "`Indices' not allowed for output (different dimensionalities)."
3331 };
3332 static char indicesMsgFDD[] = {
3333 "`Indices' not allowed for filtering (different dimensionalities)."
3334 };
3335 static char indicesMsgMIN[] = {
3336 "Wrong number of dimensions for minimum `Indices' filter."
3337 };
3338 static char indicesMsgMAX[] = {
3339 "Wrong number of dimensions for maximum `Indices' filter."
3340 };
3341 static char indicesMsgGT[] = {
3342 "Minimum `Indices' filter index is greater than maximum index."
3343 };
3344 static char indicesMsgOHM[] = {
3345 "`Indices' not allowed for output (horizontal mode)."
3346 };
3347 static char indicesMsgFHM[] = {
3348 "`Indices' not allowed for filtering (horizontal mode)."
3349 };
3350 static char indicesMsgOZD[] = {
3351 "`Indices' not allowed for output (zero dimensions)."
3352 };
3353 static char indicesMsgFZD[] = {
3354 "`Indices' not allowed for filtering (zero dimensions)."
3355 };
3356 static char indicesMsgOUT[] = {
3357 "`Indices' not allowed for output."
3358 };
3359 /****************************************************************************
3360 * Search list of exported items for `Record'.
3361 ****************************************************************************/
3362 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
3363 if (Item->type == RECORDt) {
3364 if (Item->output) {
3365 if (type == OUTPUTtoCDF) {
3366 DisplayMessage (recordMsgOUT, NOBEEPWAIT1);
3367 Item->output = FALSE;
3368 }
3369 }
3370 break;
3371 }
3372 }
3373 /****************************************************************************
3374 * Search list of exported items for `Indices'.
3375 ****************************************************************************/
3376 for (Item = exportHead; Item != NULL; Item = Item->nextExport) {
3377 if (Item->type == INDICESt) {
3378 switch (type) {
3379 case OUTPUTtoSCREENh:
3380 case OUTPUTtoFILEh:
3381 /*********************************************************************
3382 * Output not allowed in horizontal mode.
3383 *********************************************************************/
3384 if (Item->output) {
3385 DisplayMessage (indicesMsgOHM, NOBEEPWAIT1);
3386 Item->output = FALSE;
3387 }
3388 /*********************************************************************
3389 * Filtering not allowed in horizontal mode.
3390 *********************************************************************/
3391 if (Item->filter) {
3392 DisplayMessage (indicesMsgFHM, NOBEEPWAIT1);
3393 Item->filter = FALSE;
3394 }
3395 break;
3396 case OUTPUTtoSCREENv:
3397 case OUTPUTtoFILEv:
3398 if (same) {
3399 if (Item->output) {
3400 /*****************************************************************
3401 * Output not allowed if zero dimensions.
3402 *****************************************************************/
3403 if (numDims == 0) {
3404 DisplayMessage (indicesMsgOZD, NOBEEPWAIT1);
3405 Item->output = FALSE;
3406 }
3407 }
3408 if (Item->filter) {
3409 Logical checkGT = TRUE;
3410 /*****************************************************************
3411 * Filtering not allowed if zero dimensions.
3412 *****************************************************************/
3413 if (numDims == 0) {
3414 DisplayMessage (indicesMsgFZD, NOBEEPWAIT1);
3415 Item->filter = FALSE;
3416 }
3417 /*****************************************************************
3418 * Filtering not allowed if wrong number of indices (minimum).
3419 *****************************************************************/
3420 if (Item->Indices->minNumDims != NOminMax) {
3421 if (Item->Indices->minNumDims != numDims) {
3422 DisplayMessage (indicesMsgMIN, NOBEEPWAIT1);
3423 Item->filter = FALSE;
3424 checkGT = FALSE;
3425 }
3426 }
3427 /*****************************************************************
3428 * Filtering not allowed if wrong number of indices (maximum).
3429 *****************************************************************/
3430 if (Item->Indices->maxNumDims != NOminMax) {
3431 if (Item->Indices->maxNumDims != numDims) {
3432 DisplayMessage (indicesMsgMAX, NOBEEPWAIT1);
3433 Item->filter = FALSE;
3434 checkGT = FALSE;
3435 }
3436 }
3437 /*****************************************************************
3438 * Filtering not allowed if minimum greater than maximum.
3439 *****************************************************************/
3440 if (Item->Indices->minNumDims != NOminMax &&
3441 Item->Indices->maxNumDims != NOminMax && checkGT) {
3442 for (dimN = 0; dimN < numDims; dimN++) {
3443 if (Item->Indices->minIndices[dimN] >
3444 Item->Indices->maxIndices[dimN]) {
3445 DisplayMessage (indicesMsgGT, NOBEEPWAIT1);
3446 Item->filter = FALSE;
3447 }
3448 }
3449 }
3450 }
3451 }
3452 else {
3453 /*******************************************************************
3454 * Output not allowed if different dimensionalities.
3455 *******************************************************************/
3456 if (Item->output) {
3457 DisplayMessage (indicesMsgODD, NOBEEPWAIT1);
3458 Item->output = FALSE;
3459 }
3460 /*******************************************************************
3461 * Filtering not allowed if different dimensionalities.
3462 *******************************************************************/
3463 if (Item->filter) {
3464 DisplayMessage (indicesMsgFDD, NOBEEPWAIT1);
3465 Item->filter = FALSE;
3466 }
3467 }
3468 break;
3469 case OUTPUTtoCDF:
3470 /*********************************************************************
3471 * Output not allowed.
3472 *********************************************************************/
3473 if (Item->output) {
3474 DisplayMessage (indicesMsgOUT, NOBEEPWAIT1);
3475 Item->output = FALSE;
3476 }
3477 if (same) {
3478 if (Item->filter) {
3479 Logical checkGT = TRUE;
3480 /*****************************************************************
3481 * Filtering not allowed if zero dimensions.
3482 *****************************************************************/
3483 if (numDims == 0) {
3484 DisplayMessage (indicesMsgFZD, NOBEEPWAIT1);
3485 Item->filter = FALSE;
3486 }
3487 /*****************************************************************
3488 * Filtering not allowed if wrong number of indices (minimum).
3489 *****************************************************************/
3490 if (Item->Indices->minNumDims != NOminMax) {
3491 if (Item->Indices->minNumDims != numDims) {
3492 DisplayMessage (indicesMsgMIN, NOBEEPWAIT1);
3493 Item->filter = FALSE;
3494 checkGT = FALSE;
3495 }
3496 }
3497 /*****************************************************************
3498 * Filtering not allowed if wrong number of indices (maximum).
3499 *****************************************************************/
3500 if (Item->Indices->maxNumDims != NOminMax) {
3501 if (Item->Indices->maxNumDims != numDims) {
3502 DisplayMessage (indicesMsgMAX, NOBEEPWAIT1);
3503 Item->filter = FALSE;
3504 checkGT = FALSE;
3505 }
3506 }
3507 /*****************************************************************
3508 * Filtering not allowed if minimum greater than maximum.
3509 *****************************************************************/
3510 if (Item->Indices->minNumDims != NOminMax &&
3511 Item->Indices->maxNumDims != NOminMax && checkGT) {
3512 for (dimN = 0; dimN < numDims; dimN++) {
3513 if (Item->Indices->minIndices[dimN] >
3514 Item->Indices->maxIndices[dimN]) {
3515 DisplayMessage (indicesMsgGT, NOBEEPWAIT1);
3516 Item->filter = FALSE;
3517 }
3518 }
3519 }
3520 }
3521 }
3522 else {
3523 /*******************************************************************
3524 * Filtering not allowed if different dimensionalities.
3525 *******************************************************************/
3526 if (Item->filter) {
3527 DisplayMessage (indicesMsgFDD, NOBEEPWAIT1);
3528 Item->filter = FALSE;
3529 }
3530 }
3531 break;
3532 }
3533 break;
3534 }
3535 }
3536 return;
3537 }
3538
3539 /******************************************************************************
3540 * RecordPassesMin.
3541 * It is assumed that overall filtered and filtering for the `Record' item
3542 * are both enabled.
3543 ******************************************************************************/
3544
RecordPassesMin(Item,recN)3545 Logical RecordPassesMin (Item, recN)
3546 struct ItemStruct *Item;
3547 long recN;
3548 {
3549 if (Item->Record->min == NOminMax) return TRUE;
3550 if (BOO(Item->inclusive,
3551 recN >= Item->Record->min,
3552 recN > Item->Record->min)) return TRUE;
3553 return FALSE;
3554 }
3555
3556 /******************************************************************************
3557 * RecordPassesMax.
3558 * It is assumed that overall filtered and filtering for the `Record' item
3559 * are both enabled.
3560 ******************************************************************************/
3561
RecordPassesMax(Item,recN)3562 Logical RecordPassesMax (Item, recN)
3563 struct ItemStruct *Item;
3564 long recN;
3565 {
3566 if (Item->Record->max == NOminMax) return TRUE;
3567 if (BOO(Item->inclusive,
3568 recN <= Item->Record->max,
3569 recN < Item->Record->max)) return TRUE;
3570 return FALSE;
3571 }
3572
3573 /******************************************************************************
3574 * IndicesPassMin.
3575 * It is assumed that overall filtered and filtering for the `Indices' item
3576 * are both enabled.
3577 ******************************************************************************/
3578
IndicesPassMin(Item,indices)3579 Logical IndicesPassMin (Item, indices)
3580 struct ItemStruct *Item;
3581 long indices[];
3582 {
3583 int dimN;
3584 if (Item->Indices->minNumDims == NOminMax) return TRUE;
3585 for (dimN = 0; dimN < Item->Indices->minNumDims; dimN++) {
3586 if (BOO(Item->inclusive,
3587 indices[dimN] < Item->Indices->minIndices[dimN],
3588 indices[dimN] <= Item->Indices->minIndices[dimN])) return FALSE;
3589 }
3590 return TRUE;
3591 }
3592
3593 /******************************************************************************
3594 * IndicesPassMax.
3595 * It is assumed that overall filtered and filtering for the `Indices' item
3596 * are both enabled.
3597 ******************************************************************************/
3598
IndicesPassMax(Item,indices)3599 Logical IndicesPassMax (Item, indices)
3600 struct ItemStruct *Item;
3601 long indices[];
3602 {
3603 int dimN;
3604 if (Item->Indices->maxNumDims == NOminMax) return TRUE;
3605 for (dimN = 0; dimN < Item->Indices->maxNumDims; dimN++) {
3606 if (BOO(Item->inclusive,
3607 indices[dimN] > Item->Indices->maxIndices[dimN],
3608 indices[dimN] >= Item->Indices->maxIndices[dimN])) return FALSE;
3609 }
3610 return TRUE;
3611 }
3612
3613 /******************************************************************************
3614 * VarPassesMin.
3615 * It is assumed that overall filtered and filtering for this variable are
3616 * both enabled.
3617 ******************************************************************************/
3618
VarPassesMin(Item,value)3619 Logical VarPassesMin (Item, value)
3620 struct ItemStruct *Item;
3621 void *value;
3622 {
3623 if (Item->Var->min == NULL) return TRUE;
3624 if (BOO(Item->inclusive,
3625 GEx(value,Item->Var->min,Item->Var->dataType,Item->Var->numElems),
3626 GTx(value,Item->Var->min,Item->Var->dataType,Item->Var->numElems))) {
3627 return TRUE;
3628 }
3629 if (USEFILL(Item->Var,opt)) {
3630 if (EQx(value,Item->Var->fill,Item->Var->dataType,Item->Var->numElems)) {
3631 return TRUE;
3632 }
3633 }
3634 return FALSE;
3635 }
3636
3637 /******************************************************************************
3638 * VarPassesMax.
3639 * It is assumed that overall filtered and filtering for this variable are
3640 * both enabled.
3641 ******************************************************************************/
3642
VarPassesMax(Item,value)3643 Logical VarPassesMax (Item, value)
3644 struct ItemStruct *Item;
3645 void *value;
3646 {
3647 if (Item->Var->max == NULL) return TRUE;
3648 if (BOO(Item->inclusive,
3649 LEx(value,Item->Var->max,Item->Var->dataType,Item->Var->numElems),
3650 LTx(value,Item->Var->max,Item->Var->dataType,Item->Var->numElems))) {
3651 return TRUE;
3652 }
3653 if (USEFILL(Item->Var,opt)) {
3654 if (EQx(value,Item->Var->fill,Item->Var->dataType,Item->Var->numElems)) {
3655 return TRUE;
3656 }
3657 }
3658 return FALSE;
3659 }
3660
3661 /******************************************************************************
3662 * DisplayPctComplete.
3663 * Does nothing if in batch mode.
3664 ******************************************************************************/
3665
DisplayPctComplete(pct,msg)3666 void DisplayPctComplete (pct, msg)
3667 int pct;
3668 char *msg;
3669 {
3670 static int lastPct;
3671 if (BATCH(batchMode)) return;
3672 if (pct == NO_PCT) {
3673 lastPct = NO_PCT;
3674 DisplayMessage (msg, NOWAIT);
3675 return;
3676 }
3677 if (pct > lastPct) {
3678 char text[SCREEN_WIDTH+1], pctText[8+1]; int pad;
3679 strcpyX (text, msg, SCREEN_WIDTH - 2);
3680 sprintf (pctText, "%d%%", pct);
3681 pad = (SCREEN_WIDTH - 2) - strlen(text) - strlen(pctText);
3682 CatNcharacters (text, pad, ' ');
3683 strcatX (text, pctText, SCREEN_WIDTH - 2);
3684 DisplayMessage (text, NOWAIT);
3685 lastPct = pct;
3686 }
3687 return;
3688 }
3689
3690 /******************************************************************************
3691 * UpdateToScreen.
3692 ******************************************************************************/
3693
UpdateToScreen(EWscr,trailerMsg,at,total)3694 void UpdateToScreen (EWscr, trailerMsg, at, total)
3695 struct EditWindowStruct *EWscr;
3696 char *trailerMsg;
3697 long at;
3698 long total;
3699 {
3700 int pad; char pct[8+1];
3701 AOSs1 (trailer, BLANKs78)
3702 strcpyX (trailer[0], trailerMsg, SCREEN_WIDTH - 2);
3703 sprintf (pct, "%ld%%", (100 * at) / total);
3704 pad = (SCREEN_WIDTH - 2) - strlen(trailer[0]) - strlen(pct);
3705 CatNcharacters (trailer[0], pad, ' ');
3706 strcatX (trailer[0], pct, SCREEN_WIDTH - 2);
3707 EWscr->tLines = trailer;
3708 EditWindow (UPDATEew, EWscr, LogicalTRUE);
3709 return;
3710 }
3711
3712 /******************************************************************************
3713 * StandardFormat.
3714 ******************************************************************************/
3715
StandardFormat(dataType)3716 char *StandardFormat (dataType)
3717 long dataType;
3718 {
3719 switch (dataType) {
3720 case CDF_CHAR:
3721 case CDF_UCHAR: return NULL;
3722 case CDF_BYTE:
3723 case CDF_INT1: return "%4d";
3724 case CDF_UINT1: return "%3u";
3725 case CDF_INT2: return "%6d";
3726 case CDF_UINT2: return "%5u";
3727 case CDF_INT4: return Int32FORMATstandard;
3728 case CDF_UINT4: return Int32uFORMATstandard;
3729 case CDF_REAL4:
3730 case CDF_FLOAT: return "%16.9e";
3731 case CDF_REAL8:
3732 case CDF_DOUBLE: return "%25.17e";
3733 case CDF_EPOCH:
3734 switch (opt.epochStyle) {
3735 case EPOCH0_STYLE:
3736 case EPOCH1_STYLE:
3737 case EPOCH2_STYLE:
3738 case EPOCH3_STYLE: return NULL;
3739 case EPOCHf_STYLE: return StandardFormat(CDF_REAL8);
3740 case EPOCHx_STYLE: return EPOCHx_FORMAT_STANDARD;
3741 }
3742 case CDF_EPOCH16: /* Based on EPOCH, it only shows 1 of 2 doubles.*/
3743 switch (opt.epochStyle) {
3744 case EPOCH0_STYLE:
3745 case EPOCH1_STYLE:
3746 case EPOCH2_STYLE:
3747 case EPOCH3_STYLE: return NULL;
3748 case EPOCHf_STYLE: return StandardFormat(CDF_REAL8);
3749 case EPOCHx_STYLE: return EPOCHx_FORMAT_STANDARD;
3750 }
3751 }
3752 return NULL;
3753 }
3754
3755 /******************************************************************************
3756 * StandardWidth.
3757 ******************************************************************************/
3758
StandardWidth(dataType,numElems)3759 int StandardWidth (dataType, numElems)
3760 long dataType;
3761 long numElems;
3762 {
3763 switch (dataType) {
3764 case CDF_CHAR:
3765 case CDF_UCHAR: return (int) (1 + numElems + 1);
3766 case CDF_BYTE:
3767 case CDF_INT1:
3768 case CDF_UINT1:
3769 case CDF_INT2:
3770 case CDF_UINT2:
3771 case CDF_INT4:
3772 case CDF_UINT4:
3773 case CDF_REAL4:
3774 case CDF_FLOAT:
3775 case CDF_REAL8:
3776 case CDF_DOUBLE: return FormatWidth(StandardFormat(dataType));
3777 case CDF_EPOCH:
3778 switch (opt.epochStyle) {
3779 case EPOCH0_STYLE: return EPOCH_STRING_LEN;
3780 case EPOCH1_STYLE: return EPOCH1_STRING_LEN;
3781 case EPOCH2_STYLE: return EPOCH2_STRING_LEN;
3782 case EPOCH3_STYLE: return EPOCH3_STRING_LEN;
3783 case EPOCHf_STYLE: return FormatWidth(StandardFormat(CDF_REAL8));
3784 case EPOCHx_STYLE: return (int) strlen(EPOCHx_FORMAT_STANDARD);
3785 }
3786 case CDF_EPOCH16: /* Based on EPOCH, it only shows 1 of 2 doubles.*/
3787 switch (opt.epochStyle) {
3788 case EPOCH0_STYLE: return EPOCH16_STRING_LEN;
3789 case EPOCH1_STYLE: return EPOCH16_1_STRING_LEN;
3790 case EPOCH2_STYLE: return EPOCH16_2_STRING_LEN;
3791 case EPOCH3_STYLE: return EPOCH16_3_STRING_LEN;
3792 case EPOCHf_STYLE: return FormatWidth(StandardFormat(CDF_REAL8));
3793 case EPOCHx_STYLE: return (int) strlen(EPOCHx_FORMAT_STANDARD);
3794 }
3795 }
3796 return 0;
3797 }
3798